Version 2.8.0-dev.6.0

Merge commit '62291efcfdfbef76be063f1fc1ff65bf13a7f86c' into dev
diff --git a/.gitattributes b/.gitattributes
index dd98789..207c1a2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -30,6 +30,12 @@
 tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text
 tests/lib_2/mirrors/method_mirror_source_other.dart -text
 tests/lib_2/mirrors/method_mirror_source_test.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_lf.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text
+tests/lib/mirrors/method_mirror_source_other.dart -text
+tests/lib/mirrors/method_mirror_source_test.dart -text
 
 # Files to leave alone and not diff.
 *.png binary
diff --git a/.packages b/.packages
index b88c3ba..cdbd2cd 100644
--- a/.packages
+++ b/.packages
@@ -67,6 +67,7 @@
 mockito:third_party/pkg/mockito/lib
 modular_test:pkg/modular_test/lib
 mustache:third_party/pkg/mustache/lib
+native_stack_traces:pkg/native_stack_traces/lib
 nnbd_migration:pkg/nnbd_migration/lib
 oauth2:third_party/pkg/oauth2/lib
 observatory:runtime/observatory/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 50e1b26..b4164fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -127,6 +127,17 @@
 
 [17207]: https://github.com/dart-lang/sdk/issues/17207
 
+## 2.7.1 - 2020-01-23
+
+This is a patch release that improves dart2js compile-time (issue [40217][]).
+
+[40217]: https://github.com/dart-lang/sdk/issues/40217
+
+**Breaking Change**:
+The Dart SDK for macOS is now only available for x64 (issue [39810][]).
+
+[39810]: https://github.com/dart-lang/sdk/issues/39810
+
 ## 2.7.0 - 2019-12-11
 
 **Extension methods** -- which we shipped in preview in 2.6.0 -- are no longer
@@ -171,6 +182,12 @@
 * **Breaking change**: Added `IOOverrides.serverSocketBind` to aid in writing
   tests that wish to mock `ServerSocket.bind`.
 
+#### `dart:typed_data`
+
+* Added new constructors, `.sublistView(TypedData, [start, end])` to all
+  `TypedData` classes. The constructor makes it easier, and less error-prone,
+  to create a view of (a slice of) another `TypedData` object.
+
 ### Dart VM
 
 * New fields added to existing instances by a reload will now be initialized
diff --git a/benchmarks/TypedDataDuplicate/dart/TypedDataDuplicate.dart b/benchmarks/TypedDataDuplicate/dart/TypedDataDuplicate.dart
new file mode 100644
index 0000000..afebf7a
--- /dev/null
+++ b/benchmarks/TypedDataDuplicate/dart/TypedDataDuplicate.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2020, 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.
+
+// Micro-benchmarks for copying typed data lists.
+
+import 'dart:typed_data';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+abstract class Uint8ListCopyBenchmark extends BenchmarkBase {
+  final int size;
+  Uint8List input;
+  Uint8List result;
+
+  Uint8ListCopyBenchmark(String method, this.size)
+      : super('TypedDataDuplicate.Uint8List.$size.$method');
+
+  void setup() {
+    input = Uint8List(size);
+    for (int i = 0; i < size; ++i) {
+      input[i] = (i + 3) & 0xff;
+    }
+  }
+
+  void warmup() {
+    for (int i = 0; i < 100; ++i) {
+      run();
+    }
+  }
+
+  void teardown() {
+    for (int i = 0; i < size; ++i) {
+      if (result[i] != ((i + 3) & 0xff)) {
+        throw 'Unexpected result';
+      }
+    }
+  }
+}
+
+class Uint8ListCopyViaFromListBenchmark extends Uint8ListCopyBenchmark {
+  Uint8ListCopyViaFromListBenchmark(int size) : super('fromList', size);
+
+  void run() {
+    result = Uint8List.fromList(input);
+  }
+}
+
+class Uint8ListCopyViaLoopBenchmark extends Uint8ListCopyBenchmark {
+  Uint8ListCopyViaLoopBenchmark(int size) : super('loop', size);
+
+  void run() {
+    result = Uint8List(input.length);
+    for (var i = 0; i < input.length; i++) {
+      result[i] = input[i];
+    }
+  }
+}
+
+abstract class Float64ListCopyBenchmark extends BenchmarkBase {
+  final int size;
+  Float64List input;
+  Float64List result;
+
+  Float64ListCopyBenchmark(String method, this.size)
+      : super('TypedDataDuplicate.Float64List.$size.$method');
+
+  void setup() {
+    input = Float64List(size);
+    for (int i = 0; i < size; ++i) {
+      input[i] = (i - 7).toDouble();
+    }
+  }
+
+  void teardown() {
+    for (int i = 0; i < size; ++i) {
+      if (result[i] != (i - 7).toDouble()) {
+        throw 'Unexpected result';
+      }
+    }
+  }
+}
+
+class Float64ListCopyViaFromListBenchmark extends Float64ListCopyBenchmark {
+  Float64ListCopyViaFromListBenchmark(int size) : super('fromList', size);
+
+  void run() {
+    result = Float64List.fromList(input);
+  }
+}
+
+class Float64ListCopyViaLoopBenchmark extends Float64ListCopyBenchmark {
+  Float64ListCopyViaLoopBenchmark(int size) : super('loop', size);
+
+  void run() {
+    result = Float64List(input.length);
+    for (var i = 0; i < input.length; i++) {
+      result[i] = input[i];
+    }
+  }
+}
+
+main() {
+  final sizes = [8, 32, 256, 16384];
+  final benchmarks = [
+    for (int size in sizes) ...[
+      Uint8ListCopyViaLoopBenchmark(size),
+      Uint8ListCopyViaFromListBenchmark(size)
+    ],
+    for (int size in sizes) ...[
+      Float64ListCopyViaLoopBenchmark(size),
+      Float64ListCopyViaFromListBenchmark(size)
+    ]
+  ];
+  for (var bench in benchmarks) {
+    bench.report();
+  }
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 1e1ba95..eab740f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -6275,6 +6275,139 @@
         r"""Try moving the '?..' operator to be the first cascade operator in the sequence.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateNullableInterfaceError =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Can't implement '#name' because it's marked with '?'.""",
+        withArguments: _withArgumentsNullableInterfaceError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableInterfaceError =
+    const Code<Message Function(String name)>(
+  "NullableInterfaceError",
+  templateNullableInterfaceError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableInterfaceError(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableInterfaceError,
+      message: """Can't implement '${name}' because it's marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateNullableInterfaceWarning =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Implementing '#name' marked with '?'.""",
+        withArguments: _withArgumentsNullableInterfaceWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableInterfaceWarning =
+    const Code<Message Function(String name)>(
+        "NullableInterfaceWarning", templateNullableInterfaceWarning,
+        severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableInterfaceWarning(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableInterfaceWarning,
+      message: """Implementing '${name}' marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateNullableMixinError =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Can't mix '#name' in because it's marked with '?'.""",
+        withArguments: _withArgumentsNullableMixinError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableMixinError =
+    const Code<Message Function(String name)>(
+  "NullableMixinError",
+  templateNullableMixinError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableMixinError(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableMixinError,
+      message: """Can't mix '${name}' in because it's marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateNullableMixinWarning =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Mixing in '#name' marked with '?'.""",
+        withArguments: _withArgumentsNullableMixinWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableMixinWarning =
+    const Code<Message Function(String name)>(
+        "NullableMixinWarning", templateNullableMixinWarning,
+        severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableMixinWarning(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableMixinWarning,
+      message: """Mixing in '${name}' marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateNullableSuperclassError =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Can't extend '#name' because it's marked with '?'.""",
+        withArguments: _withArgumentsNullableSuperclassError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableSuperclassError =
+    const Code<Message Function(String name)>(
+  "NullableSuperclassError",
+  templateNullableSuperclassError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableSuperclassError(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableSuperclassError,
+      message: """Can't extend '${name}' because it's marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateNullableSuperclassWarning =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Extending '#name' marked with '?'.""",
+        withArguments: _withArgumentsNullableSuperclassWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeNullableSuperclassWarning =
+    const Code<Message Function(String name)>(
+        "NullableSuperclassWarning", templateNullableSuperclassWarning,
+        severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableSuperclassWarning(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeNullableSuperclassWarning,
+      message: """Extending '${name}' marked with '?'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeObjectExtends = messageObjectExtends;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7040,7 +7173,7 @@
     templateRequiredNamedParameterHasDefaultValueError =
     const Template<Message Function(String name)>(
         messageTemplate:
-            r"""Required named parameter '#name' can't have a default value.""",
+            r"""Named parameter '#name' is required and can't have a default value.""",
         withArguments:
             _withArgumentsRequiredNamedParameterHasDefaultValueError);
 
@@ -7058,7 +7191,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeRequiredNamedParameterHasDefaultValueError,
       message:
-          """Required named parameter '${name}' can't have a default value.""",
+          """Named parameter '${name}' is required and can't have a default value.""",
       arguments: {'name': name});
 }
 
@@ -7067,7 +7200,7 @@
     templateRequiredNamedParameterHasDefaultValueWarning =
     const Template<Message Function(String name)>(
         messageTemplate:
-            r"""Required named parameter '#name' has a default value.""",
+            r"""Named parameter '#name' is required and has a default value.""",
         withArguments:
             _withArgumentsRequiredNamedParameterHasDefaultValueWarning);
 
@@ -7085,7 +7218,8 @@
   if (name.isEmpty) throw 'No name provided';
   name = demangleMixinApplicationName(name);
   return new Message(codeRequiredNamedParameterHasDefaultValueWarning,
-      message: """Required named parameter '${name}' has a default value.""",
+      message:
+          """Named parameter '${name}' is required and has a default value.""",
       arguments: {'name': name});
 }
 
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/if.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/if.dart
index 44f2be0..97c1ebb 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/if.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/if.dart
@@ -44,6 +44,22 @@
   }
 }
 
+void if_then_elseNullableTypeVariableWithNonNullableBound<T extends int>(T? x) {
+  if (x == null) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
+void if_then_elseTypeVariableWithNullableBound<T extends int?>(T x) {
+  if (x == null) {
+    x;
+  } else {
+    /*nonNullable*/ x;
+  }
+}
+
 class C {
   void method_if_then_else(int? x) {
     if (x == null) {
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart
index e18296b..51ba181 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/null_check.dart
@@ -6,3 +6,30 @@
   x!;
   /*nonNullable*/ x;
 }
+
+void bang_promotesNullableTypeVariable<E>(E? x) {
+  x!;
+  /*nonNullable*/ x;
+}
+
+void bang_promotesNonNullableTypeVariable<E>(E x) {
+  x!;
+  /*nonNullable*/ x;
+}
+
+void bang_promotesNullableTypeVariableWithNullableBound<E extends int?>(E? x) {
+  x!;
+  /*nonNullable*/ x;
+}
+
+void bang_promotesNonNullableTypeVariableWithNullableBound<E extends int?>(
+    E x) {
+  x!;
+  /*nonNullable*/ x;
+}
+
+void bang_promotesNullableTypeVariableWithNonNullableBound<E extends int>(
+    E? x) {
+  x!;
+  /*nonNullable*/ x;
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/main.dart
new file mode 100644
index 0000000..9f0916a
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/main.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, 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: nnbd=false*/
+
+// @dart=2.5
+
+import 'opt_in.dart';
+
+/*class: MapImpl:Map<K*,V*>,MapImpl<K*,V*>,Object*/
+abstract class MapImpl<K, V> implements Map<K, V> {
+  /*member: MapImpl.map:Map<K2*,V2*>* Function<K2,V2>(MapEntry<K2*,V2*>* Function(K*,V*)*)**/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K key, V value) f);
+}
+
+/*class: FixedMapImpl:FixedMapImpl,Map<int*,String*>,Object*/
+abstract class FixedMapImpl implements Map<int, String> {
+  /*member: FixedMapImpl.map:Map<K2*,V2*>* Function<K2,V2>(MapEntry<K2*,V2*>* Function(int*,String*)*)**/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(int key, String value) f);
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/opt_in.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/opt_in.dart
new file mode 100644
index 0000000..e0f9575
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_in/opt_in.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, 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: nnbd=true*/
+
+/*class: Map:Map<K,V>,Object*/
+abstract class Map<K, V> {
+  /*member: Map.map:Map<K2,V2>! Function<K2,V2>(MapEntry<K2,V2>! Function(K,V)!)!*/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K key, V value) f);
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/main.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/main.dart
new file mode 100644
index 0000000..ebbea2e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/main.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, 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: nnbd=true*/
+
+import 'opt_out.dart';
+
+/*class: MapImpl:Map<K,V>,MapImpl<K,V>,Object*/
+abstract class MapImpl<K, V> implements Map<K, V> {
+  /*member: MapImpl.map:Map<K2,V2>! Function<K2,V2>(MapEntry<K2,V2>! Function(K,V)!)!*/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K key, V value) f);
+}
+
+/*class: FixedMapImpl:FixedMapImpl,Map<int!,String?>,Object*/
+abstract class FixedMapImpl implements Map<int, String?> {
+  /*member: FixedMapImpl.map:Map<K2,V2>! Function<K2,V2>(MapEntry<K2,V2>! Function(int!,String?)!)!*/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(int key, String? value) f);
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/opt_out.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/opt_out.dart
new file mode 100644
index 0000000..7d7688f
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/generic_members_from_opt_out/opt_out.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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: nnbd=false*/
+
+// @dart=2.5
+
+/*class: Map:Map<K*,V*>,Object*/
+abstract class Map<K, V> {
+  /*member: Map.map:Map<K2*,V2*>* Function<K2,V2>(MapEntry<K2*,V2*>* Function(K*,V*)*)**/
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K key, V value) f);
+}
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index e2b398a..44d21e8 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -42,8 +42,8 @@
     - prefer_final_fields
     - prefer_for_elements_to_map_fromIterable
     - prefer_generic_function_type_aliases
-    #- prefer_if_null_operators # 22
+    - prefer_if_null_operators
     - prefer_single_quotes
-    #- prefer_spread_collections # 3
+    - prefer_spread_collections
     - unnecessary_this
     - use_function_type_syntax_for_parameters
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 4292152..6e51b61 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -170,8 +170,6 @@
 const String EDIT_REQUEST_DARTFIX_INCLUDED_FIXES = 'includedFixes';
 const String EDIT_REQUEST_DARTFIX_INCLUDE_PEDANTIC_FIXES =
     'includePedanticFixes';
-const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
-    'includeRequiredFixes';
 const String EDIT_REQUEST_DARTFIX_OUTPUT_DIR = 'outputDir';
 const String EDIT_REQUEST_DARTFIX_PORT = 'port';
 const String EDIT_REQUEST_FORMAT = 'edit.format';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 36ec236..4d8dc58 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -62,7 +62,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['directories'] = directories;
     return result;
   }
@@ -85,7 +85,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, directories.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -174,7 +174,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['labels'] =
         labels.map((ClosingLabel value) => value.toJson()).toList();
@@ -200,7 +200,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, labels.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -276,7 +276,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((SourceChange value) => value.toJson()).toList();
@@ -298,7 +298,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, error.hashCode);
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -374,7 +374,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -400,7 +400,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, errors.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -456,7 +456,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     return result;
   }
@@ -478,7 +478,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -553,7 +553,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -579,7 +579,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -632,7 +632,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -655,7 +655,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -713,7 +713,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
     return result;
@@ -738,7 +738,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, errors.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -809,7 +809,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -833,7 +833,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -900,7 +900,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['hovers'] =
         hovers.map((HoverInformation value) => value.toJson()).toList();
     return result;
@@ -925,7 +925,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, hovers.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1016,7 +1016,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1043,7 +1043,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -1106,7 +1106,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
     return result;
@@ -1131,7 +1131,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1244,7 +1244,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['libraries'] = libraries;
     result['packageMap'] = packageMap;
     return result;
@@ -1278,7 +1278,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraries.hashCode);
     hash = JenkinsSmiHash.combine(hash, packageMap.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1374,7 +1374,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1401,7 +1401,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -1510,7 +1510,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -1541,7 +1541,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
@@ -1596,7 +1596,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -1619,7 +1619,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1688,7 +1688,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['sources'] = sources;
     return result;
   }
@@ -1715,7 +1715,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, sources.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1787,7 +1787,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1811,7 +1811,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1918,7 +1918,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['parameters'] =
         parameters.map((ParameterInfo value) => value.toJson()).toList();
@@ -1949,7 +1949,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameters.hashCode);
     hash = JenkinsSmiHash.combine(hash, dartdoc.hashCode);
@@ -2034,7 +2034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -2060,7 +2060,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2161,7 +2161,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['classes'] =
         classes.map((ImplementedClass value) => value.toJson()).toList();
@@ -2191,7 +2191,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, classes.hashCode);
     hash = JenkinsSmiHash.combine(hash, members.hashCode);
@@ -2306,7 +2306,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2334,7 +2334,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2472,7 +2472,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -2504,7 +2504,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
@@ -2583,7 +2583,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -2609,7 +2609,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2821,7 +2821,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (enableAsync != null) {
       result['enableAsync'] = enableAsync;
     }
@@ -2869,7 +2869,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, enableAsync.hashCode);
     hash = JenkinsSmiHash.combine(hash, enableDeferredLoading.hashCode);
     hash = JenkinsSmiHash.combine(hash, enableEnums.hashCode);
@@ -2994,7 +2994,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     if (libraryName != null) {
@@ -3024,7 +3024,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, libraryName.hashCode);
@@ -3102,7 +3102,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['overrides'] =
         overrides.map((Override value) => value.toJson()).toList();
@@ -3128,7 +3128,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, overrides.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3410,7 +3410,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['included'] = included;
     result['excluded'] = excluded;
     if (packageRoots != null) {
@@ -3441,7 +3441,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
     hash = JenkinsSmiHash.combine(hash, excluded.hashCode);
     hash = JenkinsSmiHash.combine(hash, packageRoots.hashCode);
@@ -3527,7 +3527,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = subscriptions
         .map((GeneralAnalysisService value) => value.toJson())
         .toList();
@@ -3553,7 +3553,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3633,7 +3633,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     return result;
   }
@@ -3656,7 +3656,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3743,7 +3743,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -3771,7 +3771,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3864,7 +3864,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isAnalyzing'] = isAnalyzing;
     if (analysisTarget != null) {
       result['analysisTarget'] = analysisTarget;
@@ -3886,7 +3886,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isAnalyzing.hashCode);
     hash = JenkinsSmiHash.combine(hash, analysisTarget.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3952,7 +3952,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] =
         mapMap(files, valueCallback: (dynamic value) => value.toJson());
     return result;
@@ -3976,7 +3976,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4011,7 +4011,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -4033,7 +4033,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -4086,7 +4086,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['options'] = options.toJson();
     return result;
   }
@@ -4109,7 +4109,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, options.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4187,7 +4187,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['value'] = value;
     return result;
   }
@@ -4210,7 +4210,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4317,7 +4317,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['enabled'] = enabled;
     return result;
   }
@@ -4340,7 +4340,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, enabled.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4392,7 +4392,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['action'] = action;
     return result;
   }
@@ -4415,7 +4415,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, action.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4512,7 +4512,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['event'] = event;
     result['millis'] = millis;
     return result;
@@ -4536,7 +4536,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, event.hashCode);
     hash = JenkinsSmiHash.combine(hash, millis.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4792,7 +4792,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['label'] = label;
     result['declaringLibraryUri'] = declaringLibraryUri;
     result['element'] = element.toJson();
@@ -4842,7 +4842,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
     hash = JenkinsSmiHash.combine(hash, declaringLibraryUri.hashCode);
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
@@ -4937,7 +4937,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['uri'] = uri;
     result['items'] =
@@ -4961,7 +4961,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     hash = JenkinsSmiHash.combine(hash, items.hashCode);
@@ -5050,7 +5050,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['label'] = label;
@@ -5072,7 +5072,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
@@ -5154,7 +5154,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (changedLibraries != null) {
       result['changedLibraries'] = changedLibraries
           .map((AvailableSuggestionSet value) => value.toJson())
@@ -5186,7 +5186,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, changedLibraries.hashCode);
     hash = JenkinsSmiHash.combine(hash, removedLibraries.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5261,7 +5261,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['imports'] = imports.toJson();
     return result;
@@ -5284,7 +5284,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, imports.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5400,7 +5400,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['id'] = id;
     result['label'] = label;
@@ -5429,7 +5429,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
@@ -5510,7 +5510,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['completion'] = completion;
     if (change != null) {
       result['change'] = change.toJson();
@@ -5536,7 +5536,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, completion.hashCode);
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5609,7 +5609,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -5633,7 +5633,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5689,7 +5689,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -5712,7 +5712,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5765,7 +5765,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -5788,7 +5788,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5849,7 +5849,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['tokens'] =
         tokens.map((TokenDetails value) => value.toJson()).toList();
     return result;
@@ -5874,7 +5874,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5937,7 +5937,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['paths'] =
         paths.map((LibraryPathSet value) => value.toJson()).toList();
     return result;
@@ -5962,7 +5962,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, paths.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -6265,7 +6265,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
@@ -6327,7 +6327,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacementOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode);
@@ -6447,7 +6447,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((CompletionService value) => value.toJson()).toList();
     return result;
@@ -6472,7 +6472,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -6629,7 +6629,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['explicitFileCount'] = explicitFileCount;
     result['implicitFileCount'] = implicitFileCount;
@@ -6656,7 +6656,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
     hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
@@ -6747,7 +6747,6 @@
 /// {
 ///   "name": String
 ///   "description": optional String
-///   "isRequired": optional bool
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -6756,8 +6755,6 @@
 
   String _description;
 
-  bool _isRequired;
-
   /// The name of the fix.
   String get name => _name;
 
@@ -6775,18 +6772,9 @@
     _description = value;
   }
 
-  /// `true` if the fix is in the "required" fixes group.
-  bool get isRequired => _isRequired;
-
-  /// `true` if the fix is in the "required" fixes group.
-  set isRequired(bool value) {
-    _isRequired = value;
-  }
-
-  DartFix(String name, {String description, bool isRequired}) {
+  DartFix(String name, {String description}) {
     this.name = name;
     this.description = description;
-    this.isRequired = isRequired;
   }
 
   factory DartFix.fromJson(
@@ -6804,12 +6792,7 @@
         description = jsonDecoder.decodeString(
             jsonPath + '.description', json['description']);
       }
-      bool isRequired;
-      if (json.containsKey('isRequired')) {
-        isRequired = jsonDecoder.decodeBool(
-            jsonPath + '.isRequired', json['isRequired']);
-      }
-      return DartFix(name, description: description, isRequired: isRequired);
+      return DartFix(name, description: description);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'DartFix', json);
     }
@@ -6817,14 +6800,11 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     if (description != null) {
       result['description'] = description;
     }
-    if (isRequired != null) {
-      result['isRequired'] = isRequired;
-    }
     return result;
   }
 
@@ -6834,19 +6814,16 @@
   @override
   bool operator ==(other) {
     if (other is DartFix) {
-      return name == other.name &&
-          description == other.description &&
-          isRequired == other.isRequired;
+      return name == other.name && description == other.description;
     }
     return false;
   }
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, description.hashCode);
-    hash = JenkinsSmiHash.combine(hash, isRequired.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -6910,7 +6887,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['description'] = description;
     if (location != null) {
       result['location'] = location.toJson();
@@ -6931,7 +6908,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, description.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -7017,7 +6994,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['contexts'] =
         contexts.map((ContextData value) => value.toJson()).toList();
     return result;
@@ -7042,7 +7019,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, contexts.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -7123,7 +7100,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['port'] = port;
     return result;
   }
@@ -7146,7 +7123,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, port.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -7158,7 +7135,6 @@
 ///   "included": List<FilePath>
 ///   "includedFixes": optional List<String>
 ///   "includePedanticFixes": optional bool
-///   "includeRequiredFixes": optional bool
 ///   "excludedFixes": optional List<String>
 ///   "port": optional int
 ///   "outputDir": optional FilePath
@@ -7172,8 +7148,6 @@
 
   bool _includePedanticFixes;
 
-  bool _includeRequiredFixes;
-
   List<String> _excludedFixes;
 
   int _port;
@@ -7225,14 +7199,6 @@
     _includePedanticFixes = value;
   }
 
-  /// A flag indicating whether "required" fixes should be applied.
-  bool get includeRequiredFixes => _includeRequiredFixes;
-
-  /// A flag indicating whether "required" fixes should be applied.
-  set includeRequiredFixes(bool value) {
-    _includeRequiredFixes = value;
-  }
-
   /// A list of names indicating which fixes should not be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
@@ -7266,14 +7232,12 @@
   EditDartfixParams(List<String> included,
       {List<String> includedFixes,
       bool includePedanticFixes,
-      bool includeRequiredFixes,
       List<String> excludedFixes,
       int port,
       String outputDir}) {
     this.included = included;
     this.includedFixes = includedFixes;
     this.includePedanticFixes = includePedanticFixes;
-    this.includeRequiredFixes = includeRequiredFixes;
     this.excludedFixes = excludedFixes;
     this.port = port;
     this.outputDir = outputDir;
@@ -7300,11 +7264,6 @@
         includePedanticFixes = jsonDecoder.decodeBool(
             jsonPath + '.includePedanticFixes', json['includePedanticFixes']);
       }
-      bool includeRequiredFixes;
-      if (json.containsKey('includeRequiredFixes')) {
-        includeRequiredFixes = jsonDecoder.decodeBool(
-            jsonPath + '.includeRequiredFixes', json['includeRequiredFixes']);
-      }
       List<String> excludedFixes;
       if (json.containsKey('excludedFixes')) {
         excludedFixes = jsonDecoder.decodeList(jsonPath + '.excludedFixes',
@@ -7322,7 +7281,6 @@
       return EditDartfixParams(included,
           includedFixes: includedFixes,
           includePedanticFixes: includePedanticFixes,
-          includeRequiredFixes: includeRequiredFixes,
           excludedFixes: excludedFixes,
           port: port,
           outputDir: outputDir);
@@ -7338,7 +7296,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['included'] = included;
     if (includedFixes != null) {
       result['includedFixes'] = includedFixes;
@@ -7346,9 +7304,6 @@
     if (includePedanticFixes != null) {
       result['includePedanticFixes'] = includePedanticFixes;
     }
-    if (includeRequiredFixes != null) {
-      result['includeRequiredFixes'] = includeRequiredFixes;
-    }
     if (excludedFixes != null) {
       result['excludedFixes'] = excludedFixes;
     }
@@ -7377,7 +7332,6 @@
           listEqual(includedFixes, other.includedFixes,
               (String a, String b) => a == b) &&
           includePedanticFixes == other.includePedanticFixes &&
-          includeRequiredFixes == other.includeRequiredFixes &&
           listEqual(excludedFixes, other.excludedFixes,
               (String a, String b) => a == b) &&
           port == other.port &&
@@ -7388,11 +7342,10 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
     hash = JenkinsSmiHash.combine(hash, includedFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, includePedanticFixes.hashCode);
-    hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, port.hashCode);
     hash = JenkinsSmiHash.combine(hash, outputDir.hashCode);
@@ -7594,7 +7547,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['suggestions'] =
         suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
     result['otherSuggestions'] = otherSuggestions
@@ -7642,7 +7595,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, otherSuggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, hasErrors.hashCode);
@@ -7759,7 +7712,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -7790,7 +7743,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode);
@@ -7894,7 +7847,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -7922,7 +7875,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode);
@@ -8014,7 +7967,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8041,7 +7994,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -8101,7 +8054,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['assists'] =
         assists.map((SourceChange value) => value.toJson()).toList();
     return result;
@@ -8126,7 +8079,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, assists.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8217,7 +8170,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8244,7 +8197,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -8305,7 +8258,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -8330,7 +8283,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kinds.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8362,7 +8315,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -8384,7 +8337,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -8441,7 +8394,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['fixes'] = fixes.map((DartFix value) => value.toJson()).toList();
     return result;
   }
@@ -8464,7 +8417,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8535,7 +8488,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -8559,7 +8512,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -8618,7 +8571,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -8643,7 +8596,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8736,7 +8689,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -8761,7 +8714,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -8819,7 +8772,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -8842,7 +8795,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -9004,7 +8957,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
@@ -9039,7 +8992,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9243,7 +9196,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -9292,7 +9245,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, initialProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, optionsProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, finalProblems.hashCode);
@@ -9369,7 +9322,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -9393,7 +9346,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -9472,7 +9425,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     result['whitespaceOnly'] = whitespaceOnly;
     return result;
@@ -9496,7 +9449,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     hash = JenkinsSmiHash.combine(hash, whitespaceOnly.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -9595,7 +9548,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
@@ -9626,7 +9579,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9690,7 +9643,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (edit != null) {
       result['edit'] = edit.toJson();
     }
@@ -9715,7 +9668,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -9808,7 +9761,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -9833,7 +9786,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9891,7 +9844,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['value'] = value;
     return result;
   }
@@ -9914,7 +9867,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10002,7 +9955,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['templates'] = templates
         .map((PostfixTemplateDescriptor value) => value.toJson())
         .toList();
@@ -10028,7 +9981,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, templates.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10081,7 +10034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -10104,7 +10057,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10162,7 +10115,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10185,7 +10138,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10237,7 +10190,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -10260,7 +10213,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10317,7 +10270,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10340,7 +10293,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10593,7 +10546,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
@@ -10637,7 +10590,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, fileIndex.hashCode);
@@ -10714,7 +10667,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     return result;
@@ -10733,7 +10686,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -10855,7 +10808,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['contextRoot'] = contextRoot;
     return result;
   }
@@ -10878,7 +10831,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, contextRoot.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10933,7 +10886,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -10956,7 +10909,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -11009,7 +10962,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -11032,7 +10985,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -11245,7 +11198,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['code'] = code;
     result['offset'] = offset;
     result['contextFile'] = contextFile;
@@ -11292,7 +11245,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, contextFile.hashCode);
@@ -11397,7 +11350,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (suggestions != null) {
       result['suggestions'] = suggestions
           .map((CompletionSuggestion value) => value.toJson())
@@ -11435,7 +11388,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -11531,7 +11484,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     if (kind != null) {
       result['kind'] = kind.toJson();
@@ -11562,7 +11515,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, referencedFiles.hashCode);
@@ -11648,7 +11601,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     if (file != null) {
       result['file'] = file;
@@ -11677,7 +11630,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
@@ -11750,7 +11703,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (file != null) {
       result['file'] = file;
     }
@@ -11778,7 +11731,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -11880,7 +11833,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((ExecutionService value) => value.toJson()).toList();
     return result;
@@ -11905,7 +11858,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -12000,7 +11953,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['uri'] = uri;
     result['elements'] = elements;
     return result;
@@ -12020,7 +11973,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12092,7 +12045,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['elements'] = elements.toJson();
     result['imports'] =
         imports.map((ExistingImport value) => value.toJson()).toList();
@@ -12114,7 +12067,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     hash = JenkinsSmiHash.combine(hash, imports.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12259,7 +12212,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
@@ -12291,7 +12244,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, coveringExpressionOffsets.hashCode);
     hash = JenkinsSmiHash.combine(hash, coveringExpressionLengths.hashCode);
     hash = JenkinsSmiHash.combine(hash, names.hashCode);
@@ -12375,7 +12328,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -12394,7 +12347,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, extractAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12608,7 +12561,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -12646,7 +12599,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
@@ -12816,7 +12769,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -12848,7 +12801,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
     hash = JenkinsSmiHash.combine(hash, createGetter.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -12879,7 +12832,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -12896,7 +12849,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -12948,7 +12901,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -12966,7 +12919,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -13087,7 +13040,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -13111,7 +13064,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -13177,7 +13130,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['properties'] = properties
         .map((FlutterWidgetProperty value) => value.toJson())
         .toList();
@@ -13203,7 +13156,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, properties.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -13491,7 +13444,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -13553,7 +13506,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -13741,7 +13694,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['label'] = label;
     if (literalValueBoolean != null) {
@@ -13781,7 +13734,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
     hash = JenkinsSmiHash.combine(hash, literalValueBoolean.hashCode);
@@ -13947,7 +13900,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['outline'] = outline.toJson();
     return result;
@@ -13970,7 +13923,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, outline.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14076,7 +14029,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (FlutterService value) => value.toJson());
     return result;
@@ -14104,7 +14057,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -14225,7 +14178,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     if (value != null) {
       result['value'] = value.toJson();
@@ -14251,7 +14204,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14308,7 +14261,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -14331,7 +14284,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -14566,7 +14519,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (documentation != null) {
       result['documentation'] = documentation;
     }
@@ -14613,7 +14566,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, documentation.hashCode);
     hash = JenkinsSmiHash.combine(hash, expression.hashCode);
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
@@ -14687,7 +14640,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     if (enumItems != null) {
       result['enumItems'] = enumItems
@@ -14716,7 +14669,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, enumItems.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14942,7 +14895,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (boolValue != null) {
       result['boolValue'] = boolValue;
     }
@@ -14982,7 +14935,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, boolValue.hashCode);
     hash = JenkinsSmiHash.combine(hash, doubleValue.hashCode);
     hash = JenkinsSmiHash.combine(hash, intValue.hashCode);
@@ -15105,7 +15058,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['libraryUri'] = libraryUri;
     result['className'] = className;
     result['name'] = name;
@@ -15131,7 +15084,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraryUri.hashCode);
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -15478,7 +15431,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (containingLibraryPath != null) {
@@ -15538,7 +15491,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, containingLibraryPath.hashCode);
@@ -15615,7 +15568,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15634,7 +15587,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -15701,7 +15654,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15720,7 +15673,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -15809,7 +15762,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['strings'] = strings;
     result['uris'] = uris;
     result['names'] = names;
@@ -15832,7 +15785,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, strings.hashCode);
     hash = JenkinsSmiHash.combine(hash, uris.hashCode);
     hash = JenkinsSmiHash.combine(hash, names.hashCode);
@@ -15922,7 +15875,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['path'] = path;
     result['prefix'] = prefix;
     result['elements'] = elements;
@@ -15944,7 +15897,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, path.hashCode);
     hash = JenkinsSmiHash.combine(hash, prefix.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
@@ -16018,7 +15971,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['tag'] = tag;
     result['relevanceBoost'] = relevanceBoost;
     return result;
@@ -16037,7 +15990,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, tag.hashCode);
     hash = JenkinsSmiHash.combine(hash, relevanceBoost.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16138,7 +16091,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['relevance'] = relevance;
     if (displayUri != null) {
@@ -16162,7 +16115,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, relevance.hashCode);
     hash = JenkinsSmiHash.combine(hash, displayUri.hashCode);
@@ -16232,7 +16185,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -16251,7 +16204,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16362,7 +16315,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (className != null) {
       result['className'] = className;
     }
@@ -16386,7 +16339,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     hash = JenkinsSmiHash.combine(hash, methodName.hashCode);
     hash = JenkinsSmiHash.combine(hash, isDeclaration.hashCode);
@@ -16466,7 +16419,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -16485,7 +16438,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, deleteSource.hashCode);
     hash = JenkinsSmiHash.combine(hash, inlineAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16541,7 +16494,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -16564,7 +16517,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -16649,7 +16602,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -16676,7 +16629,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, entries.hashCode);
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16750,7 +16703,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['scope'] = scope;
     result['libraryPaths'] = libraryPaths;
     return result;
@@ -16771,7 +16724,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, scope.hashCode);
     hash = JenkinsSmiHash.combine(hash, libraryPaths.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16844,7 +16797,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -16862,7 +16815,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newFile.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -16930,7 +16883,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['element'] = element.toJson();
     result['className'] = className;
     return result;
@@ -16949,7 +16902,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -17065,7 +17018,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (superclassMember != null) {
@@ -17096,7 +17049,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, superclassMember.hashCode);
@@ -17187,7 +17140,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['key'] = key;
     result['example'] = example;
@@ -17207,7 +17160,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, example.hashCode);
@@ -17259,7 +17212,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isListingPackageDirs'] = isListingPackageDirs;
     return result;
   }
@@ -17277,7 +17230,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isListingPackageDirs.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -17300,7 +17253,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -17317,7 +17270,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -17338,7 +17291,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -17355,7 +17308,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -17465,7 +17418,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -17489,7 +17442,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, elementKindName.hashCode);
@@ -17546,7 +17499,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newName'] = newName;
     return result;
   }
@@ -17564,7 +17517,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newName.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -17651,7 +17604,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['code'] = code.toJson();
     result['message'] = message;
     if (stackTrace != null) {
@@ -17675,7 +17628,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -18104,7 +18057,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (type != null) {
@@ -18128,7 +18081,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
@@ -18318,7 +18271,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (libraryPath != null) {
       result['libraryPath'] = libraryPath;
     }
@@ -18375,7 +18328,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraryPath.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -18511,7 +18464,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['type'] = type.toJson();
     return result;
@@ -18530,7 +18483,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -18628,7 +18581,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['includePotential'] = includePotential;
@@ -18655,7 +18608,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, includePotential.hashCode);
@@ -18738,7 +18691,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (id != null) {
       result['id'] = id;
     }
@@ -18766,7 +18719,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -18820,7 +18773,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -18843,7 +18796,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -18898,7 +18851,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -18921,7 +18874,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -18974,7 +18927,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -18997,7 +18950,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19052,7 +19005,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -19075,7 +19028,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19131,7 +19084,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['pattern'] = pattern;
     return result;
   }
@@ -19154,7 +19107,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19209,7 +19162,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -19232,7 +19185,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19324,7 +19277,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (file != null) {
       result['file'] = file;
     }
@@ -19357,7 +19310,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
     hash = JenkinsSmiHash.combine(hash, maxResults.hashCode);
@@ -19439,7 +19392,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['declarations'] =
         declarations.map((ElementDeclaration value) => value.toJson()).toList();
     result['files'] = files;
@@ -19466,7 +19419,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, declarations.hashCode);
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -19560,7 +19513,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     if (superOnly != null) {
@@ -19589,7 +19542,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, superOnly.hashCode);
@@ -19663,7 +19616,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (hierarchyItems != null) {
       result['hierarchyItems'] = hierarchyItems
           .map((TypeHierarchyItem value) => value.toJson())
@@ -19691,7 +19644,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, hierarchyItems.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19813,7 +19766,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['location'] = location.toJson();
     result['kind'] = kind.toJson();
     result['isPotential'] = isPotential;
@@ -19837,7 +19790,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, isPotential.hashCode);
@@ -20026,7 +19979,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['results'] =
         results.map((SearchResult value) => value.toJson()).toList();
@@ -20054,7 +20007,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, results.hashCode);
     hash = JenkinsSmiHash.combine(hash, isLast.hashCode);
@@ -20128,7 +20081,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['version'] = version;
     result['pid'] = pid;
     return result;
@@ -20151,7 +20104,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
     hash = JenkinsSmiHash.combine(hash, pid.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -20249,7 +20202,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -20275,7 +20228,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isFatal.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -20358,7 +20311,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['version'] = version;
     return result;
   }
@@ -20381,7 +20334,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20473,7 +20426,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['time'] = time;
     result['kind'] = kind.toJson();
     result['data'] = data;
@@ -20493,7 +20446,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, time.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, data.hashCode);
@@ -20633,7 +20586,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['entry'] = entry.toJson();
     return result;
   }
@@ -20655,7 +20608,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, entry.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20761,7 +20714,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((ServerService value) => value.toJson()).toList();
     return result;
@@ -20786,7 +20739,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20940,7 +20893,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (analysis != null) {
       result['analysis'] = analysis.toJson();
     }
@@ -20967,7 +20920,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, analysis.hashCode);
     hash = JenkinsSmiHash.combine(hash, pub.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -21081,7 +21034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['lexeme'] = lexeme;
     if (type != null) {
       result['type'] = type;
@@ -21110,7 +21063,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
@@ -21320,7 +21273,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['classElement'] = classElement.toJson();
     if (displayName != null) {
       result['displayName'] = displayName;
@@ -21356,7 +21309,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, classElement.hashCode);
     hash = JenkinsSmiHash.combine(hash, displayName.hashCode);
     hash = JenkinsSmiHash.combine(hash, memberElement.hashCode);
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index b955006..a5efa8a 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -166,9 +166,10 @@
     }
     // Look for documentation comments of overridden members.
     OverriddenElements overridden = findOverriddenElements(element);
-    for (Element superElement in []
-      ..addAll(overridden.superElements)
-      ..addAll(overridden.interfaceElements)) {
+    for (Element superElement in [
+      ...overridden.superElements,
+      ...overridden.interfaceElements
+    ]) {
       String rawDoc = superElement.documentationComment;
       if (rawDoc != null) {
         Element interfaceClass = superElement.enclosingElement;
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart
index 70138cd..704852e 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart
@@ -28,6 +28,6 @@
   }
 
   static List<int> _merge(List<int> a, List<int> b) {
-    return <int>[]..addAll(a)..addAll(b);
+    return <int>[...a, ...b];
   }
 }
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index 8f7faee..168a7a4 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -37,9 +37,6 @@
 
     // Determine the fixes to be applied
     final fixInfo = <DartFixInfo>[];
-    if (params.includeRequiredFixes == true) {
-      fixInfo.addAll(allFixes.where((i) => i.isRequired));
-    }
     if (params.includePedanticFixes == true) {
       for (var fix in allFixes) {
         if (fix.isPedantic && !fixInfo.contains(fix)) {
@@ -58,9 +55,6 @@
         }
       }
     }
-    if (fixInfo.isEmpty) {
-      fixInfo.addAll(allFixes.where((i) => i.isDefault));
-    }
     if (params.excludedFixes != null) {
       for (String key in params.excludedFixes) {
         var info = allFixes.firstWhere((i) => i.key == key, orElse: () => null);
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 60364ac..09eba2d 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -37,6 +37,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 // ignore: deprecated_member_use
 import 'package:analyzer/source/analysis_options_provider.dart';
@@ -109,10 +110,15 @@
     //
     // Compute fixes
     //
-    var dartFix = EditDartFix(server, request);
-    Response response = await dartFix.compute();
+    try {
+      var dartFix = EditDartFix(server, request);
+      Response response = await dartFix.compute();
 
-    server.sendResponse(response);
+      server.sendResponse(response);
+    } catch (exception, stackTrace) {
+      server.sendServerErrorNotification('Exception while running dartfix',
+          CaughtException(exception, stackTrace), stackTrace);
+    }
   }
 
   Response format(Request request) {
diff --git a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart b/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart
deleted file mode 100644
index 8a4beea..0000000
--- a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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/plugin/edit/assist/assist_core.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-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_lint_task.dart';
-import 'package:analysis_server/src/services/correction/assist.dart';
-import 'package:analysis_server/src/services/correction/assist_internal.dart';
-import 'package:analysis_server/src/services/correction/change_workspace.dart';
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer_plugin/utilities/assist/assist.dart';
-
-class BasicFixLintAssistTask extends FixLintTask {
-  final AssistKind assistKind;
-
-  BasicFixLintAssistTask(this.assistKind, DartFixListener listener)
-      : super(listener);
-
-  @override
-  Future<void> fixError(ResolvedUnitResult result, AnalysisError error) async {
-    var node = NodeLocator(error.offset).searchWithin(result.unit);
-    AssistProcessor processor = AssistProcessor(
-      DartAssistContextImpl(
-        DartChangeWorkspace(listener.server.currentSessions),
-        result,
-        node.offset,
-        node.length,
-      ),
-    );
-    List<Assist> assists = await processor.computeAssist(assistKind);
-
-    final location = listener.locationFor(result, node.offset, node.length);
-    if (assists.isNotEmpty) {
-      for (Assist assist in assists) {
-        listener.addSourceChange(assist.kind.message, location, assist.change);
-      }
-    } else {
-      // TODO(danrubel): If assists is empty, then determine why
-      // assist could not be performed and report that in the description.
-      listener.addRecommendation(
-          'Fix not found: ${assistKind.message}', location);
-    }
-  }
-
-  static void preferForElementsToMapFromIterable(DartFixRegistrar registrar,
-      DartFixListener listener, EditDartfixParams params) {
-    registrar.registerLintTask(
-      Registry.ruleRegistry['prefer_for_elements_to_map_fromIterable'],
-      BasicFixLintAssistTask(DartAssistKind.CONVERT_TO_FOR_ELEMENT, listener),
-    );
-  }
-
-  static void preferIfElementsToConditionalExpressions(
-      DartFixRegistrar registrar,
-      DartFixListener listener,
-      EditDartfixParams params) {
-    registrar.registerLintTask(
-      Registry.ruleRegistry['prefer_if_elements_to_conditional_expressions'],
-      BasicFixLintAssistTask(DartAssistKind.CONVERT_TO_IF_ELEMENT, listener),
-    );
-  }
-
-  static void preferIntLiterals(DartFixRegistrar registrar,
-      DartFixListener listener, EditDartfixParams params) {
-    registrar.registerLintTask(
-      Registry.ruleRegistry['prefer_int_literals'],
-      BasicFixLintAssistTask(DartAssistKind.CONVERT_TO_INT_LITERAL, listener),
-    );
-  }
-
-  static void preferSpreadCollections(DartFixRegistrar registrar,
-      DartFixListener listener, EditDartfixParams params) {
-    registrar.registerLintTask(
-      Registry.ruleRegistry['prefer_spread_collections'],
-      BasicFixLintAssistTask(DartAssistKind.CONVERT_TO_SPREAD, listener),
-    );
-  }
-}
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
index 58a111c..b04d632 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -5,7 +5,6 @@
 import 'package:analysis_server/protocol/protocol_generated.dart'
     show DartFix, EditDartfixParams;
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
-import 'package:analysis_server/src/edit/fix/basic_fix_lint_assist_task.dart';
 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_error_task.dart';
@@ -18,22 +17,23 @@
 
 final allFixes = <DartFixInfo>[
   //
-  // Required fixes due to errors or upcoming language changes
+  // Error and warning fixes.
   //
   DartFixInfo(
-    'fix-named-constructor-type-arguments',
+    'wrong_number_of_type_arguments_constructor',
     'Move named constructor type arguments from the name to the type.',
     FixErrorTask.fixNamedConstructorTypeArgs,
-    isRequired: true,
-  ),
-  DartFixInfo(
-    'use-mixin',
-    'Convert classes used as a mixin to the new mixin syntax.',
-    PreferMixinFix.task,
-    isRequired: true,
   ),
   //
-  // Pedantic lint fixes.
+  // Assist fixes.
+  //
+  DartFixInfo(
+    'convert_class_to_mixin',
+    'Convert classes used as a mixin to the new mixin syntax.',
+    PreferMixinFix.task,
+  ),
+  //
+  // Lint fixes.
   //
   // TODO(brianwilkerson) The commented out fixes below involve potentially
   //  non-local changes, so they can't currently be applied together. I have an
@@ -68,6 +68,7 @@
   LintFixInfo.preferFinalLocals,
   LintFixInfo.preferForElementsToMapFromIterable,
   LintFixInfo.preferGenericFunctionTypeAliases,
+  LintFixInfo.preferIfElementsToConditionalExpressions,
   LintFixInfo.preferIfNullOperators,
   LintFixInfo.preferInlinedAdds,
   LintFixInfo.preferIntLiterals,
@@ -92,35 +93,6 @@
   LintFixInfo.useFunctionTypeSyntaxForParameters,
   LintFixInfo.useRethrowWhenPossible,
   //
-  // Other fixes
-  //
-  DartFixInfo(
-    // TODO(brianwilkerson) This duplicates `LintFixInfo.preferIntLiterals` and
-    //  should be removed.
-    'double-to-int',
-    'Find double literals ending in .0 and remove the .0 wherever double context can be inferred.',
-    BasicFixLintAssistTask.preferIntLiterals,
-    isDefault: false,
-  ),
-  DartFixInfo(
-    'use-spread-collections',
-    'Convert to using collection spread operators.',
-    BasicFixLintAssistTask.preferSpreadCollections,
-    isDefault: false,
-  ),
-  DartFixInfo(
-    'collection-if-elements',
-    'Convert to using if elements when building collections.',
-    BasicFixLintAssistTask.preferIfElementsToConditionalExpressions,
-    isDefault: false,
-  ),
-  DartFixInfo(
-    'map-for-elements',
-    'Convert to for elements when building maps from iterables.',
-    BasicFixLintAssistTask.preferForElementsToMapFromIterable,
-    isDefault: false,
-  ),
-  //
   // Experimental fixes
   //
   DartFixInfo(
@@ -130,7 +102,6 @@
 This requires the experimental non-nullable flag to be enabled
 when running the updated application.''',
     NonNullableFix.task,
-    isDefault: false,
   ),
 ];
 
@@ -143,16 +114,10 @@
   /// A description of the fix, printed by the `--help` option.
   final String description;
 
-  /// A flag indicating whether this fix is in the default set of fixes.
-  final bool isDefault;
-
   /// A flag indicating whether this fix is related to the lints in the pedantic
   /// lint set.
   final bool isPedantic;
 
-  /// A flag indicating whether this fix is in the set of required fixes.
-  final bool isRequired;
-
   final void Function(DartFixRegistrar registrar, DartFixListener listener,
       EditDartfixParams params) _setup;
 
@@ -160,14 +125,11 @@
     this.key,
     this.description,
     this._setup, {
-    this.isDefault = true,
-    this.isRequired = false,
     this.isPedantic = false,
   });
 
   /// Return a newly created fix generated from this fix info.
-  DartFix asDartFix() =>
-      DartFix(key, description: description, isRequired: isRequired);
+  DartFix asDartFix() => DartFix(key, description: description);
 
   /// Register this fix with the [registrar] and report progress to the
   /// [listener].
@@ -195,7 +157,6 @@
     'always_declare_return_types',
     DartFixKind.ADD_RETURN_TYPE,
     'Add a return type where possible.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -203,7 +164,6 @@
     'always_require_non_null_named_parameters',
     DartFixKind.ADD_REQUIRED,
     'Add an @required annotation.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -211,14 +171,12 @@
     'always_specify_types',
     DartFixKind.ADD_TYPE_ANNOTATION,
     'Add a type annotation.',
-    isDefault: false,
   );
 
   static final annotateOverrides = LintFixInfo(
     'annotate_overrides',
     DartFixKind.ADD_OVERRIDE,
     'Add an @override annotation.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -226,14 +184,12 @@
     'avoid_annotating_with_dynamic',
     DartFixKind.REMOVE_TYPE_ANNOTATION,
     'Remove the type annotation.',
-    isDefault: false,
   );
 
   static final avoidEmptyElse = LintFixInfo(
     'avoid_empty_else',
     DartFixKind.REMOVE_EMPTY_ELSE,
     'Remove the empty else.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -241,7 +197,6 @@
     'avoid_init_to_null',
     DartFixKind.REMOVE_INITIALIZER,
     'Remove the initializer.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -249,14 +204,12 @@
     'avoid_redundant_argument_values',
     DartFixKind.REMOVE_ARGUMENT,
     'Remove the redundant argument.',
-    isDefault: false,
   );
 
   static final avoidRelativeLibImports = LintFixInfo(
     'avoid_relative_lib_imports',
     DartFixKind.CONVERT_TO_PACKAGE_IMPORT,
     'Convert the import to a package: import.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -264,7 +217,6 @@
     'avoid_return_types_on_setters',
     DartFixKind.REMOVE_TYPE_ANNOTATION,
     'Remove the return type.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -273,21 +225,18 @@
     // Also sometimes fixed by DartFixKind.REPLACE_WITH_IDENTIFIER
     DartFixKind.REMOVE_TYPE_ANNOTATION,
     'Remove the type annotation.',
-    isDefault: false,
   );
 
   static final awaitOnlyFutures = LintFixInfo(
     'await_only_futures',
     DartFixKind.REMOVE_AWAIT,
     "Remove the 'await'.",
-    isDefault: false,
   );
 
   static final curlyBracesInFlowControlStructures = LintFixInfo(
     'curly_braces_in_flow_control_structures',
     DartFixKind.ADD_CURLY_BRACES,
     'Add curly braces.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -295,14 +244,12 @@
     'diagnostic_describe_all_properties',
     DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE,
     'Add a debug reference to this property.',
-    isDefault: false,
   );
 
   static final emptyCatches = LintFixInfo(
     'empty_catches',
     DartFixKind.REMOVE_EMPTY_CATCH,
     'Remove the empty catch clause.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -310,7 +257,6 @@
     'empty_constructor_bodies',
     DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY,
     'Remove the empoty catch clause.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -319,21 +265,18 @@
     // Also sometimes fixed by DartFixKind.REPLACE_WITH_BRACKETS
     DartFixKind.REMOVE_EMPTY_STATEMENT,
     'Remove the empty statement.',
-    isDefault: false,
   );
 
   static final hashAndEquals = LintFixInfo(
     'hash_and_equals',
     DartFixKind.CREATE_METHOD,
     'Create the missing method.',
-    isDefault: false,
   );
 
   static final noDuplicateCaseValues = LintFixInfo(
     'no_duplicate_case_values',
     DartFixKind.REMOVE_DUPLICATE_CASE,
     'Remove the duplicate case clause.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -341,7 +284,6 @@
     'non_constant_identifier_names',
     DartFixKind.RENAME_TO_CAMEL_CASE,
     'Change the name to be camelCase.',
-    isDefault: false,
   );
 
   static final nullClosures = LintFixInfo(
@@ -355,7 +297,6 @@
     'omit_local_variable_types',
     DartFixKind.REPLACE_WITH_VAR,
     "Replace the type annotation with 'var'",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -363,7 +304,6 @@
     'prefer_adjacent_string_concatenation',
     DartFixKind.REMOVE_OPERATOR,
     "Remove the '+' operator.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -371,7 +311,6 @@
     'prefer_collection_literals',
     DartFixKind.CONVERT_TO_LIST_LITERAL,
     'Replace with a collection literal.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -379,7 +318,6 @@
     'prefer_conditional_assignment',
     DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT,
     'Replace with a conditional assignment.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -394,7 +332,6 @@
     'prefer_final_fields',
     DartFixKind.MAKE_FINAL,
     'Make the field final.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -402,14 +339,12 @@
     'prefer_final_locals',
     DartFixKind.MAKE_FINAL,
     "Make the variable 'final'.",
-    isDefault: false,
   );
 
   static final preferForElementsToMapFromIterable = LintFixInfo(
     'prefer_for_elements_to_map_fromIterable',
     DartFixKind.CONVERT_TO_FOR_ELEMENT,
     'Convert to a for element.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -417,15 +352,18 @@
     'prefer_generic_function_type_aliases',
     DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX,
     "Convert into 'Function' syntax",
-    isDefault: false,
     isPedantic: true,
   );
 
+  static final preferIfElementsToConditionalExpressions = LintFixInfo(
+      'prefer_if_elements_to_conditional_expressions',
+      DartFixKind.CONVERT_TO_IF_ELEMENT,
+      "Convert to an 'if' element.");
+
   static final preferIfNullOperators = LintFixInfo(
     'prefer_if_null_operators',
     DartFixKind.CONVERT_TO_IF_NULL,
     "Convert to use '??'.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -433,21 +371,18 @@
     'prefer_inlined_adds',
     DartFixKind.INLINE_INVOCATION,
     'Inline the invocation.',
-    isDefault: false,
   );
 
   static final preferIntLiterals = LintFixInfo(
     'prefer_int_literals',
     DartFixKind.CONVERT_TO_INT_LITERAL,
     'Convert to an int literal',
-    isDefault: false,
   );
 
   static final preferIsEmpty = LintFixInfo(
     'prefer_is_empty',
     DartFixKind.REPLACE_WITH_IS_EMPTY,
     "Convert to using 'isEmpty' when checking if a collection or iterable is empty.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -455,7 +390,6 @@
     'prefer_is_not_empty',
     DartFixKind.REPLACE_WITH_IS_NOT_EMPTY,
     "Convert to using 'isNotEmpty' when checking if a collection or iterable is not empty.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -463,7 +397,6 @@
     'prefer_iterable_whereType',
     DartFixKind.CONVERT_TO_WHERE_TYPE,
     'Add a return type where possible.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -471,21 +404,18 @@
     'prefer_null_aware_operators',
     DartFixKind.CONVERT_TO_NULL_AWARE,
     "Convert to use '?.'.",
-    isDefault: false,
   );
 
   static final preferRelativeImports = LintFixInfo(
     'prefer_relative_imports',
     DartFixKind.CONVERT_TO_RELATIVE_IMPORT,
     'Convert to a relative import.',
-    isDefault: false,
   );
 
   static final preferSingleQuotes = LintFixInfo(
     'prefer_single_quotes',
     DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING,
     'Convert strings using a dobule quote to use a single quote.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -495,7 +425,7 @@
     //  user control.
     DartFixKind.CONVERT_TO_SPREAD,
     'Convert to a spread operator.',
-    isDefault: false,
+
     isPedantic: true,
   );
 
@@ -503,7 +433,6 @@
     'slash_for_doc_comments',
     DartFixKind.CONVERT_TO_LINE_COMMENT,
     'Convert to a line comment.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -511,21 +440,18 @@
     'sort_child_properties_last',
     DartFixKind.SORT_CHILD_PROPERTY_LAST,
     "Move the 'child' argument to the end of the argument list.",
-    isDefault: false,
   );
 
   static final typeAnnotatePublicApis = LintFixInfo(
     'type_annotate_public_apis',
     DartFixKind.ADD_TYPE_ANNOTATION,
     'Add a type annotation.',
-    isDefault: false,
   );
 
   static final typeInitFormals = LintFixInfo(
     'type_init_formals',
     DartFixKind.REMOVE_TYPE_ANNOTATION,
     'Remove the type annotation.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -533,7 +459,6 @@
     'unawaited_futures',
     DartFixKind.ADD_AWAIT,
     'Add await.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -541,14 +466,12 @@
     'unnecessary_brace_in_string_interps',
     DartFixKind.REMOVE_INTERPOLATION_BRACES,
     'Remove the unnecessary interpolation braces.',
-    isDefault: false,
   );
 
   static final unnecessaryConst = LintFixInfo(
     'unnecessary_const',
     DartFixKind.REMOVE_UNNECESSARY_CONST,
     "Remove unnecessary 'const'' keywords.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -556,14 +479,12 @@
     'unnecessary_lambdas',
     DartFixKind.REPLACE_WITH_TEAR_OFF,
     'Replace the function literal with a tear-off.',
-    isDefault: false,
   );
 
   static final unnecessaryNew = LintFixInfo(
     'unnecessary_new',
     DartFixKind.REMOVE_UNNECESSARY_NEW,
     "Remove unnecessary 'new' keywords.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -571,7 +492,6 @@
     'unnecessary_null_in_if_null_operators',
     DartFixKind.REMOVE_IF_NULL_OPERATOR,
     "Remove the '??' operator.",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -579,14 +499,12 @@
     'unnecessary_overrides',
     DartFixKind.REMOVE_METHOD_DECLARATION,
     'Remove the unnecessary override.',
-    isDefault: false,
   );
 
   static final unnecessaryThis = LintFixInfo(
     'unnecessary_this',
     DartFixKind.REMOVE_THIS_EXPRESSION,
     'Remove this.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -594,7 +512,6 @@
     'use_function_type_syntax_for_parameters',
     DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX,
     "Convert into 'Function' syntax",
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -602,7 +519,6 @@
     'use_rethrow_when_possible',
     DartFixKind.USE_RETHROW,
     'Replace with rethrow.',
-    isDefault: false,
     isPedantic: true,
   );
 
@@ -617,13 +533,8 @@
     this.lintName,
     this.fixKind,
     String description, {
-    bool isDefault = true,
-    bool isRequired = false,
     bool isPedantic = false,
-  }) : super(lintName.replaceAll('_', '-'), description, null,
-            isDefault: isDefault,
-            isRequired: isRequired,
-            isPedantic: isPedantic);
+  }) : super(lintName, description, null, isPedantic: isPedantic);
 
   @override
   void setup(DartFixRegistrar registrar, DartFixListener listener,
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 920879f..55bd4d3 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,10 +6,8 @@
 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/info_builder.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.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:analysis_server/src/edit/nnbd_migration/migration_state.dart';
 import 'package:analysis_server/src/edit/preview/http_preview_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -79,16 +77,11 @@
   Future<void> finish() async {
     migration.finish();
 
-    OverlayResourceProvider provider = listener.server.resourceProvider;
-    InfoBuilder infoBuilder = InfoBuilder(
-        provider, includedRoot, instrumentationListener.data, listener);
-    Set<UnitInfo> unitInfos = await infoBuilder.explainMigration();
-    var pathContext = provider.pathContext;
-    MigrationInfo migrationInfo = MigrationInfo(
-        unitInfos, infoBuilder.unitMap, pathContext, includedRoot);
-    PathMapper pathMapper = PathMapper(provider);
+    var state = MigrationState(
+        migration, includedRoot, listener, instrumentationListener);
+    await state.refresh();
 
-    server = HttpPreviewServer(migrationInfo, pathMapper);
+    server = HttpPreviewServer(state);
     server.serveHttp();
     port = await server.boundPort;
   }
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_script.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_script.dart
index 09f3724..f123079 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_script.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_script.dart
@@ -50,8 +50,10 @@
 function writeCodeAndRegions(data) {
   const regions = document.querySelector(".regions");
   const code = document.querySelector(".code");
+  const editList = document.querySelector(".edit-list .panel-content");
   regions.innerHTML = data["regions"];
   code.innerHTML = data["navContent"];
+  editList.innerHTML = data["editList"];
   highlightAllCode();
   addClickHandlers(".code");
   addClickHandlers(".regions");
@@ -185,33 +187,115 @@
     };
   });
   const regions = parentElement.querySelectorAll(".region");
-  const infoPanel = document.querySelector(".info-panel-inner");
   regions.forEach((region) => {
-    const tooltip = region.querySelector(".tooltip");
     region.onclick = (event) => {
       loadRegionExplanation(region);
     };
   });
+  const navArrows = parentElement.querySelectorAll(".arrow");
+  navArrows.forEach((arrow) => {
+    const childList = arrow.parentNode.querySelector(":scope > ul");
+    // Animating height from "auto" to "0" is not supported by CSS [1], so all
+    // we have are hacks. The `* 2` allows for events in which the list grows in
+    // height when resized, with additional text wrapping.
+    // [1] https://css-tricks.com/using-css-transitions-auto-dimensions/
+    childList.style.maxHeight = childList.offsetHeight * 2 + "px";
+    arrow.onclick = (event) => {
+      if (!childList.classList.contains("collapsed")) {
+        childList.classList.add("collapsed");
+        arrow.classList.add("collapsed");
+      } else {
+        childList.classList.remove("collapsed");
+        arrow.classList.remove("collapsed");
+      }
+    };
+  });
+  const postLinks = parentElement.querySelectorAll(".post-link");
+  postLinks.forEach((link) => {
+    link.onclick = (event) => {
+      // Directing the server to produce an edit; request it, then do work with
+      // the response.
+      const path = absolutePath(event.currentTarget.getAttribute("href"));
+      const xhr = new XMLHttpRequest();
+      xhr.open("POST", path);
+      xhr.setRequestHeader("Content-Type", "application/json");
+      xhr.onload = function() {
+        if (xhr.status === 200) {
+          // Likely request new navigation and file content.
+        } else {
+          alert("Request failed; status of " + xhr.status);
+        }
+      };
+      xhr.onerror = function(e) {
+        alert(`Could not load ${path}; preview server might be disconnected.`);
+      };
+      xhr.send();
+    };
+  });
 }
 
-// Load the explanation for [region], into the ".info" div.
+function writeRegionExplanation(response) {
+  const editPanel = document.querySelector(".edit-panel .panel-content");
+  editPanel.innerHTML = "";
+  const regionLocation = document.createElement("p");
+  regionLocation.classList.add("region-location");
+  // Insert a zero-width space after each "/", to allow lines to wrap after each
+  // directory name.
+  const path = response["path"].replace(/\//g, "/\u200B");
+  regionLocation.appendChild(document.createTextNode(`${path} `));
+  const regionLine = regionLocation.appendChild(document.createElement("span"));
+  regionLine.appendChild(document.createTextNode(`line ${response["line"]}`));
+  regionLine.classList.add("nowrap");
+  editPanel.appendChild(regionLocation);
+  const explanation = editPanel.appendChild(document.createElement("p"));
+  explanation.appendChild(document.createTextNode(response["explanation"]));
+  const detailCount = response["details"].length;
+  if (detailCount == 0) {
+    // Having 0 details is not necessarily an expected possibility, but handling
+    // the possibility prevents awkward text, "for 0 reasons:".
+    explanation.appendChild(document.createTextNode("."));
+  } else {
+    explanation.appendChild(document.createTextNode(
+        detailCount == 1
+            ? ` for ${detailCount} reason:` : ` for ${detailCount} reasons:`));
+    const detailList = editPanel.appendChild(document.createElement("ol"));
+    for (const detail of response["details"]) {
+      const detailItem = detailList.appendChild(document.createElement("li"));
+      detailItem.appendChild(document.createTextNode(detail["description"]));
+      if (detail["link"] !== undefined) {
+        detailItem.appendChild(document.createTextNode(" ("));
+        const a = detailItem.appendChild(document.createElement("a"));
+        a.appendChild(document.createTextNode(detail["link"]["text"]));
+        a.setAttribute("href", detail["link"]["href"]);
+        a.classList.add("post-link");
+        detailItem.appendChild(document.createTextNode(")"));
+      }
+    }
+  }
+  if (response["edits"] !== undefined) {
+    for (const edit of response["edits"]) {
+      const editParagraph = editPanel.appendChild(document.createElement("p"));
+      const a = editParagraph.appendChild(document.createElement("a"));
+      a.appendChild(document.createTextNode(edit["text"]));
+      a.setAttribute("href", edit["href"]);
+      a.classList.add("post-link");
+    }
+  }
+}
+
+// Load the explanation for [region], into the ".panel-content" div.
 function loadRegionExplanation(region) {
   // Request the region, then do work with the response.
   const xhr = new XMLHttpRequest();
   const path = window.location.pathname;
   const offset = region.dataset.offset;
   xhr.open("GET", path + `?region=region&offset=${offset}`);
-  xhr.setRequestHeader("Content-Type", "text/html");
+  xhr.setRequestHeader("Content-Type", "application/json");
   xhr.onload = function() {
     if (xhr.status === 200) {
-      const response = xhr.responseText;
-      const info = document.querySelector(".info-panel-inner .info");
-      info.innerHTML = response;
-      const line = region.dataset.line;
-      const regionLocation = info.querySelector(".region-location");
-      regionLocation.textContent =
-          regionLocation.textContent + ` line ${line}:`;
-      addClickHandlers(".info-panel .info");
+      const response = JSON.parse(xhr.responseText);
+      writeRegionExplanation(response);
+      addClickHandlers(".edit-panel .panel-content");
     } else {
       alert(`Request failed; status of ${xhr.status}`);
     }
@@ -238,13 +322,16 @@
 // Resize the fixed-size and fixed-position navigation and information panels.
 function resizePanels() {
   const navInner = document.querySelector(".nav-inner");
-  // TODO(srawlins): I'm honestly not sure where 8 comes from; but without
-  // `- 8`, the navigation is too tall and the bottom cannot be seen.
-  const height = window.innerHeight - 8;
+  const height = window.innerHeight;
   navInner.style.height = height + "px";
 
-  const infoInner = document.querySelector(".info-panel-inner");
-  infoInner.style.height = height + "px";
+  const infoPanelHeight = height / 2 - 6;
+  const editPanel = document.querySelector(".edit-panel");
+  editPanel.style.height = infoPanelHeight + "px";
+
+  const editListHeight = height / 2 - 6;
+  const editList = document.querySelector(".edit-list");
+  editList.style.height = editListHeight + "px";
 }
 
 document.addEventListener("DOMContentLoaded", (event) => {
@@ -284,20 +371,21 @@
   const navPanel = document.querySelector(".nav-panel");
   const navInner = navPanel.querySelector(".nav-inner");
   const infoPanel = document.querySelector(".info-panel");
-  const infoInner = infoPanel.querySelector(".info-panel-inner");
+  const panelContainer = document.querySelector(".panel-container");
   const innerTopOffset = navPanel.offsetTop;
   if (window.pageYOffset > innerTopOffset) {
     if (!navInner.classList.contains("fixed")) {
-      navPanel.style.width = navPanel.offsetWidth + "px";
-      // Subtract 6px for nav-inner's padding.
-      navInner.style.width = (navInner.offsetWidth - 6) + "px";
+      const navPanelWidth = navPanel.offsetWidth - 14;
+      navPanel.style.width = navPanelWidth + "px";
+      // Subtract 7px for nav-inner's padding.
+      navInner.style.width = navPanelWidth + 7 + "px";
       navInner.classList.add("fixed");
     }
-    if (!infoInner.classList.contains("fixed")) {
-      infoPanel.style.width = infoPanel.offsetWidth + "px";
-      // Subtract 6px for info-panel-inner's padding.
-      infoInner.style.width = (infoInner.offsetWidth - 6) + "px";
-      infoInner.classList.add("fixed");
+    if (!panelContainer.classList.contains("fixed")) {
+      const infoPanelWidth = infoPanel.offsetWidth;
+      infoPanel.style.width = infoPanelWidth + "px";
+      panelContainer.style.width = infoPanelWidth + "px";
+      panelContainer.classList.add("fixed");
     }
   } else {
     if (navInner.classList.contains("fixed")) {
@@ -305,10 +393,10 @@
       navInner.style.width = "";
       navInner.classList.remove("fixed");
     }
-    if (infoInner.classList.contains("fixed")) {
+    if (panelContainer.classList.contains("fixed")) {
       infoPanel.style.width = "";
-      infoInner.style.width = "";
-      infoInner.classList.remove("fixed");
+      panelContainer.style.width = "";
+      panelContainer.classList.remove("fixed");
     }
   }
   debounce(resizePanels, 200)();
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_style.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_style.dart
index 327a501..c9feedb 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_style.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/dart_page_style.dart
@@ -7,23 +7,20 @@
   background-color: black;
   color: white;
   font-family: 'Open Sans', sans-serif;
-  /* This allows very small files to be displayed lower than the very top of the
-   * screen.
-   */
-  margin: 8px;
-  padding: 0.5em;
+  margin: 0;
+  padding: 0;
 }
 
 h1 {
   font-size: 2.4em;
   font-weight: 600;
-  margin: 0;
+  margin: 8px 8px 0 8px;
 }
 
 h2#unit-name {
   font-size: 1.2em;
   font-weight: 600;
-  margin-bottom: 0;
+  margin: 8px 8px 0 8px;
 }
 
 .horizontal {
@@ -79,19 +76,38 @@
   list-style-type: none;
 }
 
-.nav-inner li.dir::before {
-  content: "▼";
-  font-size: 8px;
-  padding-right: 5px;
+.nav-inner li.dir {
+  margin-left: 5px;
 }
 
 .nav-inner li:not(.dir) {
-  padding-left: 5px;
+  margin-left: 20px;
+}
+
+.nav-inner li.dir .arrow {
+  cursor: pointer;
+  display: inline-block;
+  font-size: 10px;
+  margin-right: 4px;
+  transition: transform 0.5s ease-out;
+}
+
+.nav-inner li.dir .arrow.collapsed {
+  transform: rotate(-90deg);
+}
+
+.nav-inner ul {
+  max-height: 2000px;
+  transition: max-height 0.5s ease-out;
+}
+
+.nav-inner ul.collapsed {
+  max-height: 0 !important;
+  overflow: hidden;
 }
 
 .nav-inner .nav-link {
   color: #33ccff;
-  margin-left: 1em;
 }
 
 .nav-inner .selected-file {
@@ -232,29 +248,55 @@
 }
 
 .info-panel {
-  background-color: #282b2e;
   flex: 1 1 270px;
   font-size: 14px;
   margin: 10px 0;
 }
 
-.info-panel .info {
+.info-panel .edit-panel {
+  background-color: #282b2e;
+  overflow: auto;
+}
+
+.info-panel .panel-content {
   font-size: 13px;
   padding: 7px;
 }
 
-.info-panel .info > :first-child {
+.info-panel .panel-content > :first-child {
   margin-top: 0;
 }
 
-.info-panel ul {
-  padding-left: 18px;
+.info-panel .region-location {
+  padding-left: 12px;
+  text-indent: -12px;
 }
 
-.info-panel .nav-link {
+.info-panel .nowrap {
+  white-space: nowrap;
+}
+
+.info-panel ul,
+.info-panel ol {
+  padding-left: 20px;
+}
+
+.info-panel a {
   color: #33ccff;
 }
 
+.info-panel .edit-list {
+  background-color: #282b2e;
+  margin-top: 12px;
+  overflow: auto;
+}
+
+.edit-list .edit {
+  margin: 3px 0;
+  padding-left: 21px;
+  text-indent: -21px;
+}
+
 .footer {
   padding: 8px 8px 100px 8px;
 }
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 5b95cea..cd994aa 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
@@ -51,7 +51,9 @@
 
   /// Initialize a newly created builder.
   InfoBuilder(this.provider, this.includedPath, this.info, this.listener,
-      {this.explainNonNullableTypes = true});
+      // TODO(srawlins): Re-enable once
+      //  https://github.com/dart-lang/sdk/issues/40253 is fixed.
+      {this.explainNonNullableTypes = false});
 
   /// The analysis server used to get information about libraries.
   AnalysisServer get server => listener.server;
@@ -325,7 +327,7 @@
   List<RegionDetail> _computeDetails(AtomicEdit edit) {
     List<RegionDetail> details = [];
     var fixInfo = edit.info;
-    for (FixReasonInfo reason in fixInfo.fixReasons) {
+    for (FixReasonInfo reason in fixInfo?.fixReasons ?? []) {
       if (reason == null) {
         // Sometimes reasons are null, so just ignore them (see for example the
         // test case InfoBuilderTest.test_discardCondition.  If only we had
@@ -407,8 +409,10 @@
         break;
       case NullabilityFixKind.discardCondition:
       case NullabilityFixKind.discardElse:
+      case NullabilityFixKind.discardIf:
       case NullabilityFixKind.discardThen:
       case NullabilityFixKind.removeAs:
+      case NullabilityFixKind.removeNullAwareness:
         // There's no need for hints around code that is being removed.
         break;
       case NullabilityFixKind.makeTypeNullable:
@@ -497,7 +501,7 @@
   /// Explain the type annotations that were not changed because they were
   /// determined to be non-nullable.
   void _explainNonNullableTypes(SourceInformation sourceInfo,
-      List<RegionInfo> regions, OffsetMapper mapper) {
+      List<RegionInfo> regions, OffsetMapper mapper, LineInfo lineInfo) {
     Iterable<MapEntry<TypeAnnotation, NullabilityNodeInfo>> nonNullableTypes =
         sourceInfo.explicitTypeNullability.entries
             .where((entry) => !entry.value.isNullable);
@@ -517,6 +521,7 @@
               RegionType.nonNullableType,
               mapper.map(node.offset),
               node.length,
+              lineInfo.getLocation(node.offset).lineNumber,
               'This type is not changed; it is determined to be non-nullable',
               details));
         }
@@ -532,6 +537,7 @@
     unitInfo.sources ??= _computeNavigationSources(result);
     String content = result.content;
     List<RegionInfo> regions = unitInfo.regions;
+    var lineInfo = result.unit.lineInfo;
 
     // [fileEdit] is null when a file has no edits.
     List<SourceEdit> edits = fileEdit == null ? [] : List.of(fileEdit.edits);
@@ -555,29 +561,29 @@
         // Insert the replacement text without deleting the replaced text.
         content = content.replaceRange(end, end, replacement);
         var info = edit.info;
-        String explanation =
-            info != null ? '${info.description.appliedMessage}.' : null;
+        String explanation = info?.description?.appliedMessage;
         List<EditDetail> edits =
             info != null ? _computeEdits(info, sourceOffset) : [];
         List<RegionDetail> details = _computeDetails(edit);
+        var lineNumber = lineInfo.getLocation(sourceOffset).lineNumber;
         if (length > 0) {
           if (explanation != null) {
-            regions.add(RegionInfo(
-                RegionType.fix, offset, length, explanation, details,
+            regions.add(RegionInfo(RegionType.fix, offset, length, lineNumber,
+                explanation, details,
                 edits: edits));
           }
-          offset += length;
         }
         if (explanation != null) {
-          regions.add(RegionInfo(
-              RegionType.fix, offset, replacement.length, explanation, details,
+          regions.add(RegionInfo(RegionType.fix, offset, replacement.length,
+              lineNumber, explanation, details,
               edits: edits));
         }
         offset += replacement.length;
       }
     }
     if (explainNonNullableTypes) {
-      _explainNonNullableTypes(sourceInfo, regions, mapper);
+      _explainNonNullableTypes(
+          sourceInfo, regions, mapper, result.unit.lineInfo);
     }
     regions.sort((first, second) => first.offset.compareTo(second.offset));
     unitInfo.offsetMapper = mapper;
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
index 5ccfe9d..22fd567 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
@@ -77,6 +77,14 @@
   }
 
   @override
+  void prepareForUpdate() {
+    for (var source in data.sourceInformation.keys) {
+      _sourceInfo(source).changes = null;
+    }
+    data.propagationSteps.clear();
+  }
+
+  @override
   void propagationStep(PropagationInfo info) {
     data.propagationSteps.add(info);
   }
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 29b92b5..75d7725 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
@@ -29,7 +29,7 @@
     <div class="nav-panel">
       <div class="nav-inner">
         <p class="panel-heading">Navigation</p>
-        <p class="root">{{ root }}</p>
+        <p class="root">{{{ root }}}</p>
 {{{ links }}}
       </div><!-- /nav-inner -->
     </div><!-- /nav -->
@@ -39,7 +39,7 @@
     '{{! Compilation unit content is written here. }}'
     '<p class="welcome">'
     '{{! TODO(srawlins): More welcome text! }}'
-    'Select a source file on the left to preview the modifications.'
+    'Select a source file on the left to preview the edits.'
     '</p>'
     '</div>'
     '<div class="regions">'
@@ -50,16 +50,22 @@
     '</div><!-- /content -->'
     '''
     <div class="info-panel">
-      <div class="info-panel-inner">
-        <p class="panel-heading">Modification info</p>
-        <div class="info">
-          <p>
-          Hover over modified regions to see why the migration tool chose to
-          make the modification.
-          </p>
-        </div><!-- /info -->
-      </div><!-- /info-panel-inner -->
-    </div><!-- info-panel -->
+      <div class="panel-container">
+        <div class="edit-panel">
+          <p class="panel-heading">Edit info</p>
+          <div class="panel-content">
+            <p>
+            Click a modified region of code to see why the migration tool chose
+            to make the edit.
+            </p>
+          </div><!-- /panel-content -->
+        </div><!-- /edit-panel -->
+        <div class="edit-list">
+          <p class="panel-heading">Edits</p>
+          <div class="panel-content"></div>
+        </div><!-- /edit-list -->
+      </div><!-- /panel-container -->
+    </div><!-- /info-panel -->
     </div><!-- /horizontal -->
     </div><!-- /panels -->
   </body>
@@ -68,9 +74,6 @@
 /// Instrumentation display output for a library that was migrated to use
 /// non-nullable types.
 class InstrumentationRenderer {
-  /// A flag indicating whether the incremental workflow is currently supported.
-  static const bool supportsIncrementalWorkflow = false;
-
   /// Information for a whole migration, so that libraries can reference each
   /// other.
   final MigrationInfo migrationInfo;
@@ -119,7 +122,9 @@
     buffer.writeln('$indent<ul>');
     linksGroupedByDirectory
         .forEach((String directoryName, Iterable<UnitLink> groupedLinks) {
-      buffer.writeln('$indent  <li class="dir"><span>📁$directoryName</span>');
+      buffer.write('$indent  <li class="dir">');
+      buffer.writeln(
+          '<span class="arrow">&#x25BC;</span>&#x1F4C1;$directoryName');
       _renderNavigationSubtree(groupedLinks, depth + 1, buffer);
       buffer.writeln('$indent  </li>');
     });
@@ -127,7 +132,7 @@
       var modifications =
           link.modificationCount == 1 ? 'modification' : 'modifications';
       buffer.writeln('$indent  <li>'
-          '<a href="${link.url}" class="nav-link" data-name="${link.relativePath}">'
+          '&#x1F4C4;<a href="${link.url}" class="nav-link" data-name="${link.relativePath}">'
           '${link.fileName}</a> (${link.modificationCount} $modifications)'
           '</li>');
     }
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 b95008f..1007031 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
@@ -154,6 +154,9 @@
   /// The length of the region.
   final int length;
 
+  /// The line number of the beginning of the region.
+  final int lineNumber;
+
   /// The explanation to be displayed for the region.
   final String explanation;
 
@@ -164,8 +167,8 @@
   List<EditDetail> edits;
 
   /// Initialize a newly created region.
-  RegionInfo(
-      this.regionType, this.offset, this.length, this.explanation, this.details,
+  RegionInfo(this.regionType, this.offset, this.length, this.lineNumber,
+      this.explanation, this.details,
       {this.edits = const []});
 }
 
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
new file mode 100644
index 0000000..6b7d394
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_state.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, 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/fix/dartfix_listener.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/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+
+/// The state of an NNBD migration.
+class MigrationState {
+  /// The migration associated with the state.
+  final NullabilityMigration migration;
+
+  /// The root directory that contains all of the files that were migrated.
+  final String includedRoot;
+
+  /// The listener used to collect fixes.
+  final DartFixListener listener;
+
+  /// The listener that collected information during the migration.
+  final InstrumentationListener instrumentationListener;
+
+  /// The information that was built from the rest of the migration state.
+  MigrationInfo migrationInfo;
+
+  /// The object used to map paths.
+  PathMapper pathMapper;
+
+  /// Initialize a newly created migration state with the given values.
+  MigrationState(this.migration, this.includedRoot, this.listener,
+      this.instrumentationListener);
+
+  /// Refresh the state of the migration after the migration has been updated.
+  void refresh() async {
+    OverlayResourceProvider provider = listener.server.resourceProvider;
+    InfoBuilder infoBuilder = InfoBuilder(
+        provider, includedRoot, instrumentationListener.data, listener);
+    Set<UnitInfo> unitInfos = await infoBuilder.explainMigration();
+    var pathContext = provider.pathContext;
+    migrationInfo = MigrationInfo(
+        unitInfos, infoBuilder.unitMap, pathContext, includedRoot);
+    pathMapper = PathMapper(provider);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
index 77dc017..369b9da 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/region_renderer.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert' show HtmlEscape, HtmlEscapeMode;
+import 'dart:convert' show jsonEncode;
 
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
@@ -10,11 +10,6 @@
 
 /// The HTML that is displayed for a region of code.
 class RegionRenderer {
-  /// A converter which only escapes "&", "<", and ">". Safe for use in HTML
-  /// text, between HTML elements.
-  static const HtmlEscape _htmlEscape =
-      HtmlEscape(HtmlEscapeMode(escapeLtGt: true));
-
   /// A flag indicating whether the incremental workflow is currently supported.
   static const bool supportsIncrementalWorkflow = false;
 
@@ -40,58 +35,45 @@
 
   String render() {
     var unitDir = pathContext.dirname(pathMapper.map(unitInfo.path));
-    var buffer = StringBuffer();
-    buffer.write('<p class="region-location">');
-    // The line number is hard to compute here, but is known in the browser.
-    // The browser will write the line number at the end of this paragraph.
-    buffer.write(unitDir);
-    buffer.write('</p>');
-    buffer.write('<p>${_htmlEscape.convert(region.explanation)}</p>');
-    //
-    // Write out any details.
-    //
-    if (region.details.isNotEmpty) {
-      buffer.write('<ul>');
-      for (var detail in region.details) {
-        buffer.write('<li>');
-        buffer.write(detail.description);
-        NavigationTarget target = detail.target;
-        if (target != null) {
-          String relativePath = _relativePathToTarget(target, unitDir);
-          String targetUri = _uriForRelativePath(relativePath, target);
-          buffer.write(' (<a href="$targetUri" class="nav-link">');
-          buffer.write(relativePath);
-          // TODO(brianwilkerson) Add the line number to the link text. This
-          //  will require that either the contents of all navigation targets
-          //  have been set or that line information has been saved.
-          buffer.write('</a>)');
-        }
-        buffer.write('</li>');
-      }
-      buffer.write('</ul>');
+
+    Map<String, String> linkForTarget(NavigationTarget target) {
+      String relativePath = _relativePathToTarget(target, unitDir);
+      String targetUri = _uriForRelativePath(relativePath, target);
+      // TODO(brianwilkerson) Add the line number to the link text. This
+      //  will require that either the contents of all navigation targets
+      //  have been set or that line information has been saved.
+      return {'text': relativePath, 'href': targetUri};
     }
-    //
-    // Write out any edits.
-    //
-    if (supportsIncrementalWorkflow && region.edits.isNotEmpty) {
-      for (EditDetail edit in region.edits) {
-        int offset = edit.offset;
-        String targetUri = Uri(
-            scheme: 'http',
-            path: pathContext.basename(unitInfo.path),
-            queryParameters: {
-              'offset': offset.toString(),
-              'end': (offset + edit.length).toString(),
-              'replacement': edit.replacement
-            }).toString();
-        buffer.write('<p>');
-        buffer.write('<a href="$targetUri" class="nav-link">');
-        buffer.write(edit.description);
-        buffer.write('</a>');
-        buffer.write('</p>');
-      }
-    }
-    return buffer.toString();
+
+    Map<String, String> linkForEdit(EditDetail edit) => {
+          'text': edit.description,
+          'href': Uri(
+              scheme: 'http',
+              path: pathContext.basename(unitInfo.path),
+              queryParameters: {
+                'offset': edit.offset.toString(),
+                'end': (edit.offset + edit.length).toString(),
+                'replacement': edit.replacement
+              }).toString()
+        };
+
+    var response = {
+      'path': unitInfo.path,
+      'line': region.lineNumber,
+      'explanation': region.explanation,
+      'details': [
+        for (var detail in region.details)
+          {
+            'description': detail.description,
+            if (detail.target != null) 'link': linkForTarget(detail.target)
+          },
+      ],
+      if (supportsIncrementalWorkflow)
+        'edits': [
+          for (var edit in region.edits) linkForEdit(edit),
+        ],
+    };
+    return jsonEncode(response);
   }
 
   /// Returns the URL that will navigate to the given [target].
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
index 22a0523..fa26c56b 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/unit_renderer.dart
@@ -40,10 +40,37 @@
       'thisUnit': migrationInfo.computeName(unitInfo),
       'navContent': _computeNavigationContent(),
       'regions': _computeRegionContent(),
+      'editList': _computeEditList(),
     };
     return jsonEncode(response);
   }
 
+  String _computeEditList() {
+    var content = StringBuffer();
+    var editCount = unitInfo.fixRegions.length;
+    // TODO(srawlins): Change the edit count to be badge-like (number in a
+    //  circle).
+    if (editCount == 1) {
+      content
+          .write('<p><strong>$editCount</strong> edit was made to this file. '
+              "Click the edit's checkbox to toggle its reviewed state.</p>");
+    } else {
+      content
+          .write('<p><strong>$editCount</strong> edits were made to this file. '
+              "Click an edit's checkbox to toggle its reviewed state.</p>");
+    }
+    for (var region in unitInfo.fixRegions) {
+      content.write('<p class="edit">');
+      // TODO(srawlins): Make checkboxes functional.
+      content.write('<input type="checkbox" title="Click to mark reviewed" '
+          'disabled="disabled"> ');
+      content.write('line ${region.lineNumber}: ');
+      content.write(_htmlEscape.convert(region.explanation));
+      content.write('.</p>');
+    }
+    return content.toString();
+  }
+
   /// Return the content of the file with navigation links and anchors added.
   ///
   /// The content of the file (not including added links and anchors) will be
@@ -100,9 +127,7 @@
     //
     // Apply the insertions that have been computed.
     //
-    List<int> offsets = []
-      ..addAll(openInsertions.keys)
-      ..addAll(closeInsertions.keys);
+    List<int> offsets = [...openInsertions.keys, ...closeInsertions.keys];
     offsets.sort();
     StringBuffer navContent2 = StringBuffer();
     int previousOffset2 = 0;
diff --git a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart b/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
index f6d96d6..8af13c5 100644
--- a/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
+++ b/pkg/analysis_server/lib/src/edit/preview/http_preview_server.dart
@@ -5,8 +5,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
 import 'package:analysis_server/src/edit/preview/preview_site.dart';
 
 /// Instances of the class [AbstractGetHandler] handle GET requests.
@@ -18,12 +17,8 @@
 /// Instances of the class [HttpPreviewServer] implement a simple HTTP server
 /// that serves up dartfix preview pages.
 class HttpPreviewServer {
-  /// The information about the migration that will be used to serve up pages.
-  final MigrationInfo migrationInfo;
-
-  /// The path mapper used to map paths from the unit infos to the paths being
-  /// served.
-  final PathMapper pathMapper;
+  /// The state of the migration being previewed.
+  final MigrationState migrationState;
 
   /// An object that can handle GET requests.
   AbstractGetHandler getHandler;
@@ -32,7 +27,7 @@
   Future<HttpServer> _serverFuture;
 
   /// Initialize a newly created HTTP server.
-  HttpPreviewServer(this.migrationInfo, this.pathMapper);
+  HttpPreviewServer(this.migrationState);
 
   /// Return the port this server is bound to.
   Future<int> get boundPort async {
@@ -69,7 +64,7 @@
 
   /// Handle a GET request received by the HTTP server.
   Future<void> _handleGetRequest(HttpRequest request) async {
-    getHandler ??= PreviewSite(migrationInfo, pathMapper);
+    getHandler ??= PreviewSite(migrationState);
     await getHandler.handleGetRequest(request);
   }
 
diff --git a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart b/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
index 4d61e6c..4b229ea 100644
--- a/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
+++ b/pkg/analysis_server/lib/src/edit/preview/preview_site.dart
@@ -6,6 +6,7 @@
 import 'dart:io';
 
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_state.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:analysis_server/src/edit/preview/dart_file_page.dart';
 import 'package:analysis_server/src/edit/preview/exception_page.dart';
@@ -27,12 +28,8 @@
   /// The path of the JS page used to associate highlighting within a Dart file.
   static const highlightJSPagePath = '/js/highlight.pack.js';
 
-  /// The information about the migration that will be used to serve up pages.
-  final MigrationInfo migrationInfo;
-
-  /// The path mapper used to map paths from the unit infos to the paths being
-  /// served.
-  final PathMapper pathMapper;
+  /// The state of the migration being previewed.
+  final MigrationState migrationState;
 
   /// A table mapping the paths of files to the information about the
   /// compilation units at those paths.
@@ -40,8 +37,7 @@
 
   /// Initialize a newly created site to serve a preview of the results of an
   /// NNBD migration.
-  PreviewSite(this.migrationInfo, this.pathMapper)
-      : super('NNBD Migration Preview') {
+  PreviewSite(this.migrationState) : super('NNBD Migration Preview') {
     Set<UnitInfo> unitInfos = migrationInfo.units;
     ResourceProvider provider = pathMapper.provider;
     for (UnitInfo unit in unitInfos) {
@@ -62,6 +58,14 @@
     }
   }
 
+  /// Return the information about the migration that will be used to serve up
+  /// pages.
+  MigrationInfo get migrationInfo => migrationState.migrationInfo;
+
+  /// Return the path mapper used to map paths from the unit infos to the paths
+  /// being served.
+  PathMapper get pathMapper => migrationState.pathMapper;
+
   @override
   Page createExceptionPage(String message, StackTrace trace) {
     // Use createExceptionPageWithPath instead.
@@ -87,28 +91,42 @@
     Uri uri = request.uri;
     if (uri.query.contains('replacement')) {
       performEdit(uri);
-      performMigration();
     }
     String path = uri.path;
     try {
       if (path == highlightCssPagePath) {
-        return respond(request, HighlightCssPage(this));
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/language/issues/791
+        return await respond(request, HighlightCssPage(this));
       } else if (path == highlightJSPagePath) {
-        return respond(request, HighlightJSPage(this));
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/language/issues/791
+        return await respond(request, HighlightJSPage(this));
       } else if (path == '/' || path == migrationInfo.includedRoot) {
-        return respond(request, IndexFilePage(this));
+        // Note: `return await` needed due to
+        // https://github.com/dart-lang/language/issues/791
+        return await respond(request, IndexFilePage(this));
       }
       UnitInfo unitInfo = unitInfoMap[path];
       if (unitInfo != null) {
         if (uri.queryParameters.containsKey('inline')) {
-          return respond(request, DartFilePage(this, unitInfo));
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/language/issues/791
+          return await respond(request, DartFilePage(this, unitInfo));
         } else if (uri.queryParameters.containsKey('region')) {
-          return respond(request, RegionPage(this, unitInfo));
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/language/issues/791
+          return await respond(request, RegionPage(this, unitInfo));
         } else {
-          return respond(request, IndexFilePage(this));
+          // Note: `return await` needed due to
+          // https://github.com/dart-lang/language/issues/791
+          return await respond(request, IndexFilePage(this));
         }
       }
-      return respond(request, createUnknownPage(path), HttpStatus.notFound);
+      // Note: `return await` needed due to
+      // https://github.com/dart-lang/language/issues/791
+      return await respond(
+          request, createUnknownPage(path), HttpStatus.notFound);
     } catch (exception, stackTrace) {
       try {
         await respond(
@@ -127,9 +145,9 @@
 
   /// Perform the edit indicated by the [uri].
   void performEdit(Uri uri) {
-    // We might want to allow edits to files other than the file to be displayed
-    // after the edit is performed, in which case we'll need to encode the file
-    // path as a query parameter.
+    //
+    // Update the code on disk.
+    //
     Map<String, String> params = uri.queryParameters;
     String path = uri.path;
     int offset = int.parse(params['offset']);
@@ -139,12 +157,19 @@
     String oldContent = file.readAsStringSync();
     String newContent = oldContent.replaceRange(offset, end, replacement);
     file.writeAsStringSync(newContent);
-  }
-
-  /// Perform the migration again and update this site to serve up the results
-  /// of the new migration.
-  void performMigration() {
-    // TODO(brianwilkerson) Implement this.
+    //
+    // Update the graph by adding or removing an edge.
+    //
+    int length = end - offset;
+    if (length == 0) {
+      throw UnsupportedError('Implement insertions');
+    } else {
+      throw UnsupportedError('Implement removals');
+    }
+    //
+    // Refresh the state of the migration.
+    //
+//    migrationState.refresh();
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
index 478efe6..7ecf01c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 
 import '../../../protocol_server.dart' show CompletionSuggestion;
@@ -56,17 +57,24 @@
     optype = (request as DartCompletionRequestImpl).opType;
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
 
+    final seenElements = <protocol.Element>{};
+
     // Traverse imports including dart:core
     for (ImportElement importElem in imports) {
       LibraryElement libElem = importElem?.importedLibrary;
       if (libElem != null) {
-        suggestions.addAll(_buildSuggestions(libElem.exportNamespace,
+        final newSuggestions = _buildSuggestions(libElem.exportNamespace,
             prefix: importElem.prefix?.name,
             showNames: showNamesIn(importElem),
-            hiddenNames: hiddenNamesIn(importElem)));
+            hiddenNames: hiddenNamesIn(importElem));
+        for (var suggestion in newSuggestions) {
+          // Filter out multiply-exported elements (like Future and Stream).
+          if (seenElements.add(suggestion.element)) {
+            suggestions.add(suggestion);
+          }
+        }
       }
     }
-
     return suggestions;
   }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 9d248a4..a41beec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -308,6 +308,13 @@
   Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
 
   /**
+   * Add the given completion [suggestion].
+   */
+  void addCompletionSuggestion(CompletionSuggestion suggestion) {
+    _suggestionMap[suggestion.completion] = suggestion;
+  }
+
+  /**
    * Add a suggestion based upon the given element, provided that it is not
    * shadowed by a previously added suggestion.
    */
@@ -368,7 +375,7 @@
     CompletionSuggestion suggestion =
         createSuggestion(element, relevance: relevance);
     if (suggestion != null) {
-      _suggestionMap[suggestion.completion] = suggestion;
+      addCompletionSuggestion(suggestion);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index b182711..930181e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -10,9 +10,11 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart';
 
-import '../../../protocol_server.dart' show CompletionSuggestion;
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
 
 /**
  * A contributor for calculating instance invocation / access suggestions
@@ -288,9 +290,34 @@
           }
         }
       }
+      if (targetType.isDartCoreFunction) {
+        _addFunctionCallSuggestion();
+      }
     }
   }
 
+  void _addFunctionCallSuggestion() {
+    const callString = 'call()';
+    final element = protocol.Element(
+        protocol.ElementKind.METHOD, callString, protocol.Element.makeFlags(),
+        location: null,
+        typeParameters: null,
+        parameters: null,
+        returnType: 'void');
+    addCompletionSuggestion(CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      DART_RELEVANCE_HIGH,
+      callString,
+      callString.length,
+      0,
+      false,
+      false,
+      displayText: callString,
+      element: element,
+      returnType: 'void',
+    ));
+  }
+
   /**
    * Get a list of [InterfaceType]s that should be searched to find the
    * possible completions for an object having type [type].
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index 140c6b3..569f5ca 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
@@ -548,9 +548,8 @@
     return expr;
   }
 
-  AstNode _selectedNode({int at}) =>
-      NodeLocator(at == null ? selectionOffset : at)
-          .searchWithin(completionContext.resolveResult.unit);
+  AstNode _selectedNode({int at}) => NodeLocator(at ?? selectionOffset)
+      .searchWithin(completionContext.resolveResult.unit);
 
   void _setCompletionFromBuilder(
       DartChangeBuilder builder, PostfixCompletionKind kind,
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index 1be2f37..1be8f53 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -609,7 +609,7 @@
             // emptyCondition, emptyInitializersEmptyCondition
             replacementLength = match.end - match.start;
             sb = SourceBuilder(file, forParts.leftSeparator.offset);
-            sb.append('; ${match.group(1) == null ? '' : match.group(1)}; )');
+            sb.append('; ${match.group(1) ?? ''}; )');
             String suffix = text.substring(match.end);
             if (suffix.trim().isNotEmpty) {
               sb.append(' ');
@@ -1202,7 +1202,7 @@
   }
 
   AstNode _selectedNode({int at}) =>
-      NodeLocator(at == null ? selectionOffset : at).searchWithin(unit);
+      NodeLocator(at ?? selectionOffset).searchWithin(unit);
 
   void _setCompletion(StatementCompletionKind kind, [List args]) {
     assert(exitPosition != null);
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 d1b1801..597ba77 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core';
+import 'dart:math' as math;
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
@@ -210,8 +211,9 @@
 
   Future<List<Fix>> compute() async {
     node = NodeLocator2(errorOffset).searchWithin(unit);
-    coveredNode = NodeLocator2(errorOffset, errorOffset + errorLength - 1)
-        .searchWithin(unit);
+    coveredNode =
+        NodeLocator2(errorOffset, math.max(errorOffset + errorLength - 1, 0))
+            .searchWithin(unit);
     if (coveredNode == null) {
       // TODO(brianwilkerson) Figure out why the coveredNode is sometimes null.
       return fixes;
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 3fa52ff..bf3f07d 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/utilities/null_string_sink.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -1939,7 +1940,7 @@
     var synchronousSession = SynchronousSession(analysisOptions, null);
     List<int> bytes =
         SummaryBuilder([], AnalysisContextImpl(synchronousSession, null))
-            .build();
+            .build(featureSet: FeatureSet.fromEnableFlags([]));
     newFileWithBytes('$projPath/sdk.ds', bytes);
     // Setup _embedder.yaml.
     newFile('$libPath/_embedder.yaml', content: r'''
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 5fc5fa9..7a71894 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -81,21 +81,14 @@
   }
 
   test_collection_if_elements() async {
-    // Add analysis options to enable ui as code
-    newFile('/project/analysis_options.yaml', content: '''
-analyzer:
-  enable-experiment:
-    - control-flow-collections
-    - spread-collections
-''');
     addTestFile('''
 f(bool b) {
   return ['a', b ? 'c' : 'd', 'e'];
 }
 ''');
     createProject();
-    EditDartfixResult result =
-        await performFix(includedFixes: ['collection-if-elements']);
+    EditDartfixResult result = await performFix(
+        includedFixes: ['prefer_if_elements_to_conditional_expressions']);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
     expectEdits(result.edits, '''
@@ -111,7 +104,7 @@
     ''');
     createProject();
 
-    final result = await performFixRaw(excludedFixes: ['not-a-fix']);
+    final result = await performFixRaw(excludedFixes: ['not_a_fix']);
     expect(result.error, isNotNull);
   }
 
@@ -129,7 +122,7 @@
     createProject();
 
     // Assert no suggestions now that source has been excluded
-    final result = await performFix(includedFixes: ['double-to-int']);
+    final result = await performFix(includedFixes: ['prefer_int_literals']);
     expect(result.suggestions, hasLength(0));
     expect(result.edits, hasLength(0));
   }
@@ -144,7 +137,8 @@
 }
     ''');
     createProject();
-    EditDartfixResult result = await performFix();
+    EditDartfixResult result = await performFix(
+        includedFixes: ['wrong_number_of_type_arguments_constructor']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'type arguments', 60, 8);
     expectEdits(result.edits, '''
@@ -163,37 +157,10 @@
     ''');
     createProject();
 
-    final result = await performFixRaw(includedFixes: ['not-a-fix']);
+    final result = await performFixRaw(includedFixes: ['not_a_fix']);
     expect(result.error, isNotNull);
   }
 
-  test_map_for_elements() async {
-    // Add analysis options to enable ui as code
-    newFile('/project/analysis_options.yaml', content: '''
-analyzer:
-  enable-experiment:
-    - control-flow-collections
-    - spread-collections
-''');
-    addTestFile('''
-f(Iterable<int> i) {
-  var k = 3;
-  return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k);
-}
-''');
-    createProject();
-    EditDartfixResult result =
-        await performFix(includedFixes: ['map-for-elements']);
-    expect(result.suggestions.length, greaterThanOrEqualTo(1));
-    expect(result.hasErrors, isFalse);
-    expectEdits(result.edits, '''
-f(Iterable<int> i) {
-  var k = 3;
-  return { for (var e in i) e * 2 : k };
-}
-''');
-  }
-
   test_nonNullable() async {
     createAnalysisOptionsFile(experiments: ['non-nullable']);
     addTestFile('''
@@ -302,7 +269,7 @@
 
     // Assert dartfix suggestions
     EditDartfixResult result =
-        await performFix(includedFixes: ['double-to-int']);
+        await performFix(includedFixes: ['prefer_int_literals']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'int literal', 38, 4);
     expectEdits(result.edits, '''
@@ -320,7 +287,7 @@
 
     // Assert dartfix suggestions
     EditDartfixResult result =
-        await performFix(includedFixes: ['double-to-int']);
+        await performFix(includedFixes: ['prefer_int_literals']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'int literal', 38, 4);
     expectEdits(result.edits, '''
@@ -343,7 +310,8 @@
     // Add analysis options to enable ui as code
     addTestFile('f({a: 1}) { }');
     createProject();
-    EditDartfixResult result = await performFix();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['prefer_equal_for_default_values']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], "Replace ':' with '='", 4, 1);
     expect(result.hasErrors, isFalse);
@@ -356,11 +324,11 @@
   Map<int, int>.fromIterable([1, 2, 3], key: (i) => i, value: (i) => i * 2);
     ''');
     createProject();
-    EditDartfixResult result =
-        await performFix(includedFixes: ['map-for-elements']);
+    EditDartfixResult result = await performFix(
+        includedFixes: ['prefer_for_elements_to_map_fromIterable']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(
-        result.suggestions[0], "Convert to a 'for' element", 10, 3);
+        result.suggestions[0], "Convert to a 'for' element", 10, 73);
     expectEdits(result.edits, '''
 var m =
   { for (var i in [1, 2, 3]) i : i * 2 };
@@ -372,11 +340,11 @@
 f(bool b) => ['a', b ? 'c' : 'd', 'e'];
     ''');
     createProject();
-    EditDartfixResult result =
-        await performFix(includedFixes: ['collection-if-elements']);
+    EditDartfixResult result = await performFix(
+        includedFixes: ['prefer_if_elements_to_conditional_expressions']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(
-        result.suggestions[0], "Convert to an 'if' element", 19, 1);
+        result.suggestions[0], "Convert to an 'if' element", 19, 13);
     expectEdits(result.edits, '''
 f(bool b) => ['a', if (b) 'c' else 'd', 'e'];
     ''');
@@ -388,7 +356,7 @@
     ''');
     createProject();
     EditDartfixResult result =
-        await performFix(includedFixes: ['double-to-int']);
+        await performFix(includedFixes: ['prefer_int_literals']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'int literal', 24, 4);
     expectEdits(result.edits, '''
@@ -400,7 +368,7 @@
     addTestFile('main(List<String> args) { if (args.length == 0) { } }');
     createProject();
     EditDartfixResult result =
-        await performFix(includedFixes: ['prefer-is-empty']);
+        await performFix(includedFixes: ['prefer_is_empty']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], "Replace with 'isEmpty'", 30, 16);
     expect(result.hasErrors, isFalse);
@@ -415,7 +383,8 @@
 class C with B {}
     ''');
     createProject();
-    EditDartfixResult result = await performFix();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['convert_class_to_mixin']);
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'mixin', 17, 1);
     expectEdits(result.edits, '''
@@ -437,7 +406,7 @@
 ''');
     createProject();
     EditDartfixResult result =
-        await performFix(includedFixes: ['prefer-single-quotes']);
+        await performFix(includedFixes: ['prefer_single_quotes']);
     expect(result.suggestions, hasLength(2));
     expectSuggestion(
         result.suggestions[0], 'Convert to single quoted string', 12, 5);
@@ -456,20 +425,13 @@
   }
 
   test_preferSpreadCollections() async {
-    // Add analysis options to enable ui as code
-    newFile('/project/analysis_options.yaml', content: '''
-analyzer:
-  enable-experiment:
-    - control-flow-collections
-    - spread-collections
-''');
     addTestFile('''
 var l1 = ['b'];
 var l2 = ['a']..addAll(l1);
 ''');
     createProject();
     EditDartfixResult result =
-        await performFix(includedFixes: ['use-spread-collections']);
+        await performFix(includedFixes: ['prefer_spread_collections']);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
     expectEdits(result.edits, '''
diff --git a/pkg/analysis_server/test/integration/edit/dartfix_test.dart b/pkg/analysis_server/test/integration/edit/dartfix_test.dart
index d389950..31942a9 100644
--- a/pkg/analysis_server/test/integration/edit/dartfix_test.dart
+++ b/pkg/analysis_server/test/integration/edit/dartfix_test.dart
@@ -25,36 +25,19 @@
     standardAnalysisSetup();
   }
 
-  test_dartfix() async {
-    setupTarget();
-    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)]);
-    expect(result.hasErrors, isFalse);
-    expect(result.suggestions.length, greaterThanOrEqualTo(1));
-    expect(result.edits.length, greaterThanOrEqualTo(1));
-  }
-
   test_dartfix_exclude() async {
     setupTarget();
     EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
-        excludedFixes: ['use-mixin']);
+        excludedFixes: ['convert_class_to_mixin']);
     expect(result.hasErrors, isFalse);
     expect(result.suggestions.length, 0);
     expect(result.edits.length, 0);
   }
 
-  test_dartfix_exclude_other() async {
-    setupTarget();
-    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
-        excludedFixes: ['double-to-int']);
-    expect(result.hasErrors, isFalse);
-    expect(result.suggestions.length, greaterThanOrEqualTo(1));
-    expect(result.edits.length, greaterThanOrEqualTo(1));
-  }
-
   test_dartfix_include() async {
     setupTarget();
     EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
-        includedFixes: ['use-mixin']);
+        includedFixes: ['convert_class_to_mixin']);
     expect(result.hasErrors, isFalse);
     expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.edits.length, greaterThanOrEqualTo(1));
@@ -63,18 +46,9 @@
   test_dartfix_include_other() async {
     setupTarget();
     EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
-        includedFixes: ['double-to-int']);
+        includedFixes: ['prefer_int_literals']);
     expect(result.hasErrors, isFalse);
     expect(result.suggestions.length, 0);
     expect(result.edits.length, 0);
   }
-
-  test_dartfix_required() async {
-    setupTarget();
-    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
-        includeRequiredFixes: true);
-    expect(result.hasErrors, isFalse);
-    expect(result.suggestions.length, greaterThanOrEqualTo(1));
-    expect(result.edits.length, greaterThanOrEqualTo(1));
-  }
 }
diff --git a/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart b/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart
index 2d92b6a..b62ed77 100644
--- a/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart
+++ b/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart
@@ -20,7 +20,5 @@
     standardAnalysisSetup();
     EditGetDartfixInfoResult info = await sendEditGetDartfixInfo();
     expect(info.fixes.length, greaterThanOrEqualTo(3));
-    var fix = info.fixes.firstWhere((f) => f.name == 'use-mixin');
-    expect(fix.isRequired, isTrue);
   }
 }
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index b4320ee..eb1ad52 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1576,12 +1576,12 @@
   /// source requires it.
   ///
   /// If includedFixes is specified, then those fixes will be applied. If
-  /// includeRequiredFixes is specified, then "required" fixes will be applied
-  /// in addition to whatever fixes are specified in includedFixes if any. If
-  /// neither includedFixes nor includeRequiredFixes is specified, then all
-  /// fixes will be applied. If excludedFixes is specified, then those fixes
-  /// will not be applied regardless of whether they are "required" or
-  /// specified in includedFixes.
+  /// includePedanticFixes is specified, then fixes associated with the
+  /// pedantic rule set will be applied in addition to whatever fixes are
+  /// specified in includedFixes if any. If neither includedFixes nor
+  /// includePedanticFixes is specified, then no fixes will be applied. If
+  /// excludedFixes is specified, then those fixes will not be applied
+  /// regardless of whether they are specified in includedFixes.
   ///
   /// Parameters
   ///
@@ -1609,10 +1609,6 @@
   ///
   ///   A flag indicating whether "pedantic" fixes should be applied.
   ///
-  /// includeRequiredFixes: bool (optional)
-  ///
-  ///   A flag indicating whether "required" fixes should be applied.
-  ///
   /// excludedFixes: List<String> (optional)
   ///
   ///   A list of names indicating which fixes should not be applied.
@@ -1670,14 +1666,12 @@
   Future<EditDartfixResult> sendEditDartfix(List<String> included,
       {List<String> includedFixes,
       bool includePedanticFixes,
-      bool includeRequiredFixes,
       List<String> excludedFixes,
       int port,
       String outputDir}) async {
     var params = EditDartfixParams(included,
             includedFixes: includedFixes,
             includePedanticFixes: includePedanticFixes,
-            includeRequiredFixes: includeRequiredFixes,
             excludedFixes: excludedFixes,
             port: port,
             outputDir: outputDir)
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 5a4f914..6cf2b8a 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -325,11 +325,10 @@
 /// {
 ///   "name": String
 ///   "description": optional String
-///   "isRequired": optional bool
 /// }
 final Matcher isDartFix = LazyMatcher(() => MatchesJsonObject(
     'DartFix', {'name': isString},
-    optionalFields: {'description': isString, 'isRequired': isBool}));
+    optionalFields: {'description': isString}));
 
 /// DartFixSuggestion
 ///
@@ -2208,7 +2207,6 @@
 ///   "included": List<FilePath>
 ///   "includedFixes": optional List<String>
 ///   "includePedanticFixes": optional bool
-///   "includeRequiredFixes": optional bool
 ///   "excludedFixes": optional List<String>
 ///   "port": optional int
 ///   "outputDir": optional FilePath
@@ -2219,7 +2217,6 @@
         }, optionalFields: {
           'includedFixes': isListOf(isString),
           'includePedanticFixes': isBool,
-          'includeRequiredFixes': isBool,
           'excludedFixes': isListOf(isString),
           'port': isInt,
           'outputDir': isFilePath
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index df904f2..f1b65fe 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -183,7 +183,8 @@
       String paramName,
       String paramType,
       String defaultArgListString = _UNCHECKED,
-      List<int> defaultArgumentListTextRanges}) {
+      List<int> defaultArgumentListTextRanges,
+      bool isSynthetic = false}) {
     CompletionSuggestion cs =
         getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
     if (cs == null) {
@@ -199,7 +200,7 @@
     expect(cs.selectionLength, equals(0));
     expect(cs.isDeprecated, equals(isDeprecated));
     expect(cs.isPotential, equals(isPotential));
-    if (cs.element != null) {
+    if (!isSynthetic && cs.element != null) {
       expect(cs.element.location, isNotNull);
       expect(cs.element.location.file, isNotNull);
       expect(cs.element.location.offset, isNotNull);
@@ -327,14 +328,14 @@
         elemKind: ElementKind.FIELD,
         isDeprecated: isDeprecated);
     // The returnType represents the type of a field
-    expect(cs.returnType, type != null ? type : 'dynamic');
+    expect(cs.returnType, type ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.FIELD));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
     // The returnType represents the type of a field
-    expect(element.returnType, type != null ? type : 'dynamic');
+    expect(element.returnType, type ?? 'dynamic');
     assertHasNoParameterInfo(cs);
     return cs;
   }
@@ -400,8 +401,7 @@
     //    expect(param, isNotNull);
     //    expect(param[0], equals('('));
     //    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
+    expect(element.returnType, equals(returnType ?? 'dynamic'));
     // TODO (danrubel) Determine why param info is missing
     //    assertHasParameterInfo(cs);
     return cs;
@@ -416,14 +416,13 @@
         relevance: relevance,
         elemKind: ElementKind.GETTER,
         isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    expect(cs.returnType, returnType ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.GETTER));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
+    expect(element.returnType, equals(returnType ?? 'dynamic'));
     assertHasNoParameterInfo(cs);
     return cs;
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 4d42d39..bd26c3c 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -2670,12 +2670,7 @@
     assertSuggestConstructor('D', elemOffset: -1);
   }
 
-  @failingTest
   test_InstanceCreationExpression_imported() async {
-    // This is failing because the constructor for Future is added twice. I
-    // suspect that we're adding it from both dart:core and dart:async and are
-    // not noticing that it's the same element.
-
     // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2693,7 +2688,13 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestConstructor('Object');
+    // Exported by dart:core and dart:async
     assertSuggestConstructor('Future');
+    assertSuggestConstructor('Future.delayed');
+    assertSuggestConstructor('Future.microtask');
+    assertSuggestConstructor('Future.value');
+    assertSuggestConstructor('Stream.fromIterable');
+    // ...
     assertSuggestConstructor('A');
     // Suggested by ConstructorContributor
     assertNotSuggested('B');
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
index 6f82a5e..f7ae6b1 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -24,13 +24,13 @@
     // Local variables should only be suggested by LocalReferenceContributor
     CompletionSuggestion cs = assertSuggest(name,
         csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    expect(cs.returnType, returnType ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.LOCAL_VARIABLE));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    expect(element.returnType, returnType ?? 'dynamic');
     assertHasNoParameterInfo(cs);
     return cs;
   }
@@ -39,14 +39,13 @@
       {int relevance = DART_RELEVANCE_PARAMETER}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    expect(cs.returnType, returnType ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.PARAMETER));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
+    expect(element.returnType, equals(returnType ?? 'dynamic'));
     return cs;
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 2c151ae..cb7fffc 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -33,13 +33,13 @@
     // Local variables should only be suggested by LocalReferenceContributor
     CompletionSuggestion cs = assertSuggest(name,
         csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    expect(cs.returnType, returnType ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.LOCAL_VARIABLE));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    expect(element.returnType, returnType ?? 'dynamic');
     assertHasNoParameterInfo(cs);
     return cs;
   }
@@ -48,14 +48,13 @@
       {int relevance = DART_RELEVANCE_PARAMETER}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    expect(cs.returnType, returnType ?? 'dynamic');
     Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(ElementKind.PARAMETER));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
+    expect(element.returnType, equals(returnType ?? 'dynamic'));
     return cs;
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index f53ba6c..26e0c7f 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -2225,6 +2225,59 @@
     assertNotSuggested('Foo');
   }
 
+  test_InterfaceType_Function_call() async {
+    addTestSource('''
+void f() {
+  Function fun;
+  fun.^
+}
+''');
+
+    await computeSuggestions();
+    assertSuggest(
+      'call()',
+      selectionOffset: 6,
+      elemKind: ElementKind.METHOD,
+      isSynthetic: true,
+    );
+  }
+
+  test_InterfaceType_Function_extended_call() async {
+    addTestSource('''
+class MyFun extends Function { }
+void f() {
+  MyFun fun;
+  fun.^
+}
+''');
+
+    await computeSuggestions();
+    assertSuggest(
+      'call()',
+      selectionOffset: 6,
+      elemKind: ElementKind.METHOD,
+      isSynthetic: true,
+    );
+  }
+
+  test_InterfaceType_Function_implemented_call() async {
+    addTestSource('''
+class MyFun implements Function { }
+void f() {
+  MyFun fun;
+  fun.^
+}
+''');
+
+    await computeSuggestions();
+    assertSuggest(
+      'call()',
+      selectionOffset: 6,
+      elemKind: ElementKind.METHOD,
+      isSynthetic: true,
+    );
+  }
+
   test_InterpolationExpression() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addSource('/home/test/lib/a.dart', '''
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 0da2350..706d1cc 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -457,7 +457,7 @@
     var refactoringWorkspace = RefactoringWorkspace([driver], searchEngine);
     // Allow passing an oldName for when we don't want to rename testSource,
     // but otherwise fall back to testSource.fullname
-    oldFile = convertPath(oldFile != null ? oldFile : testSource.fullName);
+    oldFile = convertPath(oldFile ?? testSource.fullName);
     refactoring = MoveFileRefactoring(
         resourceProvider, refactoringWorkspace, testAnalysisResult, oldFile);
     refactoring.newFile = convertPath(newFile);
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 6427cb0..79735da 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
@@ -596,6 +596,35 @@
     // regions[2] is the `level!` fix.
   }
 
+  test_insertParens() async {
+    var originalContent = '''
+class C {
+  C operator+(C c) => null;
+}
+C/*!*/ _f(C c) => c + c;
+''';
+    var migratedContent = '''
+class C {
+  C? operator+(C c) => null;
+}
+C/*!*/ _f(C c) => (c + c)!;
+''';
+    UnitInfo unit = await buildInfoForSingleTestFile(originalContent,
+        migratedContent: migratedContent);
+    List<RegionInfo> regions = unit.fixRegions;
+    expect(regions, hasLength(2));
+    assertRegion(
+        region: regions[0],
+        offset: migratedContent.indexOf('? operator'),
+        length: 1,
+        details: ["This method returns an explicit 'null' on line 2"]);
+    assertRegion(
+        region: regions[1],
+        offset: migratedContent.indexOf('!;'),
+        length: 1,
+        details: ['This value must be null-checked before use here.']);
+  }
+
   test_listAndSetLiteralTypeArgument() async {
     UnitInfo unit = await buildInfoForSingleTestFile('''
 void f() {
@@ -1135,6 +1164,45 @@
         details: ["This parameter has an implicit default value of 'null'"]);
   }
 
+  test_removal_handles_offsets_correctly() async {
+    var originalContent = '''
+void f(num n, int/*?*/ i) {
+  if (n is! int) return;
+  print((n as int).isEven);
+  print(i + 1);
+}
+''';
+    // Note: even though `as int` is removed, it still shows up in the
+    // preview, since we show deleted text.
+    var migratedContent = '''
+void f(num n, int?/*?*/ i) {
+  if (n is! int) return;
+  print((n as int).isEven);
+  print(i! + 1);
+}
+''';
+    UnitInfo unit = await buildInfoForSingleTestFile(originalContent,
+        migratedContent: migratedContent, removeViaComments: false);
+    List<RegionInfo> regions = unit.regions;
+    expect(regions, hasLength(4));
+    // regions[0] is the addition of `?` to the type of `i`.
+    // TODO(paulberry): why does the discarded downcast appear twice?
+    assertRegion(
+        region: regions[1],
+        offset: migratedContent.indexOf(' as int'),
+        length: ' as int'.length,
+        details: []);
+    assertRegion(
+        region: regions[2],
+        offset: migratedContent.indexOf(' as int'),
+        length: 0,
+        details: []);
+    assertRegion(
+        region: regions[3],
+        offset: migratedContent.indexOf('! + 1'),
+        details: ['node with no info (never)']);
+  }
+
   test_return_fromOverriden() async {
     UnitInfo unit = await buildInfoForSingleTestFile('''
 abstract class A {
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
index 32bc9d1..c273850 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/instrumentation_renderer_test.dart
@@ -32,7 +32,8 @@
   test_navigation_containsRoot() async {
     var renderedView = await renderViewForTestFiles(
         {convertPath('/project/lib/a.dart'): 'int a = null;'});
-    expect(renderedView, contains('<p class="root">&#x2F;project</p>'));
+    var expectedPath = convertPath('/project');
+    expect(renderedView, contains('<p class="root">$expectedPath</p>'));
   }
 
   test_navigation_containsMultipleLinks_multipleRoots() async {
@@ -45,24 +46,24 @@
     renderedView = _stripAttributes(renderedView);
     expect(renderedView, contains('''
 <ul>
-  <li class="dir"><span>📁bin</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;bin
     <ul>
-      <li><a href="..." class="nav-link" data-name="...">bin.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">bin.dart</a> (1 modification)</li>
     </ul>
   </li>
-  <li class="dir"><span>📁lib</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;lib
     <ul>
-      <li class="dir"><span>📁src</span>
+      <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;src
         <ul>
-          <li><a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
+          <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
         </ul>
       </li>
-      <li><a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
     </ul>
   </li>
-  <li class="dir"><span>📁test</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;test
     <ul>
-      <li><a href="..." class="nav-link" data-name="...">test.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">test.dart</a> (1 modification)</li>
     </ul>
   </li>
 </ul>'''));
@@ -77,17 +78,17 @@
     renderedView = _stripAttributes(renderedView);
     expect(renderedView, contains('''
 <ul>
-  <li class="dir"><span>📁lib</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;lib
     <ul>
-      <li class="dir"><span>📁src</span>
+      <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;src
         <ul>
-          <li><a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
+          <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
         </ul>
       </li>
-      <li><a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
     </ul>
   </li>
-  <li><a href="..." class="nav-link" data-name="...">tool.dart</a> (1 modification)</li>
+  <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">tool.dart</a> (1 modification)</li>
 </ul>'''));
   }
 
@@ -99,10 +100,10 @@
     renderedView = _stripAttributes(renderedView);
     expect(renderedView, contains('''
 <ul>
-  <li class="dir"><span>📁lib</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;lib
     <ul>
-      <li><a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
-      <li><a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
+      <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">b.dart</a> (1 modification)</li>
     </ul>
   </li>
 </ul>'''));
@@ -114,11 +115,11 @@
     renderedView = _stripAttributes(renderedView);
     expect(renderedView, contains('''
 <ul>
-  <li class="dir"><span>📁lib</span>
+  <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;lib
     <ul>
-      <li class="dir"><span>📁src</span>
+      <li class="dir"><span class="arrow">&#x25BC;</span>&#x1F4C1;src
         <ul>
-          <li><a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
+          <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
         </ul>
       </li>
     </ul>
@@ -132,7 +133,7 @@
     renderedView = _stripAttributes(renderedView);
     expect(renderedView, contains('''
 <ul>
-  <li><a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
+  <li>&#x1F4C4;<a href="..." class="nav-link" data-name="...">a.dart</a> (1 modification)</li>
 </ul>'''));
   }
 
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
index c3e2add..6307ba8 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/nnbd_migration_test_base.dart
@@ -24,15 +24,16 @@
   /// Uses the InfoBuilder to build information for [testFile].
   ///
   /// The information is stored in [infos].
-  Future<void> buildInfo() async {
+  Future<void> buildInfo({bool removeViaComments = true}) async {
     var includedRoot = resourceProvider.pathContext.dirname(testFile);
-    await _buildMigrationInfo([testFile], includedRoot: includedRoot);
+    await _buildMigrationInfo([testFile],
+        includedRoot: includedRoot, removeViaComments: removeViaComments);
   }
 
   /// Uses the InfoBuilder to build information for files at [testPaths], which
   /// should all share a common parent directory, [includedRoot].
   Future<void> _buildMigrationInfo(List<String> testPaths,
-      {String includedRoot}) async {
+      {String includedRoot, bool removeViaComments = true}) async {
     // Compute the analysis results.
     server.setAnalysisRoots('0', [includedRoot], [], {});
     // Run the migration engine.
@@ -41,7 +42,8 @@
     NullabilityMigration migration = NullabilityMigration(
         NullabilityMigrationAdapter(listener),
         permissive: false,
-        instrumentation: instrumentationListener);
+        instrumentation: instrumentationListener,
+        removeViaComments: removeViaComments);
     for (var testPath in testPaths) {
       var result = await server
           .getAnalysisDriver(testPath)
@@ -84,9 +86,9 @@
   /// Asserts that [originalContent] is migrated to [migratedContent]. Returns
   /// the singular UnitInfo which was built.
   Future<UnitInfo> buildInfoForSingleTestFile(String originalContent,
-      {@required String migratedContent}) async {
+      {@required String migratedContent, bool removeViaComments = true}) async {
     addTestFile(originalContent);
-    await buildInfo();
+    await buildInfo(removeViaComments: removeViaComments);
     // Ignore info for dart:core.
     var filteredInfos = [
       for (var info in infos) if (info.path.indexOf('core.dart') == -1) info
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
index 60e7444..093578e 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/region_renderer_test.dart
@@ -2,6 +2,8 @@
 // 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:convert' show jsonDecode;
+
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/region_renderer.dart';
@@ -34,54 +36,60 @@
   test_modifiedOutput_containsDetail() async {
     await buildInfoForSingleTestFile('int a = null;',
         migratedContent: 'int? a = null;');
-    var output = renderRegion(3);
-    expect(
-        output,
-        contains("<ul><li>This variable is initialized to an explicit 'null' "
-            '(<a href="test.dart?offset=8&line=1" class="nav-link">'
-            'test.dart</a>)</li></ul>'));
+    var response = jsonDecode(renderRegion(3));
+    expect(response['details'], hasLength(1));
+    var detail = response['details'].single;
+    expect(detail['description'],
+        equals("This variable is initialized to an explicit 'null'"));
+    expect(detail['link']['text'], equals('test.dart'));
+    expect(detail['link']['href'], equals('test.dart?offset=8&line=1'));
   }
 
   test_modifiedOutput_containsExplanation() async {
     await buildInfoForSingleTestFile('int a = null;',
         migratedContent: 'int? a = null;');
-    var output = renderRegion(3);
-    expect(output, contains("<p>Changed type 'int' to be nullable.</p>"));
+    var response = jsonDecode(renderRegion(3));
+    expect(
+        response['explanation'], equals("Changed type 'int' to be nullable"));
   }
 
   test_modifiedOutput_containsPath() async {
     await buildInfoForSingleTestFile('int a = null;',
         migratedContent: 'int? a = null;');
-    var output = renderRegion(3);
-    expect(output, contains('<p class="region-location">/project/bin</p>'));
+    var response = jsonDecode(renderRegion(3));
+    expect(response['path'], equals(convertPath('/project/bin/test.dart')));
+    expect(response['line'], equals(1));
   }
 
   test_unmodifiedOutput_containsDetail() async {
     await buildInfoForSingleTestFile('f(int a) => a.isEven;',
         migratedContent: 'f(int a) => a.isEven;');
-    var output = renderRegion(2);
+    var response = jsonDecode(renderRegion(2));
+    expect(response['details'], hasLength(1));
+    var detail = response['details'].single;
     expect(
-        output,
-        contains('<ul><li>This value is unconditionally used in a '
-            'non-nullable context '
-            '(<a href="test.dart?offset=12&line=1" class="nav-link">test.dart'
-            '</a>)</li></ul>'));
+        detail['description'],
+        equals('This value is unconditionally used in a '
+            'non-nullable context'));
+    expect(detail['link']['text'], equals('test.dart'));
+    expect(detail['link']['href'], equals('test.dart?offset=12&line=1'));
   }
 
   test_unmodifiedOutput_containsExplanation() async {
     await buildInfoForSingleTestFile('f(int a) => a.isEven;',
         migratedContent: 'f(int a) => a.isEven;');
-    var output = renderRegion(2);
+    var response = jsonDecode(renderRegion(2));
     expect(
-        output,
-        contains('<p>This type is not changed; it is determined to '
-            'be non-nullable</p>'));
+        response['explanation'],
+        equals(
+            'This type is not changed; it is determined to be non-nullable'));
   }
 
   test_unmodifiedOutput_containsPath() async {
     await buildInfoForSingleTestFile('f(int a) => a.isEven;',
         migratedContent: 'f(int a) => a.isEven;');
-    var output = renderRegion(2);
-    expect(output, contains('<p class="region-location">/project/bin</p>'));
+    var response = jsonDecode(renderRegion(2));
+    expect(response['path'], equals(convertPath('/project/bin/test.dart')));
+    expect(response['line'], equals(1));
   }
 }
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
index eba2221..5f5105b 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/unit_renderer_test.dart
@@ -36,6 +36,71 @@
     return contents;
   }
 
+  test_editList_containsEdit() async {
+    await buildInfoForSingleTestFile('int a = null;',
+        migratedContent: 'int? a = null;');
+    var outputJson = renderUnits()[0];
+    var output = jsonDecode(outputJson);
+    var editList = output['editList'];
+    expect(
+        editList,
+        contains('<p class="edit">'
+            '<input type="checkbox" title="Click to mark reviewed" '
+            'disabled="disabled">'
+            " line 1: Changed type 'int' to be nullable.</p>"));
+  }
+
+  test_editList_containsEdit_htmlEscaped() async {
+    await buildInfoForSingleTestFile('List<String> a = null;',
+        migratedContent: 'List<String>? a = null;');
+    var outputJson = renderUnits()[0];
+    var output = jsonDecode(outputJson);
+    var editList = output['editList'];
+    expect(editList,
+        contains("line 1: Changed type 'List&lt;String&gt;' to be nullable."));
+  }
+
+  test_editList_containsEdit_twoEdits() async {
+    await buildInfoForSingleTestFile('''
+int a = null;
+bool b = a.isEven;
+''', migratedContent: '''
+int? a = null;
+bool b = a!.isEven;
+''');
+    var outputJson = renderUnits()[0];
+    var output = jsonDecode(outputJson);
+    var editList = output['editList'];
+    expect(editList, contains("line 1: Changed type 'int' to be nullable."));
+    expect(editList,
+        contains('line 2: Added a non-null assertion to nullable expression.'));
+  }
+
+  test_editList_containsSummary() async {
+    await buildInfoForSingleTestFile('int a = null;',
+        migratedContent: 'int? a = null;');
+    var outputJson = renderUnits()[0];
+    var output = jsonDecode(outputJson);
+    var editList = output['editList'];
+    expect(editList,
+        contains('<p><strong>1</strong> edit was made to this file.'));
+  }
+
+  test_editList_containsSummary_twoEdits() async {
+    await buildInfoForSingleTestFile('''
+int a = null;
+bool b = a.isEven;
+''', migratedContent: '''
+int? a = null;
+bool b = a!.isEven;
+''');
+    var outputJson = renderUnits()[0];
+    var output = jsonDecode(outputJson);
+    var editList = output['editList'];
+    expect(editList,
+        contains('<p><strong>2</strong> edits were made to this file.'));
+  }
+
   test_navContentContainsEscapedHtml() async {
     await buildInfoForSingleTestFile('List<String> a = null;',
         migratedContent: 'List<String>? a = null;');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
index aee1f1c..f48d85d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_await_test.dart
@@ -35,7 +35,7 @@
 Future doSomething() => new Future();
 
 void main() async {
-  await doSomething()/*LINT*/;
+  await doSomething();
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart
index 8ed3a7f..8a8ca02 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_const_test.dart
@@ -37,7 +37,7 @@
   const C();
 }
 main() {
-  var c = const C/*LINT*/();
+  var c = const C();
 }
 ''');
   }
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
index f64eff8..d737fee 100644
--- 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
@@ -40,7 +40,7 @@
 class Absorber extends Widget {
   bool get absorbing => _absorbing;
   bool _absorbing;
-  bool /*LINT*/ignoringSemantics;
+  bool ignoringSemantics;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -62,7 +62,7 @@
 ''');
     await assertHasFix('''
 class Absorber extends Widget {
-  bool /*LINT*/ignoringSemantics;
+  bool ignoringSemantics;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
@@ -82,7 +82,7 @@
 ''');
     await assertHasFix('''
 class Absorber extends Widget {
-  bool /*LINT*/ignoringSemantics;
+  bool ignoringSemantics;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder props) {
     props.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
@@ -104,7 +104,7 @@
 ''');
     await assertHasFix('''
 class Absorber extends Widget {
-  bool get /*LINT*/absorbing => _absorbing;
+  bool get absorbing => _absorbing;
   bool _absorbing;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
@@ -130,7 +130,7 @@
     await assertHasFix('''
 import 'package:flutter/material.dart';
 class A extends Widget {
-  Color /*LINT*/field;
+  Color field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -152,7 +152,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  double /*LINT*/field;
+  double field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -174,7 +174,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  dynamic /*LINT*/field;
+  dynamic field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -198,7 +198,7 @@
     await assertHasFix('''
 enum Foo {bar}
 class A extends Widget {
-  Foo /*LINT*/field;
+  Foo field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -229,7 +229,7 @@
 typedef ValueChanged<T> = void Function(T value);
 
 class A extends Widget {
-  ValueChanged<double> /*LINT*/onChanged;
+  ValueChanged<double> onChanged;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -251,7 +251,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  int /*LINT*/field;
+  int field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -273,7 +273,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  Iterable<String> /*LINT*/field;
+  Iterable<String> field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -295,7 +295,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  List<List<String>> /*LINT*/field;
+  List<List<String>> field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -320,7 +320,7 @@
     await assertHasFix('''
 import 'package:vector_math/vector_math_64.dart';
 class A extends Widget {
-  Matrix4 /*LINT*/field;
+  Matrix4 field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -342,7 +342,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  Object /*LINT*/field;
+  Object field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -364,7 +364,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  String /*LINT*/field;
+  String field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -382,7 +382,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  String /*LINT*/field;
+  String field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
@@ -405,7 +405,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  ClassNotInScope<bool> /*LINT*/onChanged;
+  ClassNotInScope<bool> onChanged;
 
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
@@ -429,7 +429,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  ClassNotInScope<bool> get /*LINT*/onChanged => null;
+  ClassNotInScope<bool> get onChanged => null;
 
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
@@ -452,7 +452,7 @@
 ''');
     await assertHasFix('''
 class A extends Widget {
-  var /*LINT*/field;
+  var field;
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
index 229c280..69c6aeb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
@@ -38,7 +38,7 @@
 }
 class Sub extends Test {
   @override
-  int /*LINT*/t = 42;
+  int t = 42;
 }
 ''');
   }
@@ -58,7 +58,7 @@
 }
 class Sub extends Test {
   @override
-  int get /*LINT*/t => null;
+  int get t => null;
 }
 ''');
   }
@@ -78,7 +78,7 @@
 }
 class Sub extends Test {
   @override
-  void /*LINT*/t() { }
+  void t() { }
 }
 ''');
   }
@@ -100,7 +100,7 @@
 class Sub extends Test {
   /// Doc comment.
   @override
-  void /*LINT*/t() { }
+  void t() { }
 }
 ''');
   }
@@ -126,7 +126,7 @@
    * Doc comment.
    */
   @override
-  void /*LINT*/t() { }
+  void t() { }
 }
 ''');
   }
@@ -150,7 +150,7 @@
   /// Doc comment.
   @override
   @foo
-  void /*LINT*/t() { }
+  void t() { }
 }
 ''');
   }
@@ -172,7 +172,7 @@
 class Sub extends Test {
   // Non-doc comment.
   @override
-  void /*LINT*/t() { }
+  void t() { }
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
index 5698974..79a452c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
@@ -30,7 +30,7 @@
 }
 ''');
     await assertHasFix('''
-void function({@required String /*LINT*/param}) {
+void function({@required String param}) {
   assert(param != null);
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
index 8d33663..d7540ca 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
@@ -36,7 +36,7 @@
     await assertHasFix('''
 class A {
   void m() {
-    /*LINT*/String f() {
+    String f() {
       return '';
     }
   }
@@ -55,7 +55,7 @@
     await assertHasFix('''
 class A {
   void m() {
-    /*LINT*/String f() => '';
+    String f() => '';
   }
 }
 ''');
@@ -92,7 +92,7 @@
 ''');
     await assertHasFix('''
 class A {
-  /*LINT*/void m() {
+  void m() {
     return;
   }
 }
@@ -109,7 +109,7 @@
 ''');
     await assertHasFix('''
 class A {
-  /*LINT*/String m() {
+  String m() {
     return '';
   }
 }
@@ -124,7 +124,7 @@
 ''');
     await assertHasFix('''
 class A {
-  /*LINT*/String m() => '';
+  String m() => '';
 }
 ''');
   }
@@ -136,7 +136,7 @@
 }
 ''');
     await assertHasFix('''
-/*LINT*/String f() {
+String f() {
   return '';
 }
 ''');
@@ -147,7 +147,7 @@
 /*LINT*/f() => '';
 ''');
     await assertHasFix('''
-/*LINT*/String f() => '';
+String f() => '';
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
index e54b689..21b86e4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
@@ -33,7 +33,7 @@
 ''');
     await assertHasFix('''
 class A {
-  /*LINT*/final int f = 0;
+  final int f = 0;
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart
index 8acb794..0d75e37 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_documentation_into_line_test.dart
@@ -23,7 +23,7 @@
   @override
   String get lintCode => LintNames.slash_for_doc_comments;
 
-  // More coverage in the `convert_to_documentation_line_test.dart` assist test.
+  /// More coverage in the `convert_to_documentation_line_test.dart` assist test.
   test_onText() async {
     await resolveTestUnit('''
 class A {
@@ -37,7 +37,7 @@
 ''');
     await assertHasFix('''
 class A {
-  /// /*LINT*/AAAAAAA [int] AAAAAAA
+  /// AAAAAAA [int] AAAAAAA
   /// BBBBBBBB BBBB BBBB
   /// CCC [A] CCCCCCCCCCC
   mmm() {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart
index d2a6bd9..450db7e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_for_element_test.dart
@@ -23,7 +23,7 @@
   @override
   String get lintCode => LintNames.prefer_for_elements_to_map_fromIterable;
 
-  // More coverage in the `convert_to_for_element_line_test.dart` assist test.
+  /// More coverage in the `convert_to_for_element_line_test.dart` assist test.
   test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
     await resolveTestUnit('''
 f(Iterable<int> i) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart
index 8c615c2..4ce86e6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_generic_function_syntax_test.dart
@@ -45,7 +45,7 @@
 typedef /*LINT*/F<P, R>(P x);
 ''');
     await assertHasFix('''
-typedef /*LINT*/F<P, R> = Function(P x);
+typedef F<P, R> = Function(P x);
 ''');
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
index d689679..50e4277 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 void f(String s) {
-  print(/*LINT*/s ?? 'default');
+  print(s ?? 'default');
 }
 ''');
   }
@@ -44,7 +44,7 @@
 ''');
     await assertHasFix('''
 void f(String s) {
-  print(/*LINT*/s ?? 'default');
+  print(s ?? 'default');
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart
index 8c75087..09a819e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_int_literal_test.dart
@@ -29,7 +29,7 @@
 const double myDouble = /*LINT*/42.0;
 ''');
     await assertHasFix('''
-const double myDouble = /*LINT*/42;
+const double myDouble = 42;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart
index a0ff333..26164f4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_list_literal_test.dart
@@ -28,7 +28,7 @@
 List l = /*LINT*/List();
 ''');
     await assertHasFix('''
-List l = /*LINT*/[];
+List l = [];
 ''');
   }
 
@@ -37,7 +37,7 @@
 var l = /*LINT*/List();
 ''');
     await assertHasFix('''
-var l = /*LINT*/[];
+var l = [];
 ''');
   }
 
@@ -46,7 +46,7 @@
 var l = /*LINT*/new List();
 ''');
     await assertHasFix('''
-var l = /*LINT*/[];
+var l = [];
 ''');
   }
 
@@ -62,7 +62,7 @@
 var l = /*LINT*/List<int>();
 ''');
     await assertHasFix('''
-var l = /*LINT*/<int>[];
+var l = <int>[];
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart
index f0f3a46..be18574 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_map_literal_test.dart
@@ -28,7 +28,7 @@
 Map m = /*LINT*/Map();
 ''');
     await assertHasFix('''
-Map m = /*LINT*/{};
+Map m = {};
 ''');
   }
 
@@ -39,7 +39,7 @@
 ''');
     await assertHasFix('''
 import 'dart:collection';
-var m = /*LINT*/{};
+var m = {};
 ''');
   }
 
@@ -48,7 +48,7 @@
 var m = /*LINT*/Map();
 ''');
     await assertHasFix('''
-var m = /*LINT*/{};
+var m = {};
 ''');
   }
 
@@ -57,7 +57,7 @@
 var m = /*LINT*/new Map();
 ''');
     await assertHasFix('''
-var m = /*LINT*/{};
+var m = {};
 ''');
   }
 
@@ -66,7 +66,7 @@
 var m = /*LINT*/Map<String, int>();
 ''');
     await assertHasFix('''
-var m = /*LINT*/<String, int>{};
+var m = <String, int>{};
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
index dfa4706..981d0e8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
@@ -32,7 +32,7 @@
 ''');
 
     await assertHasFix('''
-import /*LINT*/'package:test/lib/foo.dart';
+import 'package:test/lib/foo.dart';
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
index bfe46a0..26a0b78 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
@@ -31,31 +31,30 @@
 ''');
 
     await assertHasFix('''
-import /*LINT*/'../foo.dart';
+import '../foo.dart';
 ''');
   }
 
-  test_relativeImportSameDirectory() async {
+  test_relativeImportDifferentPackages() async {
+    // Validate we don't get a fix with imports referencing different packages.
+    addSource('/home/test1/lib/foo.dart', '');
+    testFile = convertPath('/home/test2/lib/bar.dart');
+    await resolveTestUnit('''
+import /*LINT*/'package:test1/foo.dart';
+''');
+
+    await assertNoFix();
+  }
+
+  test_relativeImportGarbledUri() async {
     addSource('/home/test/lib/foo.dart', '');
     testFile = convertPath('/home/test/lib/bar.dart');
     await resolveTestUnit('''
-import /*LINT*/'package:test/foo.dart';
+import /*LINT*/'package:test/foo';
 ''');
 
     await assertHasFix('''
-import /*LINT*/'foo.dart';
-''');
-  }
-
-  test_relativeImportSubDirectory() async {
-    addSource('/home/test/lib/baz/foo.dart', '');
-    testFile = convertPath('/home/test/lib/test.dart');
-    await resolveTestUnit('''
-import /*LINT*/'package:test/baz/foo.dart';
-''');
-
-    await assertHasFix('''
-import /*LINT*/'baz/foo.dart';
+import 'foo';
 ''');
   }
 
@@ -67,30 +66,31 @@
 ''');
 
     await assertHasFix('''
-import /*LINT*/"foo.dart";
+import "foo.dart";
 ''');
   }
 
-  test_relativeImportGarbledUri() async {
+  test_relativeImportSameDirectory() async {
     addSource('/home/test/lib/foo.dart', '');
     testFile = convertPath('/home/test/lib/bar.dart');
     await resolveTestUnit('''
-import /*LINT*/'package:test/foo';
+import /*LINT*/'package:test/foo.dart';
 ''');
 
     await assertHasFix('''
-import /*LINT*/'foo';
+import 'foo.dart';
 ''');
   }
 
-  // Validate we don't get a fix with imports referencing different packages.
-  test_relativeImportDifferentPackages() async {
-    addSource('/home/test1/lib/foo.dart', '');
-    testFile = convertPath('/home/test2/lib/bar.dart');
+  test_relativeImportSubDirectory() async {
+    addSource('/home/test/lib/baz/foo.dart', '');
+    testFile = convertPath('/home/test/lib/test.dart');
     await resolveTestUnit('''
-import /*LINT*/'package:test1/foo.dart';
+import /*LINT*/'package:test/baz/foo.dart';
 ''');
 
-    await assertNoFix();
+    await assertHasFix('''
+import 'baz/foo.dart';
+''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
index dd47239..9fdd206 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_set_literal_test.dart
@@ -28,7 +28,7 @@
 Set s = /*LINT*/Set();
 ''');
     await assertHasFix('''
-Set s = /*LINT*/{};
+Set s = {};
 ''');
   }
 
@@ -37,7 +37,7 @@
 var s = /*LINT*/Set();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<dynamic>{};
+var s = <dynamic>{};
 ''');
   }
 
@@ -46,7 +46,7 @@
 var s = /*LINT*/new Set();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<dynamic>{};
+var s = <dynamic>{};
 ''');
   }
 
@@ -55,7 +55,7 @@
 var s = /*LINT*/Set<int>();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{};
+var s = <int>{};
 ''');
   }
 
@@ -70,7 +70,7 @@
     await assertHasFix('''
 import 'dart:collection';
 
-var s = /*LINT*/<int>{};
+var s = <int>{};
 ''');
   }
 
@@ -79,7 +79,7 @@
 var s = /*LINT*/Set.from([]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/<dynamic>{};
+var s = <dynamic>{};
 ''');
   }
 
@@ -93,7 +93,7 @@
 ''');
     await assertHasFix('''
 void f(Set<int> s) {}
-var s = f(/*LINT*/{});
+var s = f({});
 ''');
   }
 
@@ -102,7 +102,7 @@
 var s = /*LINT*/new Set.from([2, 3]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/{2, 3};
+var s = {2, 3};
 ''');
   }
 
@@ -111,7 +111,7 @@
 Set s = /*LINT*/Set.from([2, 3]);
 ''');
     await assertHasFix('''
-Set s = /*LINT*/{2, 3};
+Set s = {2, 3};
 ''');
   }
 
@@ -120,7 +120,7 @@
 var s = /*LINT*/Set<int>.from([2, 3]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{2, 3};
+var s = <int>{2, 3};
 ''');
   }
 
@@ -129,7 +129,7 @@
 var s = /*LINT*/Set<int>.from(<num>[2, 3]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{2, 3};
+var s = <int>{2, 3};
 ''');
   }
 
@@ -138,7 +138,7 @@
 var s = /*LINT*/Set.from(<int>[2, 3]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{2, 3};
+var s = <int>{2, 3};
 ''');
   }
 
@@ -147,7 +147,7 @@
 var s = /*LINT*/Set.from([2, 3]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/{2, 3};
+var s = {2, 3};
 ''');
   }
 
@@ -164,7 +164,7 @@
 var s = /*LINT*/Set.from([2, 3,]);
 ''');
     await assertHasFix('''
-var s = /*LINT*/{2, 3,};
+var s = {2, 3,};
 ''');
   }
 
@@ -173,7 +173,7 @@
 var s = /*LINT*/[].toSet();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<dynamic>{};
+var s = <dynamic>{};
 ''');
   }
 
@@ -182,7 +182,7 @@
 var s = /*LINT*/<int>[].toSet();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{};
+var s = <int>{};
 ''');
   }
 
@@ -191,7 +191,7 @@
 var s = /*LINT*/[2, 3].toSet();
 ''');
     await assertHasFix('''
-var s = /*LINT*/{2, 3};
+var s = {2, 3};
 ''');
   }
 
@@ -200,7 +200,7 @@
 var s = /*LINT*/<int>[2, 3].toSet();
 ''');
     await assertHasFix('''
-var s = /*LINT*/<int>{2, 3};
+var s = <int>{2, 3};
 ''');
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
index 97e2746..610b82d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_single_quoted_string_test.dart
@@ -32,7 +32,7 @@
 ''');
     await assertHasFix('''
 main() {
-  print(/*LINT*/'abc');
+  print('abc');
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart
index 035720c..c7e8f40 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_where_type_test.dart
@@ -32,7 +32,7 @@
 ''');
     await assertHasFix('''
 Iterable<C> f(List<Object> list) {
-  return list./*LINT*/whereType<C>();
+  return list.whereType<C>();
 }
 class C {}
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
index 6b98754..e6800eb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
@@ -37,7 +37,7 @@
     await assertHasFix('''
 class C {
   @override
-  int get /*LINT*/hashCode => 13;
+  int get hashCode => 13;
 
   @override
   bool operator ==(Object other) {
@@ -58,7 +58,7 @@
     await assertHasFix('''
 class C {
   @override
-  bool operator /*LINT*/==(Object other) => false;
+  bool operator ==(Object other) => false;
 
   @override
   // TODO: implement hashCode
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index 3721622..4f1daf2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -24,9 +24,26 @@
 /// A base class defining support for writing fix processor tests that are
 /// specific to fixes associated with lints that use the FixKind.
 abstract class FixProcessorLintTest extends FixProcessorTest {
+  /// The marker used to indicate where the lint is expected to be found.
+  static const lintMarker = '/*LINT*/';
+
+  /// The offset of the lint marker in the code being analyzed.
+  int lintOffset = -1;
+
   /// Return the lint code being tested.
   String get lintCode;
 
+  @override
+  Future<void> resolveTestUnit(String code) async {
+    lintOffset = code.indexOf(lintMarker);
+    if (lintOffset < 0) {
+      fail("Missing '$lintMarker' marker");
+    }
+    var endOffset = lintOffset + lintMarker.length;
+    code = code.substring(0, lintOffset) + code.substring(endOffset);
+    return super.resolveTestUnit(code);
+  }
+
   /// Find the error that is to be fixed by computing the errors in the file,
   /// using the [errorFilter] to filter out errors that should be ignored, and
   /// expecting that there is a single remaining error. The error filter should
@@ -35,12 +52,8 @@
   Future<AnalysisError> _findErrorToFix(
       bool Function(AnalysisError) errorFilter,
       {int length}) async {
-    int index = testCode.indexOf('/*LINT*/');
-    if (index < 0) {
-      fail('Missing "/*LINT*/" marker');
-    }
-    return AnalysisError(testSource, index + '/*LINT*/'.length, length ?? 0,
-        LintCode(lintCode, '<ignored>'));
+    return AnalysisError(
+        testSource, lintOffset, length ?? 0, LintCode(lintCode, '<ignored>'));
   }
 }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
index 1336479..1831cff 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 class C {
-  final int /*LINT*/f = 2;
+  final int f = 2;
 }
 ''');
   }
@@ -44,7 +44,7 @@
 ''');
     await assertHasFix('''
 class C {
-  final /*LINT*/f = 2;
+  final f = 2;
 }
 ''');
   }
@@ -57,7 +57,7 @@
 ''');
     await assertHasFix('''
 bad() {
-  final int /*LINT*/x = 2;
+  final int x = 2;
 }
 ''');
   }
@@ -70,7 +70,7 @@
 ''');
     await assertHasFix('''
 bad() {
-  final /*LINT*/x = 2;
+  final x = 2;
 }
 ''');
   }
@@ -83,7 +83,7 @@
 ''');
     await assertHasFix('''
 class C {
-  /*LINT*/final f = 2;
+  final f = 2;
 }
 ''');
   }
@@ -93,7 +93,7 @@
 int /*LINT*/x = 2;
 ''');
     await assertHasFix('''
-final int /*LINT*/x = 2;
+final int x = 2;
 ''');
   }
 
@@ -102,7 +102,7 @@
 var /*LINT*/x = 2;
 ''');
     await assertHasFix('''
-final /*LINT*/x = 2;
+final x = 2;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
index d275386..dcb6d79 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 bad() async {
-  print(/*LINT*/23);
+  print(23);
 }
 ''');
   }
@@ -44,7 +44,7 @@
 ''');
     await assertHasFix('''
 bad() async {
-  print(/*LINT*/'hola');
+  print('hola');
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
index 74e9b9f..e225dda 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
@@ -34,7 +34,6 @@
     await assertHasFix('''
 void foo() {
   while(true) {
-    /*LINT*/
   }
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart
index 0fd0c22..f6559c8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart
@@ -30,7 +30,7 @@
 ''');
     await assertHasFix('''
 var a = '';
-var b = /*LINT*/a;
+var b = a;
 ''');
   }
 
@@ -41,7 +41,7 @@
 ''');
     await assertHasFix('''
 var a = '';
-var b = /*LINT*/a;
+var b = a;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
index ff50588..b2bed15 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 class Test {
-  int /*LINT*/x;
+  int x;
 }
 ''');
   }
@@ -45,7 +45,7 @@
 ''');
     await assertHasFix('''
 void f() {
-  for (var /*LINT*/i; i != null; i++) {
+  for (var i; i != null; i++) {
   }
 }
 ''');
@@ -56,7 +56,7 @@
 String a = 'a', /*LINT*/b = null, c = 'c';
 ''');
     await assertHasFix('''
-String a = 'a', /*LINT*/b, c = 'c';
+String a = 'a', b, c = 'c';
 ''');
   }
 
@@ -65,7 +65,7 @@
 void f({String /*LINT*/s = null}) {}
 ''');
     await assertHasFix('''
-void f({String /*LINT*/s}) {}
+void f({String s}) {}
 ''');
   }
 
@@ -74,7 +74,7 @@
 void f([String /*LINT*/s = null]) {}
 ''');
     await assertHasFix('''
-void f([String /*LINT*/s]) {}
+void f([String s]) {}
 ''');
   }
 
@@ -83,7 +83,7 @@
 var /*LINT*/x = null;
 ''');
     await assertHasFix('''
-var /*LINT*/x;
+var x;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
index 4dfe93a..876d066 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
@@ -33,7 +33,7 @@
     await assertHasFix(r'''
 main() {
   var v = 42;
-  print('v: /*LINT*/$v');
+  print('v: $v');
 }
 ''', length: 4);
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart
index acdd317..aef5f95 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_operator_test.dart
@@ -28,7 +28,7 @@
 var s = 'a' /*LINT*/+ 'b';
 ''');
     await assertHasFix('''
-var s = 'a' /*LINT*/'b';
+var s = 'a' 'b';
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
index d716e6a..bcb188a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
@@ -33,7 +33,7 @@
     await assertHasFix('''
 class A {
   int x;
-  A(int x) : /*LINT*/x = x;
+  A(int x) : x = x;
 }
 ''');
   }
@@ -49,7 +49,7 @@
     await assertHasFix('''
 class A {
   void foo() {
-    /*LINT*/foo();
+    foo();
   }
 }
 ''');
@@ -66,7 +66,7 @@
     await assertHasFix('''
 class A {
   void foo() {
-    /*LINT*/foo();
+    foo();
   }
 }
 ''');
@@ -94,7 +94,7 @@
 class A {
   int x;
   void foo() {
-    /*LINT*/x = 2;
+    x = 2;
   }
 }
 ''');
@@ -113,7 +113,7 @@
 class A {
   int x;
   void foo() {
-    /*LINT*/x = 2;
+    x = 2;
   }
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
index 5517927..7e0b234 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
@@ -30,7 +30,7 @@
 }
 ''');
     await assertHasFix('''
-bad(void foo(/*LINT*/x)) {
+bad(void foo(x)) {
   return null;
 }
 ''');
@@ -43,7 +43,7 @@
 }
 ''');
     await assertHasFix('''
-bad({/*LINT*/defaultValue}) {
+bad({defaultValue}) {
   return null;
 }
 ''');
@@ -56,7 +56,7 @@
 }
 ''');
     await assertHasFix('''
-bad(/*LINT*/defaultValue) {
+bad(defaultValue) {
   return null;
 }
 ''');
@@ -69,7 +69,7 @@
 }
 ''');
     await assertHasFix('''
-bad([/*LINT*/defaultValue]) {
+bad([defaultValue]) {
   return null;
 }
 ''');
@@ -86,7 +86,7 @@
 /*LINT*/void set speed2(int ms) {}
 ''');
     await assertHasFix('''
-/*LINT*/set speed2(int ms) {}
+set speed2(int ms) {}
 ''');
   }
 }
@@ -103,7 +103,7 @@
 };
 ''');
     await assertHasFix('''
-var x = ({/*LINT*/defaultValue}) {
+var x = ({defaultValue}) {
   return null;
 };
 ''');
@@ -116,7 +116,7 @@
 };
 ''');
     await assertHasFix('''
-var x = (/*LINT*/defaultValue) {
+var x = (defaultValue) {
   return null;
 };
 ''');
@@ -129,7 +129,7 @@
 };
 ''');
     await assertHasFix('''
-var x = ([/*LINT*/defaultValue]) {
+var x = ([defaultValue]) {
   return null;
 };
 ''');
@@ -137,6 +137,12 @@
 }
 
 @reflectiveTest
+abstract class RemoveTypeAnnotationTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_TYPE_ANNOTATION;
+}
+
+@reflectiveTest
 class TypeInitFormalsTest extends RemoveTypeAnnotationTest {
   @override
   String get lintCode => LintNames.type_init_formals;
@@ -151,14 +157,8 @@
     await assertHasFix('''
 class C {
   int f;
-  C(/*LINT*/this.f);
+  C(this.f);
 }
 ''');
   }
 }
-
-@reflectiveTest
-abstract class RemoveTypeAnnotationTest extends FixProcessorLintTest {
-  @override
-  FixKind get kind => DartFixKind.REMOVE_TYPE_ANNOTATION;
-}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart
index 7ee8802..f6d1bb9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_const_test.dart
@@ -33,7 +33,7 @@
     await assertHasFix('''
 class A { const A(); }
 m(){
-  const a = /*LINT*/A();
+  const a = A();
 }
 ''');
   }
@@ -43,7 +43,7 @@
 const list = /*LINT*/const List();
 ''');
     await assertHasFix('''
-const list = /*LINT*/List();
+const list = List();
 ''', length: 5);
   }
 
@@ -52,7 +52,7 @@
 const list = /*LINT*/const [];
 ''');
     await assertHasFix('''
-const list = /*LINT*/[];
+const list = [];
 ''', length: 5);
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart
index 2c6a001..69075a9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_new_test.dart
@@ -33,7 +33,7 @@
     await assertHasFix('''
 class A { A(); }
 m(){
-  final a = /*LINT*/A();
+  final a = A();
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
index 8afc1c4..9c8715a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
@@ -34,7 +34,7 @@
 ''');
     await assertHasFix('''
 main() {
-  int /*LINT*/myIntegerVariable = 42;
+  int myIntegerVariable = 42;
   int foo;
   print(myIntegerVariable);
   print(foo);
@@ -52,7 +52,7 @@
 ''');
     await assertHasFix('''
 main() {
-  [0, 1, 2].forEach((/*LINT*/myIntegerVariable) {
+  [0, 1, 2].forEach((myIntegerVariable) {
     print(myIntegerVariable);
   });
 }
@@ -66,7 +66,7 @@
 }
 ''');
     await assertHasFix('''
-main(int /*LINT*/myIntegerVariable) {
+main(int myIntegerVariable) {
   print(myIntegerVariable);
 }
 ''');
@@ -82,7 +82,7 @@
 ''');
     await assertHasFix('''
 class A {
-  main(int /*LINT*/myIntegerVariable) {
+  main(int myIntegerVariable) {
     print(myIntegerVariable);
   }
 }
@@ -105,7 +105,7 @@
 }
 ''');
     await assertHasFix('''
-main([int /*LINT*/myIntegerVariable]) {
+main([int myIntegerVariable]) {
   print(myIntegerVariable);
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
index 2bf65bf..01296a0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
@@ -32,7 +32,7 @@
     await assertHasFix('''
 void f1({int a}) { }    
 
-f1({a/*LINT*/ = 1}) => null;
+f1({a = 1}) => null;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
index 9c05196..48416db 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
@@ -28,7 +28,7 @@
 /*LINT*/final int a = 1;
 ''');
     await assertHasFix('''
-/*LINT*/const int a = 1;
+const int a = 1;
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart
index e59a3a0..ae07cfc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_new_with_const_test.dart
@@ -37,7 +37,7 @@
   const C();
 }
 main() {
-  var c = const C/*LINT*/();
+  var c = const C();
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart
index 1f733fe..f2c38c9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_null_with_closure_test.dart
@@ -23,49 +23,6 @@
   @override
   String get lintCode => LintNames.null_closures;
 
-  test_null_closure_named_expression() async {
-    await resolveTestUnit('''
-main() {
-  [1, 3, 5].firstWhere((e) => e.isOdd, orElse: /*LINT*/null);
-}
-''');
-    await assertHasFix('''
-main() {
-  [1, 3, 5].firstWhere((e) => e.isOdd, orElse: /*LINT*/() => null);
-}
-''');
-  }
-
-  test_null_closure_named_expression_with_args() async {
-    await resolveTestUnit('''
-void f({int closure(x, y)}) { }
-main() {
-  f(closure: /*LINT*/null);
-}
-''');
-    await assertHasFix('''
-void f({int closure(x, y)}) { }
-main() {
-  f(closure: /*LINT*/(x, y) => null);
-}
-''');
-  }
-
-  test_null_closure_named_expression_with_args_2() async {
-    await resolveTestUnit('''
-void f({int closure(x, y, {z})}) { }
-main() {
-  f(closure: /*LINT*/null);
-}
-''');
-    await assertHasFix('''
-void f({int closure(x, y, {z})}) { }
-main() {
-  f(closure: /*LINT*/(x, y, {z}) => null);
-}
-''');
-  }
-
   /// Currently failing since the LINT annotation is tagging the ArgumentList
   /// where the fix (and lint) expect a NullLiteral.
   /// todo (pq): re-write FixProcessorLintTest to run the actual lints.
@@ -80,7 +37,50 @@
     await assertHasFix('''
 void f(dynamic x) { }
 main() {
-  f(/*LINT*/() => null);
+  f(() => null);
+}
+''');
+  }
+
+  test_null_closure_named_expression() async {
+    await resolveTestUnit('''
+main() {
+  [1, 3, 5].firstWhere((e) => e.isOdd, orElse: /*LINT*/null);
+}
+''');
+    await assertHasFix('''
+main() {
+  [1, 3, 5].firstWhere((e) => e.isOdd, orElse: () => null);
+}
+''');
+  }
+
+  test_null_closure_named_expression_with_args() async {
+    await resolveTestUnit('''
+void f({int closure(x, y)}) { }
+main() {
+  f(closure: /*LINT*/null);
+}
+''');
+    await assertHasFix('''
+void f({int closure(x, y)}) { }
+main() {
+  f(closure: (x, y) => null);
+}
+''');
+  }
+
+  test_null_closure_named_expression_with_args_2() async {
+    await resolveTestUnit('''
+void f({int closure(x, y, {z})}) { }
+main() {
+  f(closure: /*LINT*/null);
+}
+''');
+    await assertHasFix('''
+void f({int closure(x, y, {z})}) { }
+main() {
+  f(closure: (x, y, {z}) => null);
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
index 32be5b7..cfca8d5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
@@ -41,7 +41,7 @@
   String _fullName;
   void foo() {
     print('hi');
-    /*LINT*/_fullName ??= getFullUserName(this);
+    _fullName ??= getFullUserName(this);
     print('hi');
   }
 }
@@ -63,7 +63,7 @@
 class Person {
   String _fullName;
   void foo() {
-    /*LINT*/_fullName ??= getFullUserName(this);
+    _fullName ??= getFullUserName(this);
   }
 }
 ''');
@@ -83,7 +83,7 @@
 class Person {
   String _fullName;
   void foo() {
-    /*LINT*/_fullName ??= getFullUserName(this);
+    _fullName ??= getFullUserName(this);
   }
 }
 ''');
@@ -104,7 +104,7 @@
 class Person {
   String _fullName;
   void foo() {
-    /*LINT*/_fullName ??= getFullUserName(this);
+    _fullName ??= getFullUserName(this);
   }
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
index 82152f7..a4cc442 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
@@ -28,7 +28,7 @@
 var functionWithFunction = (/*LINT*/int f(int x)) => f(0);
 ''');
     await assertHasFix('''
-var functionWithFunction = (/*LINT*/f) => f(0);
+var functionWithFunction = (f) => f(0);
 ''');
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
index 8548cc2..909b335 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
@@ -44,7 +44,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
@@ -57,7 +57,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
@@ -70,7 +70,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
@@ -83,7 +83,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
@@ -96,7 +96,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isEmpty) {}
+  if (c.isEmpty) {}
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
index 91c556e..2fda33b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isNotEmpty) {}
+  if (c.isNotEmpty) {}
 }
 ''');
   }
@@ -44,7 +44,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isNotEmpty) {}
+  if (c.isNotEmpty) {}
 }
 ''');
   }
@@ -57,7 +57,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isNotEmpty) {}
+  if (c.isNotEmpty) {}
 }
 ''');
   }
@@ -70,7 +70,7 @@
 ''');
     await assertHasFix('''
 f(List c) {
-  if (/*LINT*/c.isNotEmpty) {}
+  if (c.isNotEmpty) {}
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
index f246605..88cc858 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
@@ -30,7 +30,7 @@
 };
 ''');
     await assertHasFix('''
-final x = /*LINT*/print;
+final x = print;
 ''');
   }
 
@@ -46,7 +46,7 @@
     await assertHasFix('''
 void foo(){}
 Function finalVar() {
-  return /*LINT*/foo;
+  return foo;
 }
 ''');
   }
@@ -64,7 +64,7 @@
 void foo() {
   bool isPair(int a) => a % 2 == 0;
   final finalList = <int>[];
-  finalList.where(/*LINT*/isPair);
+  finalList.where(isPair);
 }
 ''');
   }
@@ -74,7 +74,7 @@
 var a = /*LINT*/(x) => finalList.remove(x);
 ''');
     await assertHasFix('''
-var a = /*LINT*/finalList.remove;
+var a = finalList.remove;
 ''');
   }
 
@@ -90,7 +90,7 @@
     await assertHasFix('''
 final Object a;
 Function finalVar() {
-  return /*LINT*/a.toString;
+  return a.toString;
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
index f034acd..a657b44 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_var_test.dart
@@ -33,7 +33,7 @@
 ''');
     await assertHasFix('''
 void f(List<int> list) {
-  for (/*LINT*/var i = 0; i < list.length; i++) {
+  for (var i = 0; i < list.length; i++) {
     print(i);
   }
 }
@@ -50,7 +50,7 @@
 ''');
     await assertHasFix('''
 void f(List<int> list) {
-  for (/*LINT*/var i in list) {
+  for (var i in list) {
     print(i);
   }
 }
@@ -67,7 +67,7 @@
 ''');
     await assertHasFix('''
 C<int> f() {
-  /*LINT*/var c = C<int>();
+  var c = C<int>();
   return c;
 }
 class C<T> {}
@@ -84,7 +84,7 @@
 ''');
     await assertHasFix('''
 C<int> f() {
-  /*LINT*/var c = C<int>();
+  var c = C<int>();
   return c;
 }
 class C<T> {}
@@ -100,7 +100,7 @@
 ''');
     await assertHasFix('''
 List f() {
-  /*LINT*/var l = <int>[];
+  var l = <int>[];
   return l;
 }
 ''');
@@ -115,7 +115,7 @@
 ''');
     await assertHasFix('''
 Map f() {
-  /*LINT*/var m = <String, int>{};
+  var m = <String, int>{};
   return m;
 }
 ''');
@@ -130,7 +130,7 @@
 ''');
     await assertHasFix('''
 Set f() {
-  /*LINT*/var s = <int>{};
+  var s = <int>{};
   return s;
 }
 ''');
@@ -155,7 +155,7 @@
 ''');
     await assertHasFix('''
 String f() {
-  /*LINT*/var s = '';
+  var s = '';
   return s;
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
index 9a7ca7c..d9e72c7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
@@ -44,7 +44,7 @@
 main() {
   Column(
     crossAxisAlignment: CrossAxisAlignment.center,
-    /*LINT*/children: <Widget>[
+    children: <Widget>[
       Text('aaa'),
       Text('bbbbbb'),
       Text('ccccccccc'),
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
index 1d3a8ca..b2e3bec 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
@@ -31,7 +31,7 @@
 ''');
     await assertHasFix('''
 f(c) {
-  if (/*LINT*/c.isNotEmpty) {}
+  if (c.isNotEmpty) {}
 }
 ''');
   }
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index cf88296..629549a 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -14,7 +14,6 @@
 import 'package:analysis_server/src/status/pages.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -23,41 +22,48 @@
 import 'metrics_util.dart';
 import 'visitors.dart';
 
+// TODO(jwren) have the analysis root and verbose option be configurable via a
+//  command line UX
 main() async {
-  var analysisRoots = [''];
-  await _computeCompletionMetrics(
-      PhysicalResourceProvider.INSTANCE, analysisRoots);
+  await CompletionMetricsComputer('', true).computeCompletionMetrics();
 }
 
-/// When enabled, expected, but missing completion tokens will be printed to
-/// stdout.
-const bool _doPrintMissingCompletions = true;
+/// This is the main metrics computer class for code completions. After the
+/// object is constructed, [computeCompletionMetrics] is executed to do analysis
+/// and print a summary of the metrics gathered from the completion tests.
+class CompletionMetricsComputer {
+  /// The analysis root path that this CompletionMetrics class will be computed.
+  final String _rootPath;
 
-/// TODO(jwren) put the following methods into a class
-Future _computeCompletionMetrics(
-    ResourceProvider resourceProvider, List<String> analysisRoots) async {
-  int includedCount = 0;
-  int notIncludedCount = 0;
-  Counter completionKindCounter = Counter('completion kind counter');
-  Counter completionElementKindCounter =
-      Counter('completion element kind counter');
+  /// When enabled, expected, but missing completion tokens will be printed to
+  /// stdout.
+  final bool _verbose;
 
-  for (var root in analysisRoots) {
-    print('Analyzing root: \"$root\"');
+  CompletionMetricsComputer(this._rootPath, this._verbose);
 
-    if (!io.Directory(root).existsSync()) {
+  Future computeCompletionMetrics() async {
+    int includedCount = 0;
+    int notIncludedCount = 0;
+    var completionKindCounter = Counter('completion kind counter');
+    var completionElementKindCounter =
+        Counter('completion element kind counter');
+    var mRRComputer = MeanReciprocalRankComputer();
+
+    print('Analyzing root: \"$_rootPath\"');
+
+    if (!io.Directory(_rootPath).existsSync()) {
       print('\tError: No such directory exists on this machine.\n');
-      continue;
+      return;
     }
 
     final collection = AnalysisContextCollection(
-      includedPaths: [root],
-      resourceProvider: resourceProvider,
+      includedPaths: [_rootPath],
+      resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
 
     for (var context in collection.contexts) {
-      var declarationsTracker =
-          DeclarationsTracker(MemoryByteStore(), resourceProvider);
+      var declarationsTracker = DeclarationsTracker(
+          MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
       declarationsTracker.addContext(context);
 
       while (declarationsTracker.hasWork) {
@@ -74,19 +80,26 @@
             resolvedUnitResult.unit.accept(visitor);
 
             for (var expectedCompletion in visitor.expectedCompletions) {
-              var suggestions = await computeCompletionSuggestions(
+              var suggestions = await _computeCompletionSuggestions(
                   resolvedUnitResult,
                   expectedCompletion.offset,
                   declarationsTracker);
 
-              var fraction =
+              var place =
                   _placementInSuggestionList(suggestions, expectedCompletion);
 
-              if (fraction.denominator != 0) {
+              mRRComputer.addReciprocalRank(place);
+
+              if (place.denominator != 0) {
                 includedCount++;
               } else {
                 notIncludedCount++;
-                if (_doPrintMissingCompletions) {
+
+                completionKindCounter.count(expectedCompletion.kind.toString());
+                completionElementKindCounter
+                    .count(expectedCompletion.elementKind.toString());
+
+                if (_verbose) {
                   // The format "/file/path/foo.dart:3:4" makes for easier input
                   // with the Files dialog in IntelliJ
                   print(
@@ -94,11 +107,6 @@
                   print(
                       '\tdid not include the expected completion: \"${expectedCompletion.completion}\", completion kind: ${expectedCompletion.kind.toString()}, element kind: ${expectedCompletion.elementKind.toString()}');
                   print('');
-
-                  completionKindCounter
-                      .count(expectedCompletion.kind.toString());
-                  completionElementKindCounter
-                      .count(expectedCompletion.elementKind.toString());
                 }
               }
             }
@@ -115,62 +123,77 @@
     final percentNotIncluded = 1 - percentIncluded;
 
     completionKindCounter.printCounterValues();
+    print('');
+
     completionElementKindCounter.printCounterValues();
-    print('Summary for $root:');
+    print('');
+
+    mRRComputer.printMean();
+    print('');
+
+    print('Summary for $_rootPath:');
     print('Total number of completion tests   = $totalCompletionCount');
     print(
         'Number of successful completions   = $includedCount (${printPercentage(percentIncluded)})');
     print(
         'Number of unsuccessful completions = $notIncludedCount (${printPercentage(percentNotIncluded)})');
-  }
-  includedCount = 0;
-  notIncludedCount = 0;
-  completionKindCounter.clear();
-  completionElementKindCounter.clear();
-}
 
-Place _placementInSuggestionList(List<CompletionSuggestion> suggestions,
-    ExpectedCompletion expectedCompletion) {
-  var placeCounter = 1;
-  for (var completionSuggestion in suggestions) {
-    if (expectedCompletion.matches(completionSuggestion)) {
-      return Place(placeCounter, suggestions.length);
+    includedCount = 0;
+    notIncludedCount = 0;
+    completionKindCounter.clear();
+    completionElementKindCounter.clear();
+    mRRComputer.clear();
+  }
+
+  Future<List<CompletionSuggestion>> _computeCompletionSuggestions(
+      ResolvedUnitResult resolvedUnitResult, int offset,
+      [DeclarationsTracker declarationsTracker]) async {
+    var completionRequestImpl = CompletionRequestImpl(
+      resolvedUnitResult,
+      offset,
+      CompletionPerformance(),
+    );
+
+    // This gets all of the suggestions with relevances.
+    var suggestions =
+        await DartCompletionManager().computeSuggestions(completionRequestImpl);
+
+    // If a non-null declarationsTracker was passed, use it to call
+    // computeIncludedSetList, this current implementation just adds the set of
+    // included element names with relevance 0, future implementations should
+    // compute out the relevance that clients will set to each value.
+    if (declarationsTracker != null) {
+      var includedSuggestionSets = <IncludedSuggestionSet>[];
+      var includedElementNames = <String>{};
+
+      computeIncludedSetList(declarationsTracker, resolvedUnitResult,
+          includedSuggestionSets, includedElementNames);
+
+      for (var eltName in includedElementNames) {
+        suggestions.add(CompletionSuggestion(
+            CompletionSuggestionKind.INVOCATION,
+            0,
+            eltName,
+            0,
+            eltName.length,
+            false,
+            false));
+      }
     }
-    placeCounter++;
+
+    suggestions.sort(completionComparator);
+    return suggestions;
   }
-  return Place.none();
-}
 
-Future<List<CompletionSuggestion>> computeCompletionSuggestions(
-    ResolvedUnitResult resolvedUnitResult, int offset,
-    [DeclarationsTracker declarationsTracker]) async {
-  var completionRequestImpl = CompletionRequestImpl(
-    resolvedUnitResult,
-    offset,
-    CompletionPerformance(),
-  );
-
-  // This gets all of the suggestions with relevances.
-  var suggestions =
-      await DartCompletionManager().computeSuggestions(completionRequestImpl);
-
-  // If a non-null declarationsTracker was passed, use it to call
-  // computeIncludedSetList, this current implementation just adds the set of
-  // included element names with relevance 0, future implementations should
-  // compute out the relevance that clients will set to each value.
-  if (declarationsTracker != null) {
-    var includedSuggestionSets = <IncludedSuggestionSet>[];
-    var includedElementNames = <String>{};
-
-    computeIncludedSetList(declarationsTracker, resolvedUnitResult,
-        includedSuggestionSets, includedElementNames);
-
-    for (var eltName in includedElementNames) {
-      suggestions.add(CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
-          0, eltName, 0, eltName.length, false, false));
+  Place _placementInSuggestionList(List<CompletionSuggestion> suggestions,
+      ExpectedCompletion expectedCompletion) {
+    var placeCounter = 1;
+    for (var completionSuggestion in suggestions) {
+      if (expectedCompletion.matches(completionSuggestion)) {
+        return Place(placeCounter, suggestions.length);
+      }
+      placeCounter++;
     }
+    return Place.none();
   }
-
-  suggestions.sort(completionComparator);
-  return suggestions;
 }
diff --git a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart b/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
index 95998e9..30450de 100644
--- a/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
+++ b/pkg/analysis_server/tool/completion_metrics/metrics_util.dart
@@ -19,10 +19,10 @@
 /// ```
 class Counter {
   final String name;
-  final Map<String, int> _buckets;
+  final Map<String, int> _buckets = {};
   int _totalCount = 0;
 
-  Counter(this.name) : _buckets = {};
+  Counter(this.name);
 
   /// Return a copy of all the current count data, this getter copies and
   /// returns the data to ensure that the data is only modified with the public
@@ -52,7 +52,37 @@
     print('Counts for \'$name\':');
     _buckets.forEach((id, count) =>
         print('[$id] $count (${printPercentage(count / _totalCount, 2)})'));
-    print('');
+  }
+}
+
+/// A computer for the mean reciprocal rank,
+/// https://en.wikipedia.org/wiki/Mean_reciprocal_rank.
+class MeanReciprocalRankComputer {
+  final List<double> _ranks = [];
+  MeanReciprocalRankComputer();
+
+  double get mean {
+    double sum = 0;
+    _ranks.forEach((rank) {
+      sum += rank;
+    });
+    return rankCount == 0 ? 0 : sum / rankCount;
+  }
+
+  int get rankCount => _ranks.length;
+
+  int get ranks => _ranks.length;
+
+  void addReciprocalRank(Place place) {
+    _ranks.add(place.reciprocalRank);
+  }
+
+  void clear() => _ranks.clear();
+
+  void printMean() {
+    var mrr = mean;
+    print('Mean Reciprocal Rank    = ${mrr.toStringAsFixed(5)}');
+    print('Harmonic Mean (inverse) = ${(1 / mrr).toStringAsFixed(1)}');
   }
 }
 
@@ -65,11 +95,11 @@
   /// The total number of possible places.
   final int _denominator;
 
-  Place(this._numerator, this._denominator) {
-    assert(_numerator > 0 && _denominator > 0);
-  }
+  const Place(this._numerator, this._denominator)
+      : assert(_numerator > 0),
+        assert(_denominator >= _numerator);
 
-  Place.none()
+  const Place.none()
       : _numerator = 0,
         _denominator = 0;
 
@@ -80,6 +110,8 @@
 
   int get numerator => _numerator;
 
+  double get reciprocalRank => denominator == 0 ? 0 : numerator / denominator;
+
   @override
   bool operator ==(dynamic other) =>
       other is Place &&
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index fa1bbf6..bfe7954 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -738,7 +738,7 @@
       if (type == null) {
         writeln('return ${className.hashCode};');
       } else {
-        writeln('int hash = 0;');
+        writeln('var hash = 0;');
         for (TypeObjectField field in type.fields) {
           String valueToCombine;
           if (field.value != null) {
@@ -916,7 +916,7 @@
     writeln('@override');
     writeln('Map<String, dynamic> toJson() {');
     indent(() {
-      writeln('Map<String, dynamic> result = {};');
+      writeln('var result = <String, dynamic>{};');
       for (TypeObjectField field in type.fields) {
         String fieldNameString = literalString(field.name);
         if (field.value != null) {
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index c125d20..14d09bf 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -208,7 +208,7 @@
     String domainName = getAncestor(html, 'domain', context).attributes['name'];
     checkName(html, 'notification', context);
     String event = html.attributes['event'];
-    context = '$context.${event != null ? event : 'event'}';
+    context = '$context.${event ?? 'event'}';
     checkAttributes(html, ['event'], context,
         optionalAttributes: ['experimental']);
     bool experimental = html.attributes['experimental'] == 'true';
@@ -363,7 +363,7 @@
   Refactoring refactoringFromHtml(dom.Element html) {
     checkName(html, 'refactoring');
     String kind = html.attributes['kind'];
-    String context = kind != null ? kind : 'refactoring';
+    String context = kind ?? 'refactoring';
     checkAttributes(html, ['kind'], context);
     TypeObject feedback;
     TypeObject options;
@@ -417,7 +417,7 @@
     String domainName = getAncestor(html, 'domain', context).attributes['name'];
     checkName(html, 'request', context);
     String method = html.attributes['method'];
-    context = '$context.${method != null ? method : 'method'}';
+    context = '$context.${method ?? 'method'}';
     checkAttributes(html, ['method'], context,
         optionalAttributes: ['experimental', 'deprecated']);
     bool experimental = html.attributes['experimental'] == 'true';
@@ -450,7 +450,7 @@
   TypeDefinition typeDefinitionFromHtml(dom.Element html) {
     checkName(html, 'type');
     String name = html.attributes['name'];
-    String context = name != null ? name : 'type';
+    String context = name ?? 'type';
     checkAttributes(html, ['name'], context,
         optionalAttributes: ['experimental', 'deprecated']);
     TypeDecl type = processContentsAsType(html, context);
@@ -521,7 +521,7 @@
   TypeObjectField typeObjectFieldFromHtml(dom.Element html, String context) {
     checkName(html, 'field', context);
     String name = html.attributes['name'];
-    context = '$context.${name != null ? name : 'field'}';
+    context = '$context.${name ?? 'field'}';
     checkAttributes(html, ['name'], context,
         optionalAttributes: [
           'optional',
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 1bd0430..7f9bbc7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -480,11 +480,11 @@
    * those sources. These edits may include changes to sources outside the set of specified sources
    * if a change in a specified source requires it.
    *
-   * If includedFixes is specified, then those fixes will be applied. If includeRequiredFixes is
-   * specified, then "required" fixes will be applied in addition to whatever fixes are specified in
-   * includedFixes if any. If neither includedFixes nor includeRequiredFixes is specified, then all
-   * fixes will be applied. If excludedFixes is specified, then those fixes will not be applied
-   * regardless of whether they are "required" or specified in includedFixes.
+   * If includedFixes is specified, then those fixes will be applied. If includePedanticFixes is
+   * specified, then fixes associated with the pedantic rule set will be applied in addition to
+   * whatever fixes are specified in includedFixes if any. If neither includedFixes nor
+   * includePedanticFixes is specified, then no fixes will be applied. If excludedFixes is specified,
+   * then those fixes will not be applied regardless of whether they are specified in includedFixes.
    *
    * @param included A list of the files and directories for which edits should be suggested. If a
    *         request is made with a path that is invalid, e.g. is not absolute and normalized, an
@@ -496,14 +496,13 @@
    *         specified that does not match the name of a known fix, an error of type UNKNOWN_FIX will
    *         be generated.
    * @param includePedanticFixes A flag indicating whether "pedantic" fixes should be applied.
-   * @param includeRequiredFixes A flag indicating whether "required" fixes should be applied.
    * @param excludedFixes A list of names indicating which fixes should not be applied. If a name is
    *         specified that does not match the name of a known fix, an error of type UNKNOWN_FIX will
    *         be generated.
    * @param port Deprecated: This field is now ignored by server.
    * @param outputDir Deprecated: This field is now ignored by server.
    */
-  public void edit_dartfix(List<String> included, List<String> includedFixes, boolean includePedanticFixes, boolean includeRequiredFixes, List<String> excludedFixes, int port, String outputDir, DartfixConsumer consumer);
+  public void edit_dartfix(List<String> included, List<String> includedFixes, boolean includePedanticFixes, List<String> excludedFixes, int port, String outputDir, DartfixConsumer consumer);
 
   /**
    * {@code edit.format}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
index 0669805..1d2dde1 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
@@ -46,17 +46,11 @@
   private final String description;
 
   /**
-   * `true` if the fix is in the "required" fixes group.
-   */
-  private final Boolean isRequired;
-
-  /**
    * Constructor for {@link DartFix}.
    */
-  public DartFix(String name, String description, Boolean isRequired) {
+  public DartFix(String name, String description) {
     this.name = name;
     this.description = description;
-    this.isRequired = isRequired;
   }
 
   @Override
@@ -65,8 +59,7 @@
       DartFix other = (DartFix) obj;
       return
         ObjectUtilities.equals(other.name, name) &&
-        ObjectUtilities.equals(other.description, description) &&
-        ObjectUtilities.equals(other.isRequired, isRequired);
+        ObjectUtilities.equals(other.description, description);
     }
     return false;
   }
@@ -74,8 +67,7 @@
   public static DartFix fromJson(JsonObject jsonObject) {
     String name = jsonObject.get("name").getAsString();
     String description = jsonObject.get("description") == null ? null : jsonObject.get("description").getAsString();
-    Boolean isRequired = jsonObject.get("isRequired") == null ? null : jsonObject.get("isRequired").getAsBoolean();
-    return new DartFix(name, description, isRequired);
+    return new DartFix(name, description);
   }
 
   public static List<DartFix> fromJsonArray(JsonArray jsonArray) {
@@ -98,13 +90,6 @@
   }
 
   /**
-   * `true` if the fix is in the "required" fixes group.
-   */
-  public Boolean getIsRequired() {
-    return isRequired;
-  }
-
-  /**
    * The name of the fix.
    */
   public String getName() {
@@ -116,7 +101,6 @@
     HashCodeBuilder builder = new HashCodeBuilder();
     builder.append(name);
     builder.append(description);
-    builder.append(isRequired);
     return builder.toHashCode();
   }
 
@@ -126,9 +110,6 @@
     if (description != null) {
       jsonObject.addProperty("description", description);
     }
-    if (isRequired != null) {
-      jsonObject.addProperty("isRequired", isRequired);
-    }
     return jsonObject;
   }
 
@@ -139,9 +120,7 @@
     builder.append("name=");
     builder.append(name + ", ");
     builder.append("description=");
-    builder.append(description + ", ");
-    builder.append("isRequired=");
-    builder.append(isRequired);
+    builder.append(description);
     builder.append("]");
     return builder.toString();
   }
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 02f944c..b422873 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -2171,13 +2171,13 @@
       of specified sources if a change in a specified source requires it.
     </p>
     <p>
-      If includedFixes is specified, then those fixes will be applied.
-      If includeRequiredFixes is specified, then "required" fixes will be applied
-      in addition to whatever fixes are specified in includedFixes if any.
-      If neither includedFixes nor includeRequiredFixes is specified,
-      then all fixes will be applied.
-      If excludedFixes is specified, then those fixes will not be applied
-      regardless of whether they are "required" or specified in includedFixes.
+      If includedFixes is specified, then those fixes will be applied. If
+      includePedanticFixes is specified, then fixes associated with the pedantic
+      rule set will be applied in addition to whatever fixes are specified in
+      includedFixes if any. If neither includedFixes nor includePedanticFixes is
+      specified, then no fixes will be applied. If excludedFixes is specified,
+      then those fixes will not be applied regardless of whether they are
+      specified in includedFixes.
     </p>
     <params>
       <field name="included">
@@ -2216,12 +2216,6 @@
           A flag indicating whether "pedantic" fixes should be applied.
         </p>
       </field>
-      <field name="includeRequiredFixes" optional="true">
-        <ref>bool</ref>
-        <p>
-          A flag indicating whether "required" fixes should be applied.
-        </p>
-      </field>
       <field name="excludedFixes" optional="true">
         <list>
           <ref>String</ref>
@@ -5166,12 +5160,6 @@
           A human readable description of the fix.
         </p>
       </field>
-      <field name="isRequired" optional="true">
-        <ref>bool</ref>
-        <p>
-          `true` if the fix is in the "required" fixes group.
-        </p>
-      </field>
     </object>
   </type>
   <type name="DartFixSuggestion" experimental="true">
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 4292152..6e51b61 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -170,8 +170,6 @@
 const String EDIT_REQUEST_DARTFIX_INCLUDED_FIXES = 'includedFixes';
 const String EDIT_REQUEST_DARTFIX_INCLUDE_PEDANTIC_FIXES =
     'includePedanticFixes';
-const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
-    'includeRequiredFixes';
 const String EDIT_REQUEST_DARTFIX_OUTPUT_DIR = 'outputDir';
 const String EDIT_REQUEST_DARTFIX_PORT = 'port';
 const String EDIT_REQUEST_FORMAT = 'edit.format';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index 176c557..2aa0e9b 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -62,7 +62,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['directories'] = directories;
     return result;
   }
@@ -85,7 +85,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, directories.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -174,7 +174,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['labels'] =
         labels.map((ClosingLabel value) => value.toJson()).toList();
@@ -200,7 +200,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, labels.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -276,7 +276,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((SourceChange value) => value.toJson()).toList();
@@ -298,7 +298,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, error.hashCode);
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -374,7 +374,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -400,7 +400,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, errors.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -456,7 +456,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     return result;
   }
@@ -478,7 +478,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -553,7 +553,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -579,7 +579,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -632,7 +632,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -655,7 +655,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -713,7 +713,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
     return result;
@@ -738,7 +738,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, errors.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -809,7 +809,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -833,7 +833,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -900,7 +900,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['hovers'] =
         hovers.map((HoverInformation value) => value.toJson()).toList();
     return result;
@@ -925,7 +925,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, hovers.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1016,7 +1016,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1043,7 +1043,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -1106,7 +1106,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
     return result;
@@ -1131,7 +1131,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1244,7 +1244,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['libraries'] = libraries;
     result['packageMap'] = packageMap;
     return result;
@@ -1278,7 +1278,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraries.hashCode);
     hash = JenkinsSmiHash.combine(hash, packageMap.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1374,7 +1374,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -1401,7 +1401,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -1510,7 +1510,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -1541,7 +1541,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
@@ -1596,7 +1596,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -1619,7 +1619,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1688,7 +1688,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['sources'] = sources;
     return result;
   }
@@ -1715,7 +1715,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, sources.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1787,7 +1787,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1811,7 +1811,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1918,7 +1918,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['parameters'] =
         parameters.map((ParameterInfo value) => value.toJson()).toList();
@@ -1949,7 +1949,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameters.hashCode);
     hash = JenkinsSmiHash.combine(hash, dartdoc.hashCode);
@@ -2034,7 +2034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -2060,7 +2060,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2161,7 +2161,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['classes'] =
         classes.map((ImplementedClass value) => value.toJson()).toList();
@@ -2191,7 +2191,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, classes.hashCode);
     hash = JenkinsSmiHash.combine(hash, members.hashCode);
@@ -2306,7 +2306,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2334,7 +2334,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2472,7 +2472,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -2504,7 +2504,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
@@ -2583,7 +2583,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -2609,7 +2609,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2821,7 +2821,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (enableAsync != null) {
       result['enableAsync'] = enableAsync;
     }
@@ -2869,7 +2869,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, enableAsync.hashCode);
     hash = JenkinsSmiHash.combine(hash, enableDeferredLoading.hashCode);
     hash = JenkinsSmiHash.combine(hash, enableEnums.hashCode);
@@ -2994,7 +2994,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     if (libraryName != null) {
@@ -3024,7 +3024,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, libraryName.hashCode);
@@ -3102,7 +3102,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['overrides'] =
         overrides.map((Override value) => value.toJson()).toList();
@@ -3128,7 +3128,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, overrides.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3410,7 +3410,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['included'] = included;
     result['excluded'] = excluded;
     if (packageRoots != null) {
@@ -3441,7 +3441,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
     hash = JenkinsSmiHash.combine(hash, excluded.hashCode);
     hash = JenkinsSmiHash.combine(hash, packageRoots.hashCode);
@@ -3527,7 +3527,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = subscriptions
         .map((GeneralAnalysisService value) => value.toJson())
         .toList();
@@ -3553,7 +3553,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3633,7 +3633,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     return result;
   }
@@ -3656,7 +3656,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3743,7 +3743,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -3771,7 +3771,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -3864,7 +3864,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isAnalyzing'] = isAnalyzing;
     if (analysisTarget != null) {
       result['analysisTarget'] = analysisTarget;
@@ -3886,7 +3886,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isAnalyzing.hashCode);
     hash = JenkinsSmiHash.combine(hash, analysisTarget.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3952,7 +3952,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] =
         mapMap(files, valueCallback: (dynamic value) => value.toJson());
     return result;
@@ -3976,7 +3976,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4011,7 +4011,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -4033,7 +4033,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -4086,7 +4086,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['options'] = options.toJson();
     return result;
   }
@@ -4109,7 +4109,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, options.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4187,7 +4187,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['value'] = value;
     return result;
   }
@@ -4210,7 +4210,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4317,7 +4317,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['enabled'] = enabled;
     return result;
   }
@@ -4340,7 +4340,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, enabled.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4392,7 +4392,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['action'] = action;
     return result;
   }
@@ -4415,7 +4415,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, action.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4512,7 +4512,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['event'] = event;
     result['millis'] = millis;
     return result;
@@ -4536,7 +4536,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, event.hashCode);
     hash = JenkinsSmiHash.combine(hash, millis.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4792,7 +4792,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['label'] = label;
     result['declaringLibraryUri'] = declaringLibraryUri;
     result['element'] = element.toJson();
@@ -4842,7 +4842,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
     hash = JenkinsSmiHash.combine(hash, declaringLibraryUri.hashCode);
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
@@ -4937,7 +4937,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['uri'] = uri;
     result['items'] =
@@ -4961,7 +4961,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     hash = JenkinsSmiHash.combine(hash, items.hashCode);
@@ -5050,7 +5050,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['label'] = label;
@@ -5072,7 +5072,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
@@ -5154,7 +5154,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (changedLibraries != null) {
       result['changedLibraries'] = changedLibraries
           .map((AvailableSuggestionSet value) => value.toJson())
@@ -5186,7 +5186,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, changedLibraries.hashCode);
     hash = JenkinsSmiHash.combine(hash, removedLibraries.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5261,7 +5261,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['imports'] = imports.toJson();
     return result;
@@ -5284,7 +5284,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, imports.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5400,7 +5400,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['id'] = id;
     result['label'] = label;
@@ -5429,7 +5429,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
@@ -5510,7 +5510,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['completion'] = completion;
     if (change != null) {
       result['change'] = change.toJson();
@@ -5536,7 +5536,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, completion.hashCode);
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5609,7 +5609,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -5633,7 +5633,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5689,7 +5689,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -5712,7 +5712,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5765,7 +5765,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -5788,7 +5788,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5849,7 +5849,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['tokens'] =
         tokens.map((TokenDetails value) => value.toJson()).toList();
     return result;
@@ -5874,7 +5874,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5937,7 +5937,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['paths'] =
         paths.map((LibraryPathSet value) => value.toJson()).toList();
     return result;
@@ -5962,7 +5962,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, paths.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -6265,7 +6265,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
@@ -6327,7 +6327,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacementOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode);
@@ -6447,7 +6447,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((CompletionService value) => value.toJson()).toList();
     return result;
@@ -6472,7 +6472,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -6629,7 +6629,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['explicitFileCount'] = explicitFileCount;
     result['implicitFileCount'] = implicitFileCount;
@@ -6656,7 +6656,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
     hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
@@ -6747,7 +6747,6 @@
 /// {
 ///   "name": String
 ///   "description": optional String
-///   "isRequired": optional bool
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -6756,8 +6755,6 @@
 
   String _description;
 
-  bool _isRequired;
-
   /// The name of the fix.
   String get name => _name;
 
@@ -6775,18 +6772,9 @@
     _description = value;
   }
 
-  /// `true` if the fix is in the "required" fixes group.
-  bool get isRequired => _isRequired;
-
-  /// `true` if the fix is in the "required" fixes group.
-  set isRequired(bool value) {
-    _isRequired = value;
-  }
-
-  DartFix(String name, {String description, bool isRequired}) {
+  DartFix(String name, {String description}) {
     this.name = name;
     this.description = description;
-    this.isRequired = isRequired;
   }
 
   factory DartFix.fromJson(
@@ -6804,12 +6792,7 @@
         description = jsonDecoder.decodeString(
             jsonPath + '.description', json['description']);
       }
-      bool isRequired;
-      if (json.containsKey('isRequired')) {
-        isRequired = jsonDecoder.decodeBool(
-            jsonPath + '.isRequired', json['isRequired']);
-      }
-      return DartFix(name, description: description, isRequired: isRequired);
+      return DartFix(name, description: description);
     } else {
       throw jsonDecoder.mismatch(jsonPath, 'DartFix', json);
     }
@@ -6817,14 +6800,11 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     if (description != null) {
       result['description'] = description;
     }
-    if (isRequired != null) {
-      result['isRequired'] = isRequired;
-    }
     return result;
   }
 
@@ -6834,19 +6814,16 @@
   @override
   bool operator ==(other) {
     if (other is DartFix) {
-      return name == other.name &&
-          description == other.description &&
-          isRequired == other.isRequired;
+      return name == other.name && description == other.description;
     }
     return false;
   }
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, description.hashCode);
-    hash = JenkinsSmiHash.combine(hash, isRequired.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -6910,7 +6887,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['description'] = description;
     if (location != null) {
       result['location'] = location.toJson();
@@ -6931,7 +6908,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, description.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -7017,7 +6994,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['contexts'] =
         contexts.map((ContextData value) => value.toJson()).toList();
     return result;
@@ -7042,7 +7019,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, contexts.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -7123,7 +7100,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['port'] = port;
     return result;
   }
@@ -7146,7 +7123,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, port.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -7158,7 +7135,6 @@
 ///   "included": List<FilePath>
 ///   "includedFixes": optional List<String>
 ///   "includePedanticFixes": optional bool
-///   "includeRequiredFixes": optional bool
 ///   "excludedFixes": optional List<String>
 ///   "port": optional int
 ///   "outputDir": optional FilePath
@@ -7172,8 +7148,6 @@
 
   bool _includePedanticFixes;
 
-  bool _includeRequiredFixes;
-
   List<String> _excludedFixes;
 
   int _port;
@@ -7225,14 +7199,6 @@
     _includePedanticFixes = value;
   }
 
-  /// A flag indicating whether "required" fixes should be applied.
-  bool get includeRequiredFixes => _includeRequiredFixes;
-
-  /// A flag indicating whether "required" fixes should be applied.
-  set includeRequiredFixes(bool value) {
-    _includeRequiredFixes = value;
-  }
-
   /// A list of names indicating which fixes should not be applied.
   ///
   /// If a name is specified that does not match the name of a known fix, an
@@ -7266,14 +7232,12 @@
   EditDartfixParams(List<String> included,
       {List<String> includedFixes,
       bool includePedanticFixes,
-      bool includeRequiredFixes,
       List<String> excludedFixes,
       int port,
       String outputDir}) {
     this.included = included;
     this.includedFixes = includedFixes;
     this.includePedanticFixes = includePedanticFixes;
-    this.includeRequiredFixes = includeRequiredFixes;
     this.excludedFixes = excludedFixes;
     this.port = port;
     this.outputDir = outputDir;
@@ -7300,11 +7264,6 @@
         includePedanticFixes = jsonDecoder.decodeBool(
             jsonPath + '.includePedanticFixes', json['includePedanticFixes']);
       }
-      bool includeRequiredFixes;
-      if (json.containsKey('includeRequiredFixes')) {
-        includeRequiredFixes = jsonDecoder.decodeBool(
-            jsonPath + '.includeRequiredFixes', json['includeRequiredFixes']);
-      }
       List<String> excludedFixes;
       if (json.containsKey('excludedFixes')) {
         excludedFixes = jsonDecoder.decodeList(jsonPath + '.excludedFixes',
@@ -7322,7 +7281,6 @@
       return EditDartfixParams(included,
           includedFixes: includedFixes,
           includePedanticFixes: includePedanticFixes,
-          includeRequiredFixes: includeRequiredFixes,
           excludedFixes: excludedFixes,
           port: port,
           outputDir: outputDir);
@@ -7338,7 +7296,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['included'] = included;
     if (includedFixes != null) {
       result['includedFixes'] = includedFixes;
@@ -7346,9 +7304,6 @@
     if (includePedanticFixes != null) {
       result['includePedanticFixes'] = includePedanticFixes;
     }
-    if (includeRequiredFixes != null) {
-      result['includeRequiredFixes'] = includeRequiredFixes;
-    }
     if (excludedFixes != null) {
       result['excludedFixes'] = excludedFixes;
     }
@@ -7377,7 +7332,6 @@
           listEqual(includedFixes, other.includedFixes,
               (String a, String b) => a == b) &&
           includePedanticFixes == other.includePedanticFixes &&
-          includeRequiredFixes == other.includeRequiredFixes &&
           listEqual(excludedFixes, other.excludedFixes,
               (String a, String b) => a == b) &&
           port == other.port &&
@@ -7388,11 +7342,10 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
     hash = JenkinsSmiHash.combine(hash, includedFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, includePedanticFixes.hashCode);
-    hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
     hash = JenkinsSmiHash.combine(hash, port.hashCode);
     hash = JenkinsSmiHash.combine(hash, outputDir.hashCode);
@@ -7594,7 +7547,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['suggestions'] =
         suggestions.map((DartFixSuggestion value) => value.toJson()).toList();
     result['otherSuggestions'] = otherSuggestions
@@ -7642,7 +7595,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, otherSuggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, hasErrors.hashCode);
@@ -7759,7 +7712,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -7790,7 +7743,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode);
@@ -7894,7 +7847,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     result['selectionOffset'] = selectionOffset;
     result['selectionLength'] = selectionLength;
@@ -7922,7 +7875,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode);
@@ -8014,7 +7967,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8041,7 +7994,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -8101,7 +8054,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['assists'] =
         assists.map((SourceChange value) => value.toJson()).toList();
     return result;
@@ -8126,7 +8079,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, assists.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8217,7 +8170,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -8244,7 +8197,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -8305,7 +8258,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -8330,7 +8283,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kinds.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8362,7 +8315,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -8384,7 +8337,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -8441,7 +8394,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['fixes'] = fixes.map((DartFix value) => value.toJson()).toList();
     return result;
   }
@@ -8464,7 +8417,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8535,7 +8488,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -8559,7 +8512,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -8618,7 +8571,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -8643,7 +8596,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -8736,7 +8689,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -8761,7 +8714,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -8819,7 +8772,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -8842,7 +8795,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -9004,7 +8957,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
@@ -9039,7 +8992,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9243,7 +9196,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -9292,7 +9245,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, initialProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, optionsProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, finalProblems.hashCode);
@@ -9369,7 +9322,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -9393,7 +9346,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -9472,7 +9425,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     result['whitespaceOnly'] = whitespaceOnly;
     return result;
@@ -9496,7 +9449,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     hash = JenkinsSmiHash.combine(hash, whitespaceOnly.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -9595,7 +9548,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['elements'] =
         elements.map((ImportedElements value) => value.toJson()).toList();
@@ -9626,7 +9579,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9690,7 +9643,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (edit != null) {
       result['edit'] = edit.toJson();
     }
@@ -9715,7 +9668,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -9808,7 +9761,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['key'] = key;
     result['offset'] = offset;
@@ -9833,7 +9786,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -9891,7 +9844,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['value'] = value;
     return result;
   }
@@ -9914,7 +9867,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10002,7 +9955,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['templates'] = templates
         .map((PostfixTemplateDescriptor value) => value.toJson())
         .toList();
@@ -10028,7 +9981,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, templates.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10081,7 +10034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -10104,7 +10057,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10162,7 +10115,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10185,7 +10138,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10237,7 +10190,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -10260,7 +10213,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10317,7 +10270,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['edit'] = edit.toJson();
     return result;
   }
@@ -10340,7 +10293,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, edit.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10593,7 +10546,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
@@ -10637,7 +10590,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, fileIndex.hashCode);
@@ -10714,7 +10667,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['kind'] = kind.toJson();
     return result;
@@ -10733,7 +10686,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -10855,7 +10808,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['contextRoot'] = contextRoot;
     return result;
   }
@@ -10878,7 +10831,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, contextRoot.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -10933,7 +10886,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -10956,7 +10909,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -11009,7 +10962,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -11032,7 +10985,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -11245,7 +11198,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['code'] = code;
     result['offset'] = offset;
     result['contextFile'] = contextFile;
@@ -11292,7 +11245,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, contextFile.hashCode);
@@ -11397,7 +11350,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (suggestions != null) {
       result['suggestions'] = suggestions
           .map((CompletionSuggestion value) => value.toJson())
@@ -11435,7 +11388,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
     hash = JenkinsSmiHash.combine(hash, expressions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -11531,7 +11484,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     if (kind != null) {
       result['kind'] = kind.toJson();
@@ -11562,7 +11515,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, referencedFiles.hashCode);
@@ -11648,7 +11601,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     if (file != null) {
       result['file'] = file;
@@ -11677,7 +11630,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
@@ -11750,7 +11703,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (file != null) {
       result['file'] = file;
     }
@@ -11778,7 +11731,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -11880,7 +11833,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((ExecutionService value) => value.toJson()).toList();
     return result;
@@ -11905,7 +11858,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -12000,7 +11953,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['uri'] = uri;
     result['elements'] = elements;
     return result;
@@ -12020,7 +11973,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, uri.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12092,7 +12045,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['elements'] = elements.toJson();
     result['imports'] =
         imports.map((ExistingImport value) => value.toJson()).toList();
@@ -12114,7 +12067,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
     hash = JenkinsSmiHash.combine(hash, imports.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12259,7 +12212,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
@@ -12291,7 +12244,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, coveringExpressionOffsets.hashCode);
     hash = JenkinsSmiHash.combine(hash, coveringExpressionLengths.hashCode);
     hash = JenkinsSmiHash.combine(hash, names.hashCode);
@@ -12375,7 +12328,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -12394,7 +12347,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, extractAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -12608,7 +12561,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -12646,7 +12599,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
@@ -12816,7 +12769,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -12848,7 +12801,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
     hash = JenkinsSmiHash.combine(hash, createGetter.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -12879,7 +12832,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -12896,7 +12849,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -12948,7 +12901,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -12966,7 +12919,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -13087,7 +13040,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -13111,7 +13064,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -13177,7 +13130,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['properties'] = properties
         .map((FlutterWidgetProperty value) => value.toJson())
         .toList();
@@ -13203,7 +13156,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, properties.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -13491,7 +13444,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -13553,7 +13506,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -13741,7 +13694,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['label'] = label;
     if (literalValueBoolean != null) {
@@ -13781,7 +13734,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, label.hashCode);
     hash = JenkinsSmiHash.combine(hash, literalValueBoolean.hashCode);
@@ -13947,7 +13900,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['outline'] = outline.toJson();
     return result;
@@ -13970,7 +13923,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, outline.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14076,7 +14029,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (FlutterService value) => value.toJson());
     return result;
@@ -14104,7 +14057,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -14225,7 +14178,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     if (value != null) {
       result['value'] = value.toJson();
@@ -14251,7 +14204,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14308,7 +14261,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['change'] = change.toJson();
     return result;
   }
@@ -14331,7 +14284,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -14566,7 +14519,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (documentation != null) {
       result['documentation'] = documentation;
     }
@@ -14613,7 +14566,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, documentation.hashCode);
     hash = JenkinsSmiHash.combine(hash, expression.hashCode);
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
@@ -14687,7 +14640,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     if (enumItems != null) {
       result['enumItems'] = enumItems
@@ -14716,7 +14669,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, enumItems.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -14942,7 +14895,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (boolValue != null) {
       result['boolValue'] = boolValue;
     }
@@ -14982,7 +14935,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, boolValue.hashCode);
     hash = JenkinsSmiHash.combine(hash, doubleValue.hashCode);
     hash = JenkinsSmiHash.combine(hash, intValue.hashCode);
@@ -15105,7 +15058,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['libraryUri'] = libraryUri;
     result['className'] = className;
     result['name'] = name;
@@ -15131,7 +15084,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraryUri.hashCode);
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -15478,7 +15431,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (containingLibraryPath != null) {
@@ -15538,7 +15491,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, containingLibraryPath.hashCode);
@@ -15615,7 +15568,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15634,7 +15587,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -15701,7 +15654,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     return result;
@@ -15720,7 +15673,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -15809,7 +15762,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['strings'] = strings;
     result['uris'] = uris;
     result['names'] = names;
@@ -15832,7 +15785,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, strings.hashCode);
     hash = JenkinsSmiHash.combine(hash, uris.hashCode);
     hash = JenkinsSmiHash.combine(hash, names.hashCode);
@@ -15922,7 +15875,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['path'] = path;
     result['prefix'] = prefix;
     result['elements'] = elements;
@@ -15944,7 +15897,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, path.hashCode);
     hash = JenkinsSmiHash.combine(hash, prefix.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
@@ -16018,7 +15971,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['tag'] = tag;
     result['relevanceBoost'] = relevanceBoost;
     return result;
@@ -16037,7 +15990,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, tag.hashCode);
     hash = JenkinsSmiHash.combine(hash, relevanceBoost.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16138,7 +16091,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['relevance'] = relevance;
     if (displayUri != null) {
@@ -16162,7 +16115,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, relevance.hashCode);
     hash = JenkinsSmiHash.combine(hash, displayUri.hashCode);
@@ -16232,7 +16185,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -16251,7 +16204,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16362,7 +16315,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (className != null) {
       result['className'] = className;
     }
@@ -16386,7 +16339,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     hash = JenkinsSmiHash.combine(hash, methodName.hashCode);
     hash = JenkinsSmiHash.combine(hash, isDeclaration.hashCode);
@@ -16466,7 +16419,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -16485,7 +16438,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, deleteSource.hashCode);
     hash = JenkinsSmiHash.combine(hash, inlineAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16541,7 +16494,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -16564,7 +16517,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -16649,7 +16602,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -16676,7 +16629,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, entries.hashCode);
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16750,7 +16703,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['scope'] = scope;
     result['libraryPaths'] = libraryPaths;
     return result;
@@ -16771,7 +16724,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, scope.hashCode);
     hash = JenkinsSmiHash.combine(hash, libraryPaths.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -16844,7 +16797,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -16862,7 +16815,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newFile.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -16930,7 +16883,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['element'] = element.toJson();
     result['className'] = className;
     return result;
@@ -16949,7 +16902,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -17065,7 +17018,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (superclassMember != null) {
@@ -17096,7 +17049,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, superclassMember.hashCode);
@@ -17187,7 +17140,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['key'] = key;
     result['example'] = example;
@@ -17207,7 +17160,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, key.hashCode);
     hash = JenkinsSmiHash.combine(hash, example.hashCode);
@@ -17259,7 +17212,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isListingPackageDirs'] = isListingPackageDirs;
     return result;
   }
@@ -17277,7 +17230,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isListingPackageDirs.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -17300,7 +17253,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -17317,7 +17270,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -17338,7 +17291,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -17355,7 +17308,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -17465,7 +17418,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -17489,7 +17442,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, elementKindName.hashCode);
@@ -17546,7 +17499,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newName'] = newName;
     return result;
   }
@@ -17564,7 +17517,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newName.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -17651,7 +17604,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['code'] = code.toJson();
     result['message'] = message;
     if (stackTrace != null) {
@@ -17675,7 +17628,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -18104,7 +18057,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     if (type != null) {
@@ -18128,7 +18081,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
@@ -18318,7 +18271,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (libraryPath != null) {
       result['libraryPath'] = libraryPath;
     }
@@ -18375,7 +18328,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, libraryPath.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -18511,7 +18464,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['type'] = type.toJson();
     return result;
@@ -18530,7 +18483,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -18628,7 +18581,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['includePotential'] = includePotential;
@@ -18655,7 +18608,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, includePotential.hashCode);
@@ -18738,7 +18691,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (id != null) {
       result['id'] = id;
     }
@@ -18766,7 +18719,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -18820,7 +18773,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -18843,7 +18796,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -18898,7 +18851,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -18921,7 +18874,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -18974,7 +18927,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     return result;
   }
@@ -18997,7 +18950,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19052,7 +19005,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -19075,7 +19028,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19131,7 +19084,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['pattern'] = pattern;
     return result;
   }
@@ -19154,7 +19107,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19209,7 +19162,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     return result;
   }
@@ -19232,7 +19185,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19324,7 +19277,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (file != null) {
       result['file'] = file;
     }
@@ -19357,7 +19310,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
     hash = JenkinsSmiHash.combine(hash, maxResults.hashCode);
@@ -19439,7 +19392,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['declarations'] =
         declarations.map((ElementDeclaration value) => value.toJson()).toList();
     result['files'] = files;
@@ -19466,7 +19419,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, declarations.hashCode);
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -19560,7 +19513,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     if (superOnly != null) {
@@ -19589,7 +19542,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, superOnly.hashCode);
@@ -19663,7 +19616,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (hierarchyItems != null) {
       result['hierarchyItems'] = hierarchyItems
           .map((TypeHierarchyItem value) => value.toJson())
@@ -19691,7 +19644,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, hierarchyItems.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -19813,7 +19766,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['location'] = location.toJson();
     result['kind'] = kind.toJson();
     result['isPotential'] = isPotential;
@@ -19837,7 +19790,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, isPotential.hashCode);
@@ -20026,7 +19979,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['id'] = id;
     result['results'] =
         results.map((SearchResult value) => value.toJson()).toList();
@@ -20054,7 +20007,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, results.hashCode);
     hash = JenkinsSmiHash.combine(hash, isLast.hashCode);
@@ -20128,7 +20081,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['version'] = version;
     result['pid'] = pid;
     return result;
@@ -20151,7 +20104,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
     hash = JenkinsSmiHash.combine(hash, pid.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -20249,7 +20202,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -20275,7 +20228,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isFatal.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -20358,7 +20311,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['version'] = version;
     return result;
   }
@@ -20381,7 +20334,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20473,7 +20426,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['time'] = time;
     result['kind'] = kind.toJson();
     result['data'] = data;
@@ -20493,7 +20446,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, time.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, data.hashCode);
@@ -20633,7 +20586,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['entry'] = entry.toJson();
     return result;
   }
@@ -20655,7 +20608,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, entry.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20761,7 +20714,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] =
         subscriptions.map((ServerService value) => value.toJson()).toList();
     return result;
@@ -20786,7 +20739,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -20940,7 +20893,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (analysis != null) {
       result['analysis'] = analysis.toJson();
     }
@@ -20967,7 +20920,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, analysis.hashCode);
     hash = JenkinsSmiHash.combine(hash, pub.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -21081,7 +21034,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['lexeme'] = lexeme;
     if (type != null) {
       result['type'] = type;
@@ -21110,7 +21063,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
@@ -21320,7 +21273,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['classElement'] = classElement.toJson();
     if (displayName != null) {
       result['displayName'] = displayName;
@@ -21356,7 +21309,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, classElement.hashCode);
     hash = JenkinsSmiHash.combine(hash, displayName.hashCode);
     hash = JenkinsSmiHash.combine(hash, memberElement.hashCode);
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index df7fd67..17ab10b 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.39.5-dev
+* Deprecated `ClassElement.instantiateToBounds()` and
+  `FunctionTypeAliasElement.instantiateToBounds()`. With the null-safety
+  feature, type arguments derived from type parameter bounds cannot be used as
+  is, and might require erasing nullability, when the element is instantiated
+  from a legacy library. Use `TypeSystem.instantiateToBounds2()` instead.
+
 ## 0.39.4
 * Deprecated `DartType.name`, use `element` or `getDisplayString()` instead.
 * Fixed bugs 35108 and 39996.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 2353cb9..38c46a8 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -232,6 +232,7 @@
   /// Create the [InterfaceType] for this class with type arguments that
   /// correspond to the bounds of the type parameters, and the given
   /// [nullabilitySuffix].
+  @Deprecated('Use TypeSystem.instantiateToBounds2() instead')
   InterfaceType instantiateToBounds({
     @required NullabilitySuffix nullabilitySuffix,
   });
@@ -1191,6 +1192,7 @@
   /// generic function, with type formals. For example, if the typedef is:
   ///     typedef F<T> = void Function<U>(T, U);
   /// then `F<int>` will produce `void Function<U>(int, U)`.
+  @Deprecated('Use TypeSystem.instantiateToBounds2() instead')
   FunctionType instantiateToBounds({
     @required NullabilitySuffix nullabilitySuffix,
   });
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 8573d0ed..298ece7 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -2,6 +2,8 @@
 // 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/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:meta/meta.dart';
 
@@ -33,6 +35,17 @@
   /// Other type systems may define this operation differently.
   DartType flatten(DartType type);
 
+  /// Instantiate the given generic element using the type arguments that
+  /// correspond to the bounds of its type parameters.
+  ///
+  /// One and only one of [classElement] or [functionTypeAliasElement] must
+  /// be provided.
+  DartType instantiateToBounds2({
+    ClassElement classElement,
+    FunctionTypeAliasElement functionTypeAliasElement,
+    @required NullabilitySuffix nullabilitySuffix,
+  });
+
   /// Return `true` if the [leftType] is assignable to the [rightType].
   ///
   /// For the Dart 2.0 type system, the definition of this relationship is given
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index 092f0b2..2f7abdf 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -11,6 +11,10 @@
 import 'package:pub_semver/pub_semver.dart';
 
 class FeatureSetProvider {
+  /// This flag will be turned to `true` and inlined when we un-fork SDK,
+  /// so that the only SDK is the Null Safe SDK.
+  static const isNullSafetySdk = false;
+
   static final _preNonNullableVersion = Version(2, 7, 0);
 
   final FeatureSet _sdkFeatureSet;
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 654f29d..04dc28d 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -146,12 +146,6 @@
 
 /// A representation of an instance of a Dart class.
 class DartObjectImpl implements DartObject {
-  /// When `true`, `operator==` only compares constant values, ignoring types.
-  ///
-  /// This is a temporary hack to work around dartbug.com/35908.
-  // TODO(paulberry): when #35908 is fixed, remove this hack.
-  static bool _ignoreTypesInEqualityComparison = false;
-
   @override
   final ParameterizedType type;
 
@@ -208,8 +202,7 @@
   @override
   bool operator ==(Object object) {
     if (object is DartObjectImpl) {
-      return (_ignoreTypesInEqualityComparison || type == object.type) &&
-          _state == object._state;
+      return type == object.type && _state == object._state;
     }
     return false;
   }
@@ -447,21 +440,6 @@
       DartObjectImpl(
           typeProvider.intType, _state.integerDivide(rightOperand._state));
 
-  /// Indicates whether `this` is equal to [other], ignoring types both in this
-  /// object and sub-objects.
-  ///
-  /// This is a temporary hack to work around dartbug.com/35908.
-  // TODO(paulberry): when #35908 is fixed, remove this hack.
-  bool isEqualIgnoringTypesRecursively(Object other) {
-    bool oldIgnoreTypesInEqualityComparison = _ignoreTypesInEqualityComparison;
-    _ignoreTypesInEqualityComparison = true;
-    try {
-      return this == other;
-    } finally {
-      _ignoreTypesInEqualityComparison = oldIgnoreTypesInEqualityComparison;
-    }
-  }
-
   /// Return the result of invoking the identical function on this object with
   /// the [rightOperand]. The [typeProvider] is the type provider used to find
   /// known types.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9ba8289..0e75695 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -207,6 +207,7 @@
     );
   }
 
+  @Deprecated('Use TypeSystem.instantiateToBounds2() instead')
   @override
   InterfaceType instantiateToBounds({
     @required NullabilitySuffix nullabilitySuffix,
@@ -4785,6 +4786,7 @@
     );
   }
 
+  @Deprecated('Use TypeSystem.instantiateToBounds2() instead')
   @override
   FunctionType instantiateToBounds({
     @required NullabilitySuffix nullabilitySuffix,
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index a83bbd9..7bde90f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -108,15 +108,23 @@
     if (constructor == null || definingType.typeArguments.isEmpty) {
       return constructor;
     }
+
     FunctionType baseType = constructor.type;
     if (baseType == null) {
       // TODO(brianwilkerson) We need to understand when this can happen.
       return constructor;
     }
+
+    var isLegacy = false;
+    if (constructor is ConstructorMember) {
+      isLegacy = (constructor as ConstructorMember).isLegacy;
+      constructor = constructor.declaration;
+    }
+
     return ConstructorMember(
       constructor,
       Substitution.fromInterfaceType(definingType),
-      false,
+      isLegacy,
     );
   }
 }
@@ -175,7 +183,7 @@
 
   @override
   List<ParameterElement> get parameters {
-    return declaration.parameters.map((p) {
+    return declaration.parameters.map<ParameterElement>((p) {
       if (p is FieldFormalParameterElement) {
         return FieldFormalParameterMember(p, _substitution, isLegacy);
       }
diff --git a/pkg/analyzer/lib/src/dart/element/normalize.dart b/pkg/analyzer/lib/src/dart/element/normalize.dart
new file mode 100644
index 0000000..ebf6cef
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/normalize.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2020, 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/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.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/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+
+/// Helper for computing canonical presentation of types.
+///
+/// https://github.com/dart-lang/language
+/// See `resources/type-system/normalization.md`
+class NormalizeHelper {
+  final TypeSystemImpl typeSystem;
+  final TypeProviderImpl typeProvider;
+
+  final Set<TypeParameterElement> _typeParameters = {};
+
+  NormalizeHelper(this.typeSystem) : typeProvider = typeSystem.typeProvider;
+
+  DartType normalize(DartType T) {
+    return _normalize(T);
+  }
+
+  /// NORM(R Function<X extends B>(S)) = R1 Function(X extends B1>(S1)
+  ///   * where R1 = NORM(R)
+  ///   * and B1 = NORM(B)
+  ///   * and S1 = NORM(S)
+  FunctionTypeImpl _functionType(FunctionType functionType) {
+    var fresh = getFreshTypeParameters(functionType.typeFormals);
+    for (var typeParameter in fresh.freshTypeParameters) {
+      if (typeParameter.bound != null) {
+        var typeParameterImpl = typeParameter as TypeParameterElementImpl;
+        typeParameterImpl.bound = _normalize(typeParameter.bound);
+      }
+    }
+
+    functionType = fresh.applyToFunctionType(functionType);
+
+    return FunctionTypeImpl(
+      typeFormals: functionType.typeFormals,
+      parameters: functionType.parameters.map((e) {
+        return ParameterElementImpl.synthetic(
+          e.name,
+          _normalize(e.type),
+          // ignore: deprecated_member_use_from_same_package
+          e.parameterKind,
+        )..isExplicitlyCovariant = e.isCovariant;
+      }).toList(),
+      returnType: _normalize(functionType.returnType),
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  /// NORM(FutureOr<T>)
+  DartType _futureOr(InterfaceType T) {
+    // * let S be NORM(T)
+    var S = _normalize(T.typeArguments[0]);
+    var S_nullability = S.nullabilitySuffix;
+
+    // * if S is a top type then S
+    if (typeSystem.isTop(S)) {
+      return S;
+    }
+
+    // * if S is Object then S
+    // * if S is Object* then S
+    if (S.isDartCoreObject) {
+      if (S_nullability == NullabilitySuffix.none ||
+          S_nullability == NullabilitySuffix.star) {
+        return S;
+      }
+    }
+
+    // * if S is Never then Future<Never>
+    if (identical(S, NeverTypeImpl.instance)) {
+      return typeProvider.futureElement.instantiate(
+        typeArguments: [NeverTypeImpl.instance],
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    }
+
+    // * if S is Null then Future<Null>?
+    if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
+      return typeProvider.futureElement.instantiate(
+        typeArguments: [typeSystem.nullNone],
+        nullabilitySuffix: NullabilitySuffix.question,
+      );
+    }
+
+    // * else FutureOr<S>
+    return typeProvider.futureOrElement.instantiate(
+      typeArguments: [S],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  DartType _normalize(DartType T) {
+    var T_nullability = T.nullabilitySuffix;
+
+    // NORM(T) = T if T is primitive
+    if (identical(T, DynamicTypeImpl.instance) ||
+        identical(T, NeverTypeImpl.instance) ||
+        identical(T, VoidTypeImpl.instance) ||
+        T_nullability == NullabilitySuffix.none &&
+            T is InterfaceType &&
+            T.typeArguments.isEmpty) {
+      return T;
+    }
+
+    // NORM(FutureOr<T>)
+    if (T_nullability == NullabilitySuffix.none &&
+        T is InterfaceType &&
+        T.isDartAsyncFutureOr) {
+      return _futureOr(T);
+    }
+
+    // NORM(T?)
+    if (T_nullability == NullabilitySuffix.question) {
+      return _nullabilityQuestion(T);
+    }
+
+    // NORM(T*)
+    if (T_nullability == NullabilitySuffix.star) {
+      return _nullabilityStar(T);
+    }
+
+    assert(T_nullability == NullabilitySuffix.none);
+
+    // NORM(X extends T)
+    // NORM(X & T)
+    if (T is TypeParameterType) {
+      return _typeParameterType(T);
+    }
+
+    // NORM(C<T0, ..., Tn>) = C<R0, ..., Rn> where Ri is NORM(Ti)
+    if (T is InterfaceType) {
+      return T.element.instantiate(
+        typeArguments: T.typeArguments.map(_normalize).toList(),
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    }
+
+    // NORM(R Function<X extends B>(S)) = R1 Function(X extends B1>(S1)
+    return _functionType(T);
+  }
+
+  /// NORM(T?)
+  DartType _nullabilityQuestion(TypeImpl T) {
+    // * let S be NORM(T)
+    var T_none = T.withNullability(NullabilitySuffix.none);
+    var S = _normalize(T_none);
+    var S_nullability = S.nullabilitySuffix;
+
+    // * if S is a top type then S
+    if (typeSystem.isTop(S)) {
+      return S;
+    }
+
+    // * if S is Never then Null
+    if (identical(S, NeverTypeImpl.instance)) {
+      return typeSystem.nullNone;
+    }
+
+    // * if S is Never* then Null
+    if (identical(S, NeverTypeImpl.instanceLegacy)) {
+      return typeSystem.nullNone;
+    }
+
+    // * if S is Null then Null
+    if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
+      return typeSystem.nullNone;
+    }
+
+    // * if S is FutureOr<R> and R is nullable then S
+    if (S_nullability == NullabilitySuffix.none &&
+        S is InterfaceType &&
+        S.isDartAsyncFutureOr) {
+      var R = S.typeArguments[0];
+      if (typeSystem.isNullable(R)) {
+        return S;
+      }
+    }
+
+    // * if S is FutureOr<R>* and R is nullable then FutureOr<R>
+    if (S_nullability == NullabilitySuffix.star &&
+        S is InterfaceType &&
+        S.isDartAsyncFutureOr) {
+      var R = S.typeArguments[0];
+      if (typeSystem.isNullable(R)) {
+        return typeProvider.futureOrElement.instantiate(
+          typeArguments: [R],
+          nullabilitySuffix: NullabilitySuffix.none,
+        );
+      }
+    }
+
+    // * if S is R? then R?
+    // * if S is R* then R?
+    // * else S?
+    return (S as TypeImpl).withNullability(NullabilitySuffix.question);
+  }
+
+  /// NORM(T*)
+  DartType _nullabilityStar(TypeImpl T) {
+    // * let S be NORM(T)
+    var T_none = T.withNullability(NullabilitySuffix.none);
+    var S = _normalize(T_none);
+    var S_nullability = S.nullabilitySuffix;
+
+    // * if S is a top type then S
+    if (typeSystem.isTop(S)) {
+      return S;
+    }
+
+    // * if S is Null then Null
+    if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
+      return typeSystem.nullNone;
+    }
+
+    // * if S is R? then R?
+    if (S_nullability == NullabilitySuffix.question) {
+      return S;
+    }
+
+    // * if S is R* then R*
+    // * else S*
+    return (S as TypeImpl).withNullability(NullabilitySuffix.star);
+  }
+
+  /// NORM(X extends T)
+  /// NORM(X & T)
+  DartType _typeParameterType(TypeParameterType T) {
+    var element = T.element;
+
+    var bound = element.bound;
+    if (bound == null) {
+      return T;
+    }
+
+    // * let S be NORM(T)
+    DartType S;
+    if (_typeParameters.add(element)) {
+      S = _normalize(bound);
+      _typeParameters.remove(element);
+    } else {
+      return T;
+    }
+
+    // * if S is Never then Never
+    if (identical(S, NeverTypeImpl.instance)) {
+      return NeverTypeImpl.instance;
+    }
+
+    if (element is TypeParameterMember) {
+      return _typeParameterType_promoted(element, S);
+    } else {
+      // NORM(X extends T)
+      // * else X
+      return T;
+    }
+  }
+
+  /// NORM(X & T)
+  /// * let S be NORM(T)
+  DartType _typeParameterType_promoted(TypeParameterMember X, DartType S) {
+    // * if S is a top type then X
+    if (typeSystem.isTop(S)) {
+      return X.declaration.instantiate(
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    }
+
+    // * if S is X then X
+    if (S is TypeParameterType &&
+        S.nullabilitySuffix == NullabilitySuffix.none &&
+        S.element == X.declaration) {
+      return X.declaration.instantiate(
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    }
+
+    // * if S is Object and NORM(B) is Object where B is the bound of X then X
+    if (S.nullabilitySuffix == NullabilitySuffix.none && S.isDartCoreObject) {
+      var B = X.declaration.bound;
+      if (B != null) {
+        var B_norm = _normalize(B);
+        if (B_norm.nullabilitySuffix == NullabilitySuffix.none &&
+            B_norm.isDartCoreObject) {
+          return X.declaration.instantiate(
+            nullabilitySuffix: NullabilitySuffix.none,
+          );
+        }
+      }
+    }
+
+    // * else X & S
+    var promoted = TypeParameterMember(
+      X.declaration,
+      Substitution.empty,
+      S,
+    );
+    return promoted.instantiate(
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/top_merge.dart b/pkg/analyzer/lib/src/dart/element/top_merge.dart
index aa62184..147e00b 100644
--- a/pkg/analyzer/lib/src/dart/element/top_merge.dart
+++ b/pkg/analyzer/lib/src/dart/element/top_merge.dart
@@ -8,8 +8,13 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 
 class TopMergeHelper {
+  final TypeSystemImpl typeSystem;
+
+  TopMergeHelper(this.typeSystem);
+
   /**
    * Merges two types into a single type.
    * Compute the canonical representation of [T].
@@ -18,7 +23,7 @@
    * See `accepted/future-releases/nnbd/feature-specification.md`
    * See `#classes-defined-in-opted-in-libraries`
    */
-  static DartType topMerge(DartType T, DartType S) {
+  DartType topMerge(DartType T, DartType S) {
     var T_nullability = T.nullabilitySuffix;
     var S_nullability = S.nullabilitySuffix;
 
@@ -51,6 +56,16 @@
       return VoidTypeImpl.instance;
     }
 
+    // NNBD_TOP_MERGE(void, Object*) = void
+    // NNBD_TOP_MERGE(Object*, void) = void
+    var T_isObjectStar =
+        T_nullability == NullabilitySuffix.star && T.isDartCoreObject;
+    var S_isObjectStar =
+        S_nullability == NullabilitySuffix.star && S.isDartCoreObject;
+    if (T_isVoid && S_isObjectStar || T_isObjectStar && S_isVoid) {
+      return VoidTypeImpl.instance;
+    }
+
     // NNBD_TOP_MERGE(void, dynamic) = void
     // NNBD_TOP_MERGE(dynamic, void) = void
     if (T_isVoid && S_isDynamic || T_isDynamic && S_isVoid) {
@@ -66,6 +81,12 @@
       return S;
     }
 
+    // NNBD_TOP_MERGE(Object*, dynamic) = Object?
+    // NNBD_TOP_MERGE(dynamic, Object*) = Object?
+    if (T_isObjectStar && S_isDynamic || T_isDynamic && S_isObjectStar) {
+      return typeSystem.objectQuestion;
+    }
+
     // NNBD_TOP_MERGE(Never*, Null) = Null
     // NNBD_TOP_MERGE(Null, Never*) = Null
     if (identical(T, NeverTypeImpl.instanceLegacy) &&
@@ -144,7 +165,7 @@
     throw _TopMergeStateError(T, S, 'Unexpected pair');
   }
 
-  static FunctionTypeImpl _functionTypes(FunctionType T, FunctionType S) {
+  FunctionTypeImpl _functionTypes(FunctionType T, FunctionType S) {
     var T_typeParameters = T.typeFormals;
     var S_typeParameters = S.typeFormals;
     if (T_typeParameters.length != S_typeParameters.length) {
@@ -205,12 +226,39 @@
         throw _TopMergeStateError(T, S, 'Different named parameter names');
       }
 
-      var R_type = mergeTypes(T_parameter.type, S_parameter.type);
+      DartType R_type;
+
+      // Given two corresponding parameters of type `T1` and `T2`, where at least
+      // one of the parameters is covariant:
+      var T_isCovariant = T_parameter.isCovariant;
+      var S_isCovariant = S_parameter.isCovariant;
+      var R_isCovariant = T_isCovariant || S_isCovariant;
+      if (R_isCovariant) {
+        var T1 = T_parameter.type;
+        var T2 = S_parameter.type;
+        var T1_isSubtype = typeSystem.isSubtypeOf(T1, T2);
+        var T2_isSubtype = typeSystem.isSubtypeOf(T2, T1);
+        if (T1_isSubtype && T2_isSubtype) {
+          // if `T1 <: T2` and `T2 <: T1`, then the result is
+          // `NNBD_TOP_MERGE(T1, T2)`, and it is covariant.
+          R_type = mergeTypes(T_parameter.type, S_parameter.type);
+        } else if (T1_isSubtype) {
+          // otherwise, if `T1 <: T2`, then the result is
+          // `T2` and it is covariant.
+          R_type = T2;
+        } else {
+          // otherwise, the result is `T1` and it is covariant.
+          R_type = T1;
+        }
+      } else {
+        R_type = mergeTypes(T_parameter.type, S_parameter.type);
+      }
+
       R_parameters[i] = ParameterElementImpl.synthetic(
         T_parameter.name,
         R_type,
         T_kind,
-      );
+      )..isExplicitlyCovariant = R_isCovariant;
     }
 
     return FunctionTypeImpl(
@@ -221,7 +269,7 @@
     );
   }
 
-  static InterfaceType _interfaceTypes(InterfaceType T, InterfaceType S) {
+  InterfaceType _interfaceTypes(InterfaceType T, InterfaceType S) {
     if (T.element != S.element) {
       throw _TopMergeStateError(T, S, 'Different class elements');
     }
@@ -242,7 +290,7 @@
     }
   }
 
-  static _MergeTypeParametersResult _typeParameters(
+  _MergeTypeParametersResult _typeParameters(
     List<TypeParameterElement> aParameters,
     List<TypeParameterElement> bParameters,
   ) {
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index bd2f179..f1653a6 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -124,7 +124,7 @@
           substitute(parameter.type),
           // ignore: deprecated_member_use_from_same_package
           parameter.parameterKind,
-        );
+        )..isExplicitlyCovariant = parameter.isCovariant;
       }).toList(),
       returnType: substitute(type.returnType),
       nullabilitySuffix: type.nullabilitySuffix,
@@ -524,7 +524,7 @@
     }
 
     return NamedTypeBuilder(
-      type.isNNBD,
+      type.typeSystem,
       type.element,
       arguments,
       type.nullabilitySuffix,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index d0a5a00..a6a834e 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -30,7 +30,7 @@
   // The analyzer produces this diagnostic when code is found that won't be
   // executed because execution will never reach the code.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the invocation of
   // `print` occurs after the function has returned:
@@ -91,7 +91,7 @@
   // object is selected, and both of those forms will match any object, so no
   // catch clauses that follow them will be selected.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -154,7 +154,7 @@
   // matches anything matchable by the highlighted clause, so the highlighted
   // clause will never be selected.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -223,7 +223,7 @@
   // The analyzer produces this diagnostic when a deprecated library or class
   // member is used in a different package.
   //
-  // #### Example
+  // #### Examples
   //
   // If the method `m` in the class `C` is annotated with `@deprecated`, then
   // the following code produces this diagnostic:
@@ -253,7 +253,7 @@
   // The analyzer produces this diagnostic when a deprecated library member or
   // class member is used in the same package in which it's declared.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is deprecated:
   //
@@ -329,7 +329,7 @@
   // that is the same as an import before it in the file. The second import
   // doesn’t add value and should be removed.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -503,7 +503,7 @@
   // The analyzer produces this diagnostic when the `@literal` annotation is
   // applied to anything other than a const constructor.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the constructor is not
   // a `const` constructor:
@@ -835,7 +835,7 @@
   // The analyzer produces this diagnostic when either the `@visibleForTemplate`
   // or `@visibleForTesting` annotation is applied to a non-public declaration.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -938,7 +938,7 @@
   // named parameter that is annotated as being required is invoked without
   // providing a value for the parameter.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the named parameter `x`
   // is required:
@@ -995,7 +995,7 @@
   // throw implicitly returns `null`. This is rarely the desired behavior. The
   // analyzer produces this diagnostic when it finds an implicit return.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` doesn't end with a
   // return:
@@ -1034,7 +1034,7 @@
   // Classes that are sealed can't be extended, implemented, mixed in, or used
   // as a superclass constraint.
   //
-  // #### Example
+  // #### Examples
   //
   // If the package 'p' defines a sealed class:
   //
@@ -1081,7 +1081,7 @@
   // marked as being immutable using the annotation `@immutable` or if it's a
   // subclass of an immutable class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the field `x` isn't
   // final:
@@ -1130,15 +1130,56 @@
           "{0}");
 
   /**
-   * Generate a hint for methods that override methods annotated `@mustCallSuper`
-   * that do not invoke the overridden super method.
-   *
    * Parameters:
    * 0: the name of the class declaring the overridden method
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a method that overrides a method
+  // that is annotated as `@mustCallSuper` doesn't invoke the overridden method
+  // as required.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the method `m` in `B`
+  // doesn't invoke the overridden method `m` in `A`:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // class A {
+  //   @mustCallSuper
+  //   m() {}
+  // }
+  //
+  // class B extends A {
+  //   @override
+  //   [!m!]() {}
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add an invocation of the overridden method in the overriding method:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // class A {
+  //   @mustCallSuper
+  //   m() {}
+  // }
+  //
+  // class B extends A {
+  //   @override
+  //   m() {
+  //     super.m();
+  //   }
+  // }
+  // ```
   static const HintCode MUST_CALL_SUPER = HintCode(
       'MUST_CALL_SUPER',
-      "This method overrides a method annotated as @mustCallSuper in '{0}', "
+      "This method overrides a method annotated as '@mustCallSuper' in '{0}', "
           "but doesn't invoke the overridden method.");
 
   /**
@@ -1156,7 +1197,7 @@
   // that the constructor should be used to create a constant value whenever
   // possible.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -1289,7 +1330,7 @@
   // the `@override` annotation, but the member isn’t declared in any of the
   // supertypes of the class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` isn't declared in
   // any of the supertypes of `C`:
@@ -1382,7 +1423,7 @@
   // earlier versions, these classes weren't defined in `dart:core`, so the
   // import was necessary.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.1.0:
@@ -1438,7 +1479,7 @@
   // versions, so this code won't be able to run against earlier versions of the
   // SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.3.2:
@@ -1495,7 +1536,7 @@
   // [constant context](#constant-context) wasn't supported in earlier versions,
   // so this code won't be able to run against earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.3.2:
@@ -1554,7 +1595,7 @@
   // supported in earlier versions, so this code won't be able to run against
   // earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.3.2:
@@ -1614,7 +1655,7 @@
   // versions, so this code won't be able to run against earlier versions of the
   // SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.6.0:
@@ -1673,7 +1714,7 @@
   // operator wasn't supported in earlier versions, so this code won't be able
   // to run against earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.X.0:
@@ -1733,7 +1774,7 @@
   // versions, so this code won't be able to run against earlier versions of the
   // SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.3.2:
@@ -1789,7 +1830,7 @@
   // literals weren't supported in earlier versions, so this code won't be able
   // to run against earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.2.0:
@@ -1840,7 +1881,7 @@
   // 2.X.0. This class wasn't defined in earlier versions, so this code won't be
   // able to run against earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.X.0:
@@ -1893,7 +1934,7 @@
   // versions, so this code won't be able to run against earlier versions of the
   // SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.3.0:
@@ -1954,7 +1995,7 @@
   // supported in earlier versions, so this code won't be able to run against
   // earlier versions of the SDK.
   //
-  // #### Example
+  // #### Examples
   //
   // Here's an example of a pubspec that defines an SDK constraint with a lower
   // bound of less than 2.5.0:
@@ -2042,23 +2083,108 @@
       correction: "Try replacing the 'is Null' check with '== null'.");
 
   /**
-   * An undefined name hidden in an import or export directive.
+   * Parameters:
+   * 0: the name of the library being imported
+   * 1: the name in the hide clause that isn't defined in the library
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a hide combinator includes a
+  // name that isn't defined by the library being imported.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `dart:math` doesn't
+  // define the name `String`:
+  //
+  // ```dart
+  // import 'dart:math' hide [!String!], max;
+  //
+  // var x = min(0, 1);
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If a different name should be hidden, then correct the name. Otherwise,
+  // remove the name from the list:
+  //
+  // ```dart
+  // import 'dart:math' hide max;
+  //
+  // var x = min(0, 1);
+  // ```
   static const HintCode UNDEFINED_HIDDEN_NAME = HintCode(
       'UNDEFINED_HIDDEN_NAME',
       "The library '{0}' doesn't export a member with the hidden name '{1}'.",
       correction: "Try removing the name from the list of hidden members.");
 
   /**
-   * An undefined name shown in an import or export directive.
+   * Parameters:
+   * 0: the name of the library being imported
+   * 1: the name in the show clause that isn't defined in the library
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a show combinator includes a
+  // name that isn't defined by the library being imported.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `dart:math` doesn't
+  // define the name `String`:
+  //
+  // ```dart
+  // import 'dart:math' show min, [!String!];
+  //
+  // var x = min(0, 1);
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If a different name should be shown, then correct the name. Otherwise,
+  // remove the name from the list:
+  //
+  // ```dart
+  // import 'dart:math' show min;
+  //
+  // var x = min(0, 1);
+  // ```
   static const HintCode UNDEFINED_SHOWN_NAME = HintCode('UNDEFINED_SHOWN_NAME',
       "The library '{0}' doesn't export a member with the shown name '{1}'.",
       correction: "Try removing the name from the list of shown members.");
 
   /**
-   * Unnecessary cast.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the value being cast is already
+  // known to be of the type that it's being cast to.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `n` is already known to
+  // be an `int` as a result of the `is` test:
+  //
+  // ```dart
+  // void f(num n) {
+  //   if (n is int) {
+  //     ([!n as int!]).isEven;
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the unnecessary cast:
+  //
+  // ```dart
+  // void f(num n) {
+  //   if (n is int) {
+  //     n.isEven;
+  //   }
+  // }
+  // ```
   static const HintCode UNNECESSARY_CAST = HintCode(
       'UNNECESSARY_CAST', "Unnecessary cast.",
       correction: "Try removing the cast.");
@@ -2087,8 +2213,42 @@
       correction: "Try correcting the type check, or removing the type check.");
 
   /**
-   * Unused catch exception variables.
+   * Parameters:
+   * 0: the name of the exception variable
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a catch clause is found, and
+  // neither the exception parameter nor the optional stack trace parameter are
+  // used in the catch block.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `e` isn't referenced:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     int.parse(';');
+  //   } on FormatException catch ([!e!]) {
+  //     // ignored
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the unused catch clause:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     int.parse(';');
+  //   } on FormatException {
+  //     // ignored
+  //   }
+  // }
+  // ```
   static const HintCode UNUSED_CATCH_CLAUSE = HintCode(
       'UNUSED_CATCH_CLAUSE',
       "The exception variable '{0}' isn't used, so the 'catch' clause can be "
@@ -2099,8 +2259,43 @@
       correction: "Try removing the catch clause.");
 
   /**
-   * Unused catch stack trace variables.
+   * Parameters:
+   * 0: the name of the stack trace variable
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the stack trace parameter in a
+  // catch clause isn't referenced within the body of the catch block.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `stackTrace` isn't
+  // referenced:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     // ...
+  //   } catch (exception, [!stackTrace!]) {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the stack trace parameter, then add a reference to
+  // it. Otherwise, remove it:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     // ...
+  //   } catch (exception) {
+  //     // ...
+  //   }
+  // }
+  // ```
   static const HintCode UNUSED_CATCH_STACK = HintCode('UNUSED_CATCH_STACK',
       "The stack trace variable '{0}' isn't used and can be removed.",
       correction: "Try removing the stack trace variable, or using it.");
@@ -2115,7 +2310,7 @@
   // typedef, top level variable, top level function, or method is declared but
   // never referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // Assuming that no code in the library references `_C`, the following code
   // produces this diagnostic:
@@ -2143,7 +2338,7 @@
   // The analyzer produces this diagnostic when a private field is declared but
   // never read, even if it's written in one or more places.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `_x` isn't referenced
   // anywhere in the library:
@@ -2174,7 +2369,7 @@
   // none of the names that are imported are referenced within the importing
   // library.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because nothing defined in
   // `dart:async` is referenced in the library:
@@ -2196,9 +2391,50 @@
       correction: "Try removing the import directive.", hasPublishedDocs: true);
 
   /**
-   * Unused labels are labels that are never referenced in either a 'break' or
-   * 'continue' statement.
+   * Parameters:
+   * 0: the label that isn't used
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a label that isn't used is
+  // found.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the label `loop` isn't
+  // referenced anywhere in the method:
+  //
+  // ```dart
+  // void f(int limit) {
+  //   [!loop:!] for (int i = 0; i < limit; i++) {
+  //     print(i);
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the label isn't needed, then remove it:
+  //
+  // ```dart
+  // void f(int limit) {
+  //   for (int i = 0; i < limit; i++) {
+  //     print(i);
+  //   }
+  // }
+  // ```
+  //
+  // If the label is needed, then use it:
+  //
+  // ```dart
+  // void f(int limit) {
+  //   loop: for (int i = 0; i < limit; i++) {
+  //     print(i);
+  //     break loop;
+  //   }
+  // }
+  // ```
+  // TODO(brianwilkerson) Highlight the identifier without the colon.
   static const HintCode UNUSED_LABEL =
       HintCode('UNUSED_LABEL', "The label '{0}' isn't used.",
           correction: "Try removing the label, or "
@@ -2213,7 +2449,7 @@
   // The analyzer produces this diagnostic when a local variable is declared but
   // never read, even if it's written in one or more places.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the value of `count` is
   // never read:
@@ -2236,10 +2472,37 @@
       hasPublishedDocs: true);
 
   /**
-   * Unused shown names are names shown on imports which are never used.
+   * Parameters:
+   * 0: the name that is shown but not used
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a show combinator includes a
+  // name that isn't used within the library. Because it isn't referenced, the
+  // name can be removed.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the function `max`
+  // isn't used:
+  //
+  // ```dart
+  // import 'dart:math' show min, [!max!];
+  //
+  // var x = min(0, 1);
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Either use the name or remove it:
+  //
+  // ```dart
+  // import 'dart:math' show min;
+  //
+  // var x = min(0, 1);
+  // ```
   static const HintCode UNUSED_SHOWN_NAME = HintCode(
-      'UNUSED_SHOWN_NAME', "The name {0} is shown, but not used.",
+      'UNUSED_SHOWN_NAME', "The name {0} is shown, but isn’t used.",
       correction: "Try removing the name from the list of shown members.");
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 0ea992e..c3b76ba 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -215,7 +215,7 @@
   // The analyzer produces this diagnostic when an abstract declaration is
   // declared in an extension. Extensions can declare only concrete members.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the method `a` doesn't
   // have a body:
@@ -242,7 +242,7 @@
   // extensions aren't classes, and it isn't possible to create an instance of
   // an extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because there is a constructor
   // declaration in `E`:
@@ -268,7 +268,7 @@
   // found in an extension. It isn't valid to define an instance field because
   // extensions can only add behavior, not state.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `s` is an instance
   // field:
@@ -488,7 +488,7 @@
   // Extensions aren't classes and don't have subclasses, so the keyword serves
   // no purpose.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `i` is marked as being
   // covariant:
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 817a8ca..3540a44 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
+import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/super_context.dart';
 import 'package:analyzer/src/generated/variable_type_provider.dart';
@@ -54,6 +55,8 @@
   final ElementTypeProvider _elementTypeProvider;
   final InvocationInferenceHelper _inferenceHelper;
 
+  final MigratableAstInfoProvider _migratableAstInfoProvider;
+
   /// The invocation being resolved.
   MethodInvocationImpl _invocation;
 
@@ -62,7 +65,8 @@
 
   MethodInvocationResolver(
     this._resolver,
-    this._elementTypeProvider, {
+    this._elementTypeProvider,
+    this._migratableAstInfoProvider, {
     @required InvocationInferenceHelper inferenceHelper,
   })  : _typeType = _resolver.typeProvider.typeType,
         _inheritance = _resolver.inheritance,
@@ -142,7 +146,8 @@
     DartType receiverType = receiver.staticType;
     receiverType = _resolveTypeParameter(receiverType);
 
-    if (node.isNullAware && _typeSystem.isNonNullableByDefault) {
+    if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
+        _typeSystem.isNonNullableByDefault) {
       receiverType = _typeSystem.promoteToNonNull(receiverType);
     }
 
@@ -298,7 +303,8 @@
     if (!inferred) {
       DartType staticStaticType = _inferenceHelper.computeInvokeReturnType(
         node.staticInvokeType,
-        isNullAware: node.isNullAware,
+        isNullAware:
+            _migratableAstInfoProvider.isMethodInvocationNullAware(node),
       );
       _inferenceHelper.recordStaticType(node, staticStaticType);
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index bce5eb43..982e042 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -325,10 +325,12 @@
           node,
           element.typeParameters.length,
         );
-        return element.instantiate(
+        var type = element.instantiate(
           typeArguments: typeArguments,
           nullabilitySuffix: nullability,
         );
+        type = typeSystem.toLegacyType(type);
+        return type;
       } else if (element is NeverElementImpl) {
         _buildTypeArguments(node, 0);
         return element.instantiate(
@@ -358,13 +360,15 @@
         return _inferRedirectedConstructor(element);
       }
 
-      return element.instantiateToBounds(
+      return typeSystem.instantiateToBounds2(
+        classElement: element,
         nullabilitySuffix: nullability,
       );
     } else if (element is DynamicElementImpl) {
       return DynamicTypeImpl.instance;
     } else if (element is FunctionTypeAliasElement) {
-      return element.instantiateToBounds(
+      return typeSystem.instantiateToBounds2(
+        functionTypeAliasElement: element,
         nullabilitySuffix: nullability,
       );
     } else if (element is NeverElementImpl) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
index fb1d037..52817e6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -13,8 +13,8 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/collection_element_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
@@ -25,7 +25,7 @@
   final TypeSystemImpl _typeSystem;
   final TypeProviderImpl _typeProvider;
   final ErrorReporter _errorReporter;
-  final CollectionElementProvider _collectionElementProvider;
+  final MigratableAstInfoProvider _migratableAstInfoProvider;
 
   final bool _strictInference;
   final bool _uiAsCodeEnabled;
@@ -34,8 +34,8 @@
 
   factory TypedLiteralResolver(ResolverVisitor resolver, FeatureSet featureSet,
       TypeSystemImpl typeSystem, TypeProviderImpl typeProvider,
-      {CollectionElementProvider collectionElementProvider =
-          const CollectionElementProvider()}) {
+      {MigratableAstInfoProvider migratableAstInfoProvider =
+          const MigratableAstInfoProvider()}) {
     var library = resolver.definingLibrary as LibraryElementImpl;
     var analysisOptions = library.context.analysisOptions;
     var analysisOptionsImpl = analysisOptions as AnalysisOptionsImpl;
@@ -48,7 +48,7 @@
         featureSet.isEnabled(Feature.control_flow_collections) ||
             featureSet.isEnabled(Feature.spread_collections),
         featureSet.isEnabled(Feature.non_nullable),
-        collectionElementProvider);
+        migratableAstInfoProvider);
   }
 
   TypedLiteralResolver._(
@@ -59,7 +59,7 @@
       this._strictInference,
       this._uiAsCodeEnabled,
       this._isNonNullableByDefault,
-      this._collectionElementProvider);
+      this._migratableAstInfoProvider);
 
   DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
 
@@ -301,10 +301,10 @@
   }
 
   List<CollectionElement> _getListElements(ListLiteral node) =>
-      _collectionElementProvider.getListElements(node);
+      _migratableAstInfoProvider.getListElements(node);
 
   List<CollectionElement> _getSetOrMapElements(SetOrMapLiteral node) =>
-      _collectionElementProvider.getSetOrMapElements(node);
+      _migratableAstInfoProvider.getSetOrMapElements(node);
 
   _InferredCollectionElementTypeInformation _inferCollectionElementType(
       CollectionElement element) {
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index b3a9d12..cfd68d6 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -1450,9 +1450,21 @@
       return;
     }
     AstNode grandparent = parent?.parent;
-    Element element = grandparent is ConstructorName
-        ? grandparent.staticElement
-        : identifier.staticElement;
+
+    var element;
+    var name;
+    var node;
+
+    if (grandparent is ConstructorName) {
+      element = grandparent.staticElement;
+      name = grandparent.toSource();
+      node = grandparent;
+    } else {
+      element = identifier.staticElement;
+      name = identifier.name;
+      node = identifier;
+    }
+
     if (element == null || _inCurrentLibrary(element)) {
       return;
     }
@@ -1486,20 +1498,21 @@
     if (hasProtected) {
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
-          identifier,
-          [identifier.name, definingClass.source.uri]);
+          node,
+          [name, definingClass.source.uri]);
     }
     if (hasVisibleForTemplate) {
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
-          identifier,
-          [identifier.name, definingClass.source.uri]);
+          node,
+          [name, definingClass.source.uri]);
     }
+
     if (hasVisibleForTesting) {
       _errorReporter.reportErrorForNode(
           HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER,
-          identifier,
-          [identifier.name, definingClass.source.uri]);
+          node,
+          [name, definingClass.source.uri]);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 14da3a3..5439b11 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -76,7 +76,7 @@
   // The analyzer produces this diagnostic when the evaluation of a constant
   // expression would result in a `CastException`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the value of `x` is an
   // `int`, which can't be assigned to `y` because an `int` isn't a `String`:
@@ -146,7 +146,7 @@
   // referenced using `super`, but there is no concrete implementation of the
   // member in the superclass chain. Abstract members can't be invoked.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `B` doesn't inherit a
   // concrete implementation of `a`:
@@ -219,7 +219,7 @@
   // extended type that's more specific than the extended types of all of the
   // other extensions, making the reference to the member ambiguous.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because there's no way to
   // choose between the member in `E1` and the member in `E2`:
@@ -291,7 +291,7 @@
   // impossible for the analyzer to determine whether you are writing a map
   // literal or a set literal.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -351,7 +351,7 @@
   // a type that allows the analyzer to decide whether you were writing a map
   // literal or a set literal.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -494,7 +494,7 @@
   // The analyzer produces this diagnostic when the name of an extension is a
   // built-in identifier. Built-in identifiers can’t be used as extension names.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `mixin` is a built-in
   // identifier:
@@ -526,12 +526,30 @@
           correction: "Try choosing a different name for the prefix.");
 
   /**
-   * 12.30 Identifier Reference: It is a compile-time error to use a built-in
-   * identifier other than dynamic as a type annotation.
-   *
    * Parameters:
    * 0: the built-in identifier that is being used
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a built-in identifier is used
+  // where a type name is expected.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `import` can't be used
+  // as a type because it's a built-in identifier:
+  //
+  // ```dart
+  // [!import!]<int> x;
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Replace the built-in identifier with the name of a valid type:
+  //
+  // ```dart
+  // List<int> x;
+  // ```
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE =
       CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE',
           "The built-in identifier '{0}' can't be used as a type.",
@@ -787,11 +805,49 @@
               "removing the keyword 'const' from the constructor.");
 
   /**
-   * 7.6.3 Constant Constructors: It is a compile-time error if a constant
-   * constructor is declared by a class that has a non-final instance variable.
-   *
-   * The above refers to both locally declared and inherited instance variables.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constructor is marked as a
+  // const constructor, but the constructor is defined in a class that has at
+  // least one non-final instance field (either directly or by inheritance).
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the field `x` isn't
+  // final:
+  //
+  // ```dart
+  // class C {
+  //   int x;
+  //
+  //   const [!C!](this.x);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If it's possible to mark all of the fields as final, then do so:
+  //
+  // ```dart
+  // class C {
+  //   final int x;
+  //
+  //   const C(this.x);
+  // }
+  // ```
+  //
+  // If it isn't possible to mark all of the fields as final, then remove the
+  // keyword `const` from the constructor:
+  //
+  // ```dart
+  // class C {
+  //   int x;
+  //
+  //   C(this.x);
+  // }
+  // ```
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD =
       CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD',
           "Can't define a const constructor for a class with non-final fields.",
@@ -900,7 +956,7 @@
   // known to be a constant is assigned to a variable that's declared to be a
   // 'const' variable.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` isn't declared to
   // be `const`:
@@ -960,7 +1016,7 @@
   // The analyzer produces this diagnostic when an instance field is marked as
   // being const.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` is an instance
   // field:
@@ -1019,7 +1075,7 @@
   // The analyzer produces this diagnostic when a variable that is declared to
   // be a constant doesn't have an initializer.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `c` isn't initialized:
   //
@@ -1061,7 +1117,7 @@
   // operator in a constant list or set evaluates to something other than a list
   // or a set.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the value of `list1` is
   // `null`, which is neither a list nor a set:
@@ -1093,7 +1149,7 @@
   // The analyzer produces this diagnostic when the expression of a spread
   // operator in a constant map evaluates to something other than a map.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the value of `map1` is
   // `null`, which isn't a map:
@@ -1124,7 +1180,7 @@
   // The analyzer produces this diagnostic when the keyword `const` is used to
   // invoke a constructor that isn't marked with `const`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the constructor in `A`
   // isn't a const constructor:
@@ -1173,7 +1229,7 @@
   // The analyzer produces this diagnostic when a const constructor is invoked
   // with an argument that isn't a constant expression.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `i` isn't a constant:
   //
@@ -1303,7 +1359,7 @@
   // a value for the parameter is always provided at the call sites, so the
   // default value can never be used.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code generates this diagnostic:
   //
@@ -1345,6 +1401,77 @@
   /**
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a class declares more than one
+  // unnamed constructor or when it declares more than one constructor with the
+  // same name.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because there are two
+  // declarations for the unnamed constructor:
+  //
+  // ```dart
+  // class C {
+  //   C();
+  //
+  //   [!C!]();
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because there are two
+  // declarations for the constructor named `m`:
+  //
+  // ```dart
+  // class C {
+  //   C.m();
+  //
+  //   [!C.m!]();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If there are multiple unnamed constructors and all of the constructors are
+  // needed, then give all of them, or all except one of them, a name:
+  //
+  // ```dart
+  // class C {
+  //   C();
+  //
+  //   C.n();
+  // }
+  // ```
+  //
+  // If there are multiple unnamed constructors and all except one of them are
+  // unneeded, then remove the constructors that aren't needed:
+  //
+  // ```dart
+  // class C {
+  //   C();
+  // }
+  // ```
+  //
+  // If there are multiple named constructors and all of the constructors are
+  // needed, then rename all except one of them:
+  //
+  // ```dart
+  // class C {
+  //   C.m();
+  //
+  //   C.n();
+  // }
+  // ```
+  //
+  // If there are multiple named constructors and all except one of them are
+  // unneeded, then remove the constructorsthat aren't needed:
+  //
+  // ```dart
+  // class C {
+  //   C.m();
+  // }
+  // ```
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT =
       CompileTimeErrorCodeWithUniqueName(
           'DUPLICATE_CONSTRUCTOR',
@@ -1372,7 +1499,7 @@
   // The analyzer produces this diagnostic when a name is declared, and there is
   // a previous declaration with the same name in the same scope.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `x` is
   // declared twice:
@@ -1409,13 +1536,54 @@
           "Try removing all but one of the duplicated part directives.");
 
   /**
-   * 12.14.2 Binding Actuals to Formals: It is a compile-time error if
-   * <i>q<sub>i</sub> = q<sub>j</sub></i> for any <i>i != j</i> [where
-   * <i>q<sub>i</sub></i> is the label for a named argument].
-   *
    * Parameters:
    * 0: the name of the parameter that was duplicated
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an invocation has two or more
+  // named arguments that have the same name.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because there are two arguments
+  // with the name `a`:
+  //
+  // ```dart
+  // void f(C c) {
+  //   c.m(a: 0, [!a!]: 1);
+  // }
+  //
+  // class C {
+  //   void m({int a, int b}) {}
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If one of the arguments should have a different name, then change the name:
+  //
+  // ```dart
+  // void f(C c) {
+  //   c.m(a: 0, b: 1);
+  // }
+  //
+  // class C {
+  //   void m({int a, int b}) {}
+  // }
+  // ```
+  //
+  // If one of the arguments is wrong, then remove it:
+  //
+  // ```dart
+  // void f(C c) {
+  //   c.m(a: 1);
+  // }
+  //
+  // class C {
+  //   void m({int a, int b}) {}
+  // }
+  // ```
   static const CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT =
       CompileTimeErrorCode('DUPLICATE_NAMED_ARGUMENT',
           "The argument for the named parameter '{0}' was already specified.",
@@ -1432,7 +1600,7 @@
   // literal have the same value. The set can only contain each value once,
   // which means that one of the values is unnecessary.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the string `'a'` is
   // specified twice:
@@ -1467,7 +1635,7 @@
   // second value would overwrite the first value, which makes having both pairs
   // pointless.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the key `1` is used
   // twice:
@@ -1545,7 +1713,7 @@
   // The analyzer produces this diagnostic when the analyzer finds an
   // expression, rather than a map entry, in what appears to be a map literal.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code generates this diagnostic:
   //
@@ -1626,7 +1794,7 @@
   // The analyzer produces this diagnostic when an extends clause contains a
   // name that is declared to be something other than a class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` is declared to be a
   // function:
@@ -1677,7 +1845,7 @@
   // representing the type of the class. Extensions, on the other hand, don't
   // define a type and can't be used as a type literal.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `E` is an extension:
   //
@@ -1720,7 +1888,7 @@
   // because it's unclear which member is being referenced by an unqualified use
   // of the name within the body of the extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `a` is being
   // used for two different members:
@@ -1761,7 +1929,7 @@
   // `Object`. Such a member can never be used because the member in `Object` is
   // always found first.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `toString` is defined
   // by `Object`:
@@ -1800,7 +1968,7 @@
   // classes, the static members of an extension should be accessed using the
   // name of the extension, not an extension override.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` is static:
   //
@@ -1845,7 +2013,7 @@
   // The analyzer produces this diagnostic when the argument to an extension
   // override isn't assignable to the type being extended by the extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `3` isn't a `String`:
   //
@@ -1894,7 +2062,7 @@
   // `e..m` is the value of the target `e`, but extension overrides are not
   // expressions and don't have a value.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `E(3)` isn't an
   // expression:
@@ -1941,7 +2109,7 @@
   // extension override syntax doesn't have any runtime semantics; it only
   // controls which member is selected at compile time.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `E(i)` isn't an
   // expression:
@@ -1998,7 +2166,7 @@
   // The analyzer produces this diagnostic when a method or function invocation
   // has more positional arguments than the method or function allows.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` defines 2
   // parameters but is invoked with 3 arguments:
@@ -2037,7 +2205,7 @@
   // has more positional arguments than the method or function allows, but the
   // method or function defines named parameters.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` defines 2
   // positional parameters but has a named parameter that could be used for the
@@ -2241,7 +2409,7 @@
   // clause of a class or mixin declaration is defined to be something other
   // than a class or mixin.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is a variable
   // rather than a class or mixin:
@@ -2281,7 +2449,7 @@
   // The analyzer produces this diagnostic when a single class is specified more
   // than once in an implements clause.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `A` is in the list
   // twice:
@@ -2324,7 +2492,7 @@
   // The analyzer produces this diagnostic when it finds a reference to an
   // instance member in a constructor's initializer list.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `defaultX` is an
   // instance member:
@@ -2457,7 +2625,7 @@
   // Constructors can't initialize fields that aren't declared and fields that
   // are inherited from superclasses.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the initializer is
   // initializing `x`, but `x` isn't a field in the class:
@@ -2530,7 +2698,7 @@
   // initialized. Constructors can't initialize fields that aren't declared and
   // fields that are inherited from superclasses.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the field `x` isn't
   // defined:
@@ -2626,7 +2794,7 @@
   // factory constructor, the instance isn't created before executing the body,
   // so `this` can't be used to reference it.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` isn't in scope in
   // the factory constructor:
@@ -2667,7 +2835,7 @@
   // The analyzer produces this diagnostic when a static method contains an
   // unqualified reference to an instance member.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the instance field `x`
   // is being referenced in a static method:
@@ -2814,7 +2982,7 @@
   // the value of `this` within the extension method, so there must be one
   // argument.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because there are no arguments:
   //
@@ -2870,7 +3038,7 @@
   // The analyzer produces this diagnostic when the name of a factory
   // constructor isn't the same as the name of the surrounding class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name of the factory
   // constructor (`A`) isn't the same as the surrounding class (`C`):
@@ -2971,7 +3139,7 @@
   // * The return type of the override is assignable to the return type of the
   //   overridden member.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the type of the
   // parameter `s` (`String`) isn't assignable to the type of the parameter `i`
@@ -3029,7 +3197,7 @@
   // only defined in the context of an instance method or a generative
   // constructor.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `v` is a top-level
   // variable:
@@ -3107,20 +3275,26 @@
       ParserErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION;
 
   /**
-   * 14.2 Exports: It is a compile-time error if the compilation unit found at
-   * the specified URI is not a library declaration.
-   *
-   * 14.1 Imports: It is a compile-time error if the compilation unit found at
-   * the specified URI is not a library declaration.
-   *
-   * 14.3 Parts: It is a compile time error if the contents of the URI are not a
-   * valid part declaration.
-   *
    * Parameters:
    * 0: the URI that is invalid
-   *
-   * See [URI_DOES_NOT_EXIST].
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a URI in a directive doesn't
+  // conform to the syntax of a valid URI.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `'#'` isn't a valid
+  // URI:
+  //
+  // ```dart
+  // import [!'#'!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Replace the invalid URI with a valid URI.
   static const CompileTimeErrorCode INVALID_URI =
       CompileTimeErrorCode('INVALID_URI', "Invalid URI syntax: '{0}'.");
 
@@ -3133,7 +3307,7 @@
   // The analyzer produces this diagnostic when an extension override is used to
   // invoke a function but the extension doesn't declare a `call` method.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the extension `E`
   // doesn't define a `call` method:
@@ -3237,7 +3411,7 @@
   // The analyzer produces this diagnostic when a map entry (a key/value pair)
   // is found in a set literal.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the literal has a map
   // entry even though it's a set literal:
@@ -3327,7 +3501,7 @@
   // parameter to have a value of null, then the implicit default value is not
   // valid.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code generates this diagnostic:
   //
@@ -3538,7 +3712,7 @@
   // The analyzer produces this diagnostic when a name in a mixin clause is
   // defined to be something other than a mixin or a class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `F` is defined to be a
   // function type:
@@ -3590,7 +3764,7 @@
   // The analyzer produces this diagnostic when a type following the `on`
   // keyword in a mixin declaration is neither a class nor a mixin.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `F` is neither a class
   // nor a mixin:
@@ -3641,11 +3815,42 @@
           correction: "Try removing all but one of the 'super' initializers.");
 
   /**
-   * 15 Metadata: Metadata consists of a series of annotations, each of which
-   * begin with the character @, followed by a constant expression that must be
-   * either a reference to a compile-time constant variable, or a call to a
-   * constant constructor.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an annotation consists of a
+  // single identifier, but that identifier is the name of a class rather than a
+  // variable. To create an instance of the class, the identifier must be
+  // followed by an argument list.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `C` is a class, and a
+  // class can't be used as an annotation without invoking a `const` constructor
+  // from the class:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  // }
+  //
+  // [!@C!]
+  // var x;
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add the missing argument list:
+  //
+  // ```dart
+  // class C {
+  //   const C();
+  // }
+  //
+  // @C()
+  // var x;
+  // ```
   static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS =
       CompileTimeErrorCode('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS',
           "Annotation creation must have arguments.",
@@ -3698,7 +3903,7 @@
   // The analyzer produces this diagnostic when the expression in a case clause
   // isn't a constant expression.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `j` isn't a constant:
   //
@@ -3761,7 +3966,7 @@
   // named or positional, has a default value that isn't a compile-time
   // constant.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -3822,7 +4027,7 @@
   // explicitly (because it's prefixed by the `const` keyword) or implicitly
   // (because it appears in a [constant context](#constant-context)).
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` isn't a constant,
   // even though it appears in an implicitly constant list literal:
@@ -3881,7 +4086,7 @@
   // The analyzer produces this diagnostic when a key in a constant map literal
   // isn't a constant value.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic beause `a` isn't a constant:
   //
@@ -3934,7 +4139,7 @@
   // The analyzer produces this diagnostic when a value in a constant map
   // literal isn't a constant value.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `a` isn't a constant:
   //
@@ -3973,7 +4178,7 @@
   // The analyzer produces this diagnostic when an if element or a spread
   // element in a constant map isn't a constant element.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because it is attempting to
   // spread a non-constant map:
@@ -4050,7 +4255,7 @@
   // The analyzer produces this diagnostic when a constant set literal contains
   // an element that isn't a compile-time constant.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `i` isn't a constant:
   //
@@ -4140,7 +4345,7 @@
   // has fewer positional arguments than the number of required positional
   // parameters.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` declares two
   // required parameters, but only one argument is provided:
@@ -4230,7 +4435,7 @@
   // expression of a spread element that appears in either a list literal or a
   // set literal doesn't implement the type `Iterable`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code generates this diagnostic:
   //
@@ -4262,7 +4467,7 @@
   // expression of a spread element that appears in a map literal doesn't
   // implement the type `Map`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `l` isn't a `Map`:
   //
@@ -4317,7 +4522,7 @@
   // reason to allow the nullability to be specified when used in the extends
   // clause.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code generates this diagnostic:
   //
@@ -4403,7 +4608,7 @@
   // The analyzer produces this diagnostic when a part directive is found and
   // the referenced file doesn't have a part-of directive.
   //
-  // #### Example
+  // #### Examples
   //
   // Given a file (`a.dart`) containing:
   //
@@ -4651,7 +4856,7 @@
   // produces this diagnostic when the redirect is to something other than a
   // constructor.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` is a function:
   //
@@ -4713,7 +4918,7 @@
   // The analyzer also produces a context message that indicates where the
   // declaration is located.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `i` is used before it
   // is declared:
@@ -4822,7 +5027,7 @@
   // extension uses the `super` keyword . Extensions aren't classes and don't
   // have superclasses, so the `super` keyword serves no purpose.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `super` can't be used
   // in an extension:
@@ -4849,14 +5054,27 @@
       hasPublishedDocs: true);
 
   /**
-   * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
-   * <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
-   * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a
-   * compile-time error if a super method invocation occurs in a top-level
-   * function or variable initializer, in an instance variable initializer or
-   * initializer list, in class Object, in a factory constructor, or in a static
-   * method or variable initializer.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the keyword `super` is used
+  // outside of a instance method.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `super` is used in a
+  // top-level function:
+  //
+  // ```dart
+  // void f() {
+  //   [!super!].f();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Rewrite the code to not use `super`.
   static const CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT =
       CompileTimeErrorCode('SUPER_IN_INVALID_CONTEXT',
           "Invalid context for 'super' invocation.");
@@ -4889,7 +5107,7 @@
   // The analyzer produces this diagnostic when a type argument isn't the same
   // as or a subclass of the bounds of the corresponding type parameter.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `String` isn't a
   // subclass of `num`:
@@ -4937,7 +5155,7 @@
   // The analyzer produces this diagnostic when a name that isn't defined is
   // used as an annotation.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `undefined`
   // isn't defined:
@@ -4983,7 +5201,7 @@
   // appears to be the name of a class but either isn't defined or isn't visible
   // in the scope in which it's being referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `Piont` isn't defined:
   //
@@ -5019,6 +5237,64 @@
    * 0: the name of the superclass that does not define the invoked constructor
    * 1: the name of the constructor being invoked
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a superclass constructor is
+  // invoked in the initializer list of a constructor, but the superclass
+  // doesn't define the constructor being invoked.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `A` doesn't have an
+  // unnamed constructor:
+  //
+  // ```dart
+  // class A {
+  //   A.n();
+  // }
+  // class B extends A {
+  //   B() : [!super()!];
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because `A` doesn't have a
+  // constructor named `m`:
+  //
+  // ```dart
+  // class A {
+  //   A.n();
+  // }
+  // class B extends A {
+  //   B() : [!super.m()!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the superclass defines a constructor that should be invoked, then change
+  // the constructor being invoked:
+  //
+  // ```dart
+  // class A {
+  //   A.n();
+  // }
+  // class B extends A {
+  //   B() : super.n();
+  // }
+  // ```
+  //
+  // If the superclass doesn't define an appropriate constructor, then define
+  // the constructor being invoked:
+  //
+  // ```dart
+  // class A {
+  //   A.m();
+  //   A.n();
+  // }
+  // class B extends A {
+  //   B() : super.m();
+  // }
+  // ```
   static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER =
       CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
           "The class '{0}' doesn't have a constructor named '{1}'.",
@@ -5050,7 +5326,7 @@
   // The analyzer also produces this diagnostic when a static getter is
   // referenced but isn't defined by the specified extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the extension `E`
   // doesn't declare an instance getter named `b`:
@@ -5151,7 +5427,7 @@
   // The analyzer also produces this diagnostic when a static method is
   // referenced but isn't defined by the specified extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the extension `E`
   // doesn't declare an instance method named `b`:
@@ -5262,7 +5538,7 @@
   // The analyzer also produces this diagnostic when a static setter is
   // referenced but isn't defined by the specified extension.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the extension `E`
   // doesn't declare an instance setter named `b`:
@@ -5363,7 +5639,7 @@
   // has a named argument, but the method or function being invoked doesn't
   // define a parameter with the same name.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` doesn't declare a
   // named parameter named `a`:
@@ -5439,7 +5715,7 @@
   // the name is the same as a static member of the extended type or one of its
   // superclasses.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` is a static member
   // of the extended type `C`:
@@ -5507,7 +5783,7 @@
   // The analyzer produces this diagnostic when an import, export, or part
   // directive is found where the URI refers to a file that doesn't exist.
   //
-  // #### Example
+  // #### Examples
   //
   // If the file `lib.dart` doesn't exist, the following code produces this
   // diagnostic:
@@ -5544,7 +5820,7 @@
   // - `.pbjson.dart`
   // - `.template.dart`
   //
-  // #### Example
+  // #### Examples
   //
   // If the file `lib.g.dart` doesn't exist, the following code produces this
   // diagnostic:
@@ -5593,7 +5869,7 @@
   // The analyzer produces this diagnostic when a declaration of an operator has
   // the wrong number of parameters.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the operator `+` must
   // have a single parameter corresponding to the right operand:
@@ -5636,12 +5912,46 @@
           "Operator '-' should declare 0 or 1 parameter, but {0} found.");
 
   /**
-   * 7.3 Setters: It is a compile-time error if a setter's formal parameter list
-   * does not include exactly one required formal parameter <i>p</i>.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a setter is found that doesn't
+  // declare exactly one required positional parameter.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the setter `s` declares
+  // two required parameters:
+  //
+  // ```dart
+  // class C {
+  //   set [!s!](int x, int y) {}
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the setter `s` declares
+  // one optional parameter:
+  //
+  // ```dart
+  // class C {
+  //   set [!s!]([int x]) {}
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Change the declaration so that there's exactly one required positional
+  // parameter:
+  //
+  // ```dart
+  // class C {
+  //   set s(int x) {}
+  // }
+  // ```
   static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER =
       CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER',
-          "Setters should declare exactly one required parameter.");
+          "Setters must declare exactly one required positional parameter.");
 
   /**
    * Let `C` be a generic class that declares a formal type parameter `X`, and
@@ -5850,16 +6160,44 @@
               "removing the modifier 'sync*' from the function body.");
 
   /**
-   * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
-   * not have an accessible (3.2) instance member named <i>m</i>.
-   *
    * Parameters:
    * 0: the name of the static member
    * 1: the kind of the static member (field, getter, setter, or method)
    * 2: the name of the defining class
-   *
-   * See [UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER].
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an access operator is used to
+  // access a static member through an instance of the class.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `zero` is a static
+  // field, but it’s being accessed as if it were an instance field:
+  //
+  // ```dart
+  // void f(C c) {
+  //   c.[!zero!];
+  // }
+  //
+  // class C {
+  //   static int zero = 0;
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Use the class to access the static member:
+  //
+  // ```dart
+  // void f(C c) {
+  //   C.zero;
+  // }
+  //
+  // class C {
+  //   static int zero = 0;
+  // }
+  // ```
   static const StaticTypeWarningCode INSTANCE_ACCESS_TO_STATIC_MEMBER =
       StaticTypeWarningCode('INSTANCE_ACCESS_TO_STATIC_MEMBER',
           "Static {1} '{0}' can't be accessed through an instance.",
@@ -5876,7 +6214,7 @@
   // that is assigned to a variable isn't assignable to the type of the
   // variable.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the type of the
   // initializer (`int`) isn't assignable to the type of the variable
@@ -5925,7 +6263,7 @@
   // but the name of the function being invoked is defined to be something other
   // than a function.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `Binary` is the name of
   // a function type, not a function:
@@ -5960,7 +6298,7 @@
   // but the name being referenced isn't the name of a function, or when the
   // expression computing the function doesn't compute a function.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` isn't a function:
   //
@@ -6010,7 +6348,7 @@
   // The analyzer produces this diagnostic when a condition, such as an `if` or
   // `while` loop, doesn't have the static type `bool`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` has the static type
   // `int`:
@@ -6046,7 +6384,7 @@
   // The analyzer produces this diagnostic when the first expression in an
   // assert has a type other than `bool`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the type of `p` is
   // `int`, but a `bool` is required:
@@ -6079,7 +6417,7 @@
   // The analyzer produces this diagnostic when the operand of the unary
   // negation operator (`!`) doesn't have the type `bool`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is an `int` when it
   // must be a `bool`:
@@ -6111,7 +6449,7 @@
   // The analyzer produces this diagnostic when one of the operands of either
   // the `&&` or `||` operator doesn't have the type `bool`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `a` isn't a Boolean
   // value:
@@ -6142,7 +6480,7 @@
   // The analyzer produces this diagnostic when an identifier that isn't a type
   // is used as a type argument.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is a variable, not
   // a type:
@@ -6194,7 +6532,7 @@
   // expression isn't assignable to the return type that the closure is required
   // to have.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` is defined to be a
   // function that returns a `String`, but the closure assigned to it returns an
@@ -6229,7 +6567,7 @@
   // The analyzer produces this diagnostic when a method or function returns a
   // value whose type isn't assignable to the declared return type.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` has a return type
   // of `String` but is returning an `int`:
@@ -6315,7 +6653,7 @@
   // appears to be the name of a function but either isn't defined or isn't
   // visible in the scope in which it's being referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `emty` isn't
   // defined:
@@ -6363,7 +6701,7 @@
   // appears to be the name of a getter but either isn't defined or isn't
   // visible in the scope in which it's being referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `String` has no member
   // named `len`:
@@ -6402,7 +6740,7 @@
   // appears to be the name of a method but either isn't defined or isn't
   // visible in the scope in which it's being referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the identifier
   // `removeMiddle` isn't defined:
@@ -6437,7 +6775,7 @@
   // The analyzer produces this diagnostic when a user-definable operator is
   // invoked on an object for which the operator isn't defined.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the class `C` doesn't
   // define the operator `+`:
@@ -6474,7 +6812,7 @@
   // where the prefix is valid, but the identifier isn't declared in any of the
   // libraries imported using that prefix.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `dart:core` doesn't
   // define anything named `a`:
@@ -6515,7 +6853,7 @@
   // appears to be the name of a setter but either isn't defined or isn't
   // visible in the scope in which the identifier is being referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because there isn't a setter
   // named `z`:
@@ -6576,7 +6914,7 @@
   // referenced using `super`, but there’s no method with that name in the
   // superclass chain.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `Object` doesn't define
   // a member named `n`:
@@ -6678,7 +7016,7 @@
   // is used and type arguments are provided, but the number of type arguments
   // isn't the same as the number of type parameters.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `C` has one type
   // parameter but two type arguments are provided:
@@ -6773,7 +7111,7 @@
   // The analyzer produces this diagnostic when the expression following `in` in
   // a for-in loop has a type that isn't a subclass of `Iterable`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` is a `Map`, and
   // `Map` isn't a subclass of `Iterable`:
@@ -6868,7 +7206,7 @@
   // The analyzer produces this diagnostic when a name is referenced that is
   // declared in two or more imported libraries.
   //
-  // #### Example
+  // #### Examples
   //
   // Given a library (`a.dart`) that defines a class (`C` in this example):
   //
@@ -6942,7 +7280,7 @@
   // The analyzer produces this diagnostic when the static type of an argument
   // can't be assigned to the static type of the corresponding parameter.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because a `num` can't be
   // assigned to a `String`:
@@ -7015,7 +7353,7 @@
   // setter, but there's no setter because the field with the same name was
   // declared to be `final` or `const`.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `v` is final:
   //
@@ -7049,13 +7387,41 @@
       correction: "Try finding a different setter, or making '{0}' non-final.");
 
   /**
-   * 5 Variables: Attempting to assign to a final variable elsewhere will cause
-   * a NoSuchMethodError to be thrown, because no setter is defined for it. The
-   * assignment will also give rise to a static warning for the same reason.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a local variable that was
+  // declared to be final is assigned after it was initialized.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `x` is final, so it
+  // can't have a value assigned to it after it was initialized:
+  //
+  // ```dart
+  // void f() {
+  //   final x = 0;
+  //   [!x!] = 3;
+  //   print(x);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the keyword `final`, and replace it with `var` if there's no type
+  // annotation:
+  //
+  // ```dart
+  // void f() {
+  //   var x = 0;
+  //   x = 3;
+  //   print(x);
+  // }
+  // ```
   static const StaticWarningCode ASSIGNMENT_TO_FINAL_LOCAL = StaticWarningCode(
       'ASSIGNMENT_TO_FINAL_LOCAL',
-      "'{0}', a final variable, can only be set once.",
+      "The final variable '{0}' can only be set once.",
       correction: "Try making '{0}' non-final.");
 
   /**
@@ -7067,7 +7433,7 @@
   // found; there is no setter defined for the type; but there is a getter
   // defined with the same name.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because there is no setter
   // named `x` in `C`, but there is a getter named `x`:
@@ -7131,10 +7497,31 @@
       'ASSIGNMENT_TO_FUNCTION', "Functions can't be assigned a value.");
 
   /**
-   * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>
-   * It is a static type warning if <i>T</i> does not have an accessible
-   * instance setter named <i>v=</i>.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the target of an assignment is a
+  // method.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `f` can't be assigned a
+  // value because it's a method:
+  //
+  // ```dart
+  // class C {
+  //   void f() {}
+  //
+  //   void g() {
+  //     [!f!] = null;
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Rewrite the code so that there isn't an assignment to a method.
   static const StaticWarningCode ASSIGNMENT_TO_METHOD = StaticWarningCode(
       'ASSIGNMENT_TO_METHOD', "Methods can't be assigned a value.");
 
@@ -7149,14 +7536,49 @@
       'ASSIGNMENT_TO_TYPE', "Types can't be assigned a value.");
 
   /**
-   * 13.9 Switch: It is a static warning if the last statement of the statement
-   * sequence <i>s<sub>k</sub></i> is not a break, continue, rethrow, return
-   * or throw statement.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the last statement in a case
+  // block isn't one of the required terminators: `break`, `continue`,
+  // `rethrow`, `return`, or `throw`.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the case block ends
+  // with an assignment:
+  //
+  // ```dart
+  // void f(int x) {
+  //   switch (x) {
+  //     [!case!] 0:
+  //       x += 2;
+  //     default:
+  //       x += 1;
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add one of the required terminators:
+  //
+  // ```dart
+  // void f(int x) {
+  //   switch (x) {
+  //     case 0:
+  //       x += 2;
+  //       break;
+  //     default:
+  //       x += 1;
+  //   }
+  // }
+  // ```
   static const StaticWarningCode CASE_BLOCK_NOT_TERMINATED = StaticWarningCode(
       'CASE_BLOCK_NOT_TERMINATED',
       "The last statement of the 'case' should be 'break', 'continue', "
-          "'rethrow', 'return' or 'throw'.",
+          "'rethrow', 'return', or 'throw'.",
       correction: "Try adding one of the required statements.");
 
   /**
@@ -7167,7 +7589,7 @@
   // The analyzer produces this diagnostic when the name following the `as` in a
   // cast expression is defined to be something other than a type.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is a variable, not
   // a type:
@@ -7203,7 +7625,7 @@
   // found that doesn't have a concrete implementation. Concrete classes aren't
   // allowed to contain abstract members.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `m` is an abstract
   // method but `C` isn't an abstract class:
@@ -7353,7 +7775,7 @@
   // The analyzer produces this diagnostic when a final field or variable isn't
   // initialized.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` doesn't have an
   // initializer:
@@ -7410,7 +7832,7 @@
   // initialized when the instance is created, either by the field's initializer
   // or by the constructor.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic:
   //
@@ -7550,7 +7972,7 @@
   // though you can't create an instance of an abstract class, abstract classes
   // can declare constructors that can be invoked by subclasses.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `C` is an abstract
   // class:
@@ -7628,7 +8050,7 @@
   // The analyzer produces this diagnostic when the type of an element in a list
   // literal isn't assignable to the element type of the list.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `2.5` is a double, and
   // the list can hold only integers:
@@ -7673,7 +8095,7 @@
   // The analyzer produces this diagnostic when a key of a key-value pair in a
   // map literal has a type that isn't assignable to the key type of the map.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `2` is an `int`, but
   // the keys of the map are required to be `String`s:
@@ -7713,7 +8135,7 @@
   // map literal has a type that isn't assignable to the the value type of the
   // map.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `2` is an `int`, but/
   // the values of the map are required to be `String`s:
@@ -7772,7 +8194,7 @@
   // Note that `null` is always a possible value for an enum and therefore also
   // must be handled.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the enum constant `e2`
   // isn't handled:
@@ -7880,7 +8302,7 @@
   // invoked on a class that defines named constructors but the class doesn’t
   // have an unnamed constructor.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `A` doesn't define an
   // unnamed constructor:
@@ -7968,7 +8390,7 @@
   // more abstract members, and doesn't provide or inherit an implementation for
   // at least one of those abstract members.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the class `B` doesn't
   // have a concrete implementation of `m`:
@@ -8063,15 +8485,42 @@
           hasPublishedDocs: true);
 
   /**
-   * 13.11 Try: An on-catch clause of the form <i>on T catch (p<sub>1</sub>,
-   * p<sub>2</sub>) s</i> or <i>on T s</i> matches an object <i>o</i> if the
-   * type of <i>o</i> is a subtype of <i>T</i>. It is a static warning if
-   * <i>T</i> does not denote a type available in the lexical scope of the
-   * catch clause.
-   *
    * Parameters:
    * 0: the name of the non-type element
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the identifier following the
+  // `on` in a catch clause is defined to be something other than a type.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `f` is a function, not
+  // a type:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     // ...
+  //   } on [!f!] {
+  //     // ...
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Change the name to the type of object that should be caught:
+  //
+  // ```dart
+  // void f() {
+  //   try {
+  //     // ...
+  //   } on FormatException {
+  //     // ...
+  //   }
+  // }
+  // ```
   static const StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = StaticWarningCode(
       'NON_TYPE_IN_CATCH_CLAUSE',
       "The name '{0}' isn't a type and can't be used in an on-catch "
@@ -8106,7 +8555,7 @@
   // The analyzer produces this diagnostic when a name is used as a type but
   // declared to be something other than a type.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` is a function:
   //
@@ -8143,38 +8592,144 @@
           "the library in the part's part-of directive.");
 
   /**
-   * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
-   * is not a subtype of the type of <i>k</i>.
-   *
    * Parameters:
    * 0: the name of the redirected constructor
    * 1: the name of the redirecting constructor
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a factory constructor attempts
+  // to redirect to another constructor, but the two have incompatible
+  // parameters. The parameters are compatible if all of the parameters of the
+  // redirecting constructor can be passed to the other constructor and if the
+  // other constructor doesn't require any parameters that aren't declared by
+  // the redirecting constructor.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the constructor for `A`
+  // doesn't declare a parameter that the constructor for `B` requires:
+  //
+  // ```dart
+  // abstract class A {
+  //   factory A() = [!B!];
+  // }
+  //
+  // class B implements A {
+  //   B(int x);
+  //   B.zero();
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the constructor for `A`
+  // declares a named parameter (`y`) that the constructor for `B` doesn't
+  // allow:
+  //
+  // ```dart
+  // abstract class A {
+  //   factory A(int x, {int y}) = [!B!];
+  // }
+  //
+  // class B implements A {
+  //   B(int x);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If there's a different constructor that is compatible with the redirecting
+  // constructor, then redirect to that constructor:
+  //
+  // ```dart
+  // abstract class A {
+  //   factory A() = B.zero;
+  // }
+  //
+  // class B implements A {
+  //   B(int x);
+  //   B.zero();
+  // }
+  // ```
+  //
+  // Otherwise, update the redirecting constructor to be compatible:
+  //
+  // ```dart
+  // abstract class A {
+  //   factory A(int x) = B;
+  // }
+  //
+  // class B implements A {
+  //   B(int x);
+  // }
+  // ```
   static const StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE =
       StaticWarningCode(
           'REDIRECT_TO_INVALID_FUNCTION_TYPE',
           "The redirected constructor '{0}' has incompatible parameters with "
               "'{1}'.",
-          correction: "Try redirecting to a different constructor, or directly "
-              "invoking the desired constructor rather than redirecting to "
-              "it.");
+          correction: "Try redirecting to a different constructor.");
 
   /**
-   * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
-   * is not a subtype of the type of <i>k</i>.
-   *
    * Parameters:
    * 0: the name of the redirected constructor's return type
    * 1: the name of the redirecting constructor's return type
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a factory constructor redirects
+  // to a constructor whose return type isn't a subtype of the type that the
+  // factory constructor is declared to produce.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because `A` isn't a subclass
+  // of `C`, which means that the value returned by the constructor `A()`
+  // couldn't be returned from the constructor `C()`:
+  //
+  // ```dart
+  // class A {}
+  //
+  // class B implements C {}
+  //
+  // class C {
+  //   factory C() = [!A!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the factory constructor is redirecting to a constructor in the wrong
+  // class, then update the factory constructor to redirect to the correct
+  // constructor:
+  //
+  // ```dart
+  // class A {}
+  //
+  // class B implements C {}
+  //
+  // class C {
+  //   factory C() = B;
+  // }
+  // ```
+  //
+  // If the class defining the constructor being redirected to is the class that
+  // should be returned, then make it a subtype of the factory's return type:
+  //
+  // ```dart
+  // class A implements C {}
+  //
+  // class B implements C {}
+  //
+  // class C {
+  //   factory C() = A;
+  // }
+  // ```
   static const StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE =
       StaticWarningCode(
           'REDIRECT_TO_INVALID_RETURN_TYPE',
           "The return type '{0}' of the redirected constructor isn't "
               "assignable to '{1}'.",
-          correction: "Try redirecting to a different constructor, or directly "
-              "invoking the desired constructor rather than redirecting to "
-              "it.");
+          correction: "Try redirecting to a different constructor.");
 
   @Deprecated('Use CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR')
   static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR =
@@ -8185,14 +8740,35 @@
       CompileTimeErrorCode.REDIRECT_TO_NON_CLASS;
 
   /**
-   * 13.12 Return: Let <i>f</i> be the function immediately enclosing a return
-   * statement of the form <i>return;</i> It is a static warning if both of the
-   * following conditions hold:
-   * * <i>f</i> is not a generative constructor.
-   * * The return type of <i>f</i> may not be assigned to void.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when it finds a return statement
+  // without an expression in a function that declares a return type.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the function `f` is
+  // expected to return an `int`, but no value is being returned:
+  //
+  // ```dart
+  // int f() {
+  //   [!return!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Add an expression that computes the value to be returned:
+  //
+  // ```dart
+  // int f() {
+  //   return 0;
+  // }
+  // ```
   static const StaticWarningCode RETURN_WITHOUT_VALUE = StaticWarningCode(
-      'RETURN_WITHOUT_VALUE', "Missing return value after 'return'.");
+      'RETURN_WITHOUT_VALUE', "The  return value is missing after 'return'.");
 
   /**
    * Parameters:
@@ -8213,7 +8789,7 @@
   // an instance field. Instance fields don't exist on a class; they exist only
   // on an instance of the class.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `x` is an instance
   // field:
@@ -8303,7 +8879,7 @@
   // The analyzer produces this diagnostic when the name following the `is` in a
   // type test expression isn't defined.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `Srting` isn't
   // defined:
@@ -8373,7 +8949,7 @@
   // either isn't defined or isn't visible in the scope in which it's being
   // referenced.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because the name `rihgt` isn't
   // defined:
@@ -8472,7 +9048,7 @@
   // expected, such as before a member access or on the right-hand side of an
   // assignment.
   //
-  // #### Example
+  // #### Examples
   //
   // The following code produces this diagnostic because `f` doesn't produce an
   // object on which `toString` can be invoked:
diff --git a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
index 6a56870..4ada2b5 100644
--- a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
+++ b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
@@ -17,15 +17,17 @@
 
   bool _isInNativeClass = false;
 
-  /**
-   * When a new class or mixin is entered, [_initFieldsMap] initializes this
-   * map, and [leaveClassOrMixin] resets it.
-   *
-   * [_InitState.notInit] or [_InitState.initInDeclaration] is set for each
-   * field. Later [verify] is called to verify each constructor of the class.
-   */
+  /// When a new class or mixin is entered, [_initFieldsMap] initializes this
+  /// map, and [leaveClassOrMixin] resets it.
+  ///
+  /// [_InitState.notInit] or [_InitState.initInDeclaration] is set for each
+  /// field. Later [verify] is called to verify each constructor of the class.
   Map<FieldElement, _InitState> _initialFieldMap;
 
+  /// The state of fields in the current constructor.
+  Map<FieldElement, _InitState> _fieldMap = {};
+
+  /// Set to `true` if the current constructor redirects.
   bool _hasRedirectingConstructorInvocation = false;
 
   ConstructorFieldsVerifier({
@@ -62,9 +64,11 @@
       return;
     }
 
-    var fieldMap = Map.of(_initialFieldMap);
-    _updateWithParameters(node, fieldMap);
-    _updateWithInitializers(node, fieldMap);
+    _fieldMap = Map.of(_initialFieldMap);
+    _hasRedirectingConstructorInvocation = false;
+
+    _updateWithParameters(node);
+    _updateWithInitializers(node);
 
     if (_hasRedirectingConstructorInvocation) {
       return;
@@ -73,7 +77,7 @@
     // Prepare lists of not initialized fields.
     List<FieldElement> notInitFinalFields = <FieldElement>[];
     List<FieldElement> notInitNonNullableFields = <FieldElement>[];
-    fieldMap.forEach((FieldElement field, _InitState state) {
+    _fieldMap.forEach((FieldElement field, _InitState state) {
       if (state != _InitState.notInit) return;
       if (field.isLate) return;
 
@@ -153,10 +157,7 @@
     }
   }
 
-  void _updateWithInitializers(
-    ConstructorDeclaration node,
-    Map<FieldElement, _InitState> fieldMap,
-  ) {
+  void _updateWithInitializers(ConstructorDeclaration node) {
     for (var initializer in node.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         _hasRedirectingConstructorInvocation = true;
@@ -165,9 +166,9 @@
         SimpleIdentifier fieldName = initializer.fieldName;
         Element element = fieldName.staticElement;
         if (element is FieldElement) {
-          _InitState state = fieldMap[element];
+          _InitState state = _fieldMap[element];
           if (state == _InitState.notInit) {
-            fieldMap[element] = _InitState.initInInitializer;
+            _fieldMap[element] = _InitState.initInInitializer;
           } else if (state == _InitState.initInDeclaration) {
             if (element.isFinal || element.isConst) {
               _errorReporter.reportErrorForNode(
@@ -194,10 +195,7 @@
     }
   }
 
-  void _updateWithParameters(
-    ConstructorDeclaration node,
-    Map<FieldElement, _InitState> fieldMap,
-  ) {
+  void _updateWithParameters(ConstructorDeclaration node) {
     var formalParameters = node.parameters.parameters;
     for (FormalParameter parameter in formalParameters) {
       parameter = _baseParameter(parameter);
@@ -205,9 +203,9 @@
         FieldElement fieldElement =
             (parameter.declaredElement as FieldFormalParameterElementImpl)
                 .field;
-        _InitState state = fieldMap[fieldElement];
+        _InitState state = _fieldMap[fieldElement];
         if (state == _InitState.notInit) {
-          fieldMap[fieldElement] = _InitState.initInFieldFormal;
+          _fieldMap[fieldElement] = _InitState.initInFieldFormal;
         } else if (state == _InitState.initInDeclaration) {
           if (fieldElement.isFinal || fieldElement.isConst) {
             _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index bcaf531..9d3bce8 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -736,6 +735,6 @@
     // corresponding DartObject will be `null`.  Since an error has already been
     // reported, there's no need to report another.
     if (x == null || y == null) return true;
-    return (x as DartObjectImpl).isEqualIgnoringTypesRecursively(y);
+    return x == y;
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/collection_element_provider.dart b/pkg/analyzer/lib/src/generated/collection_element_provider.dart
deleted file mode 100644
index 4eb6563..0000000
--- a/pkg/analyzer/lib/src/generated/collection_element_provider.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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/dart/ast/ast.dart';
-
-/// Abstraction layer allowing the mechanism for looking up the elements of
-/// collections to be customized.
-///
-/// This is needed for the NNBD migration engine, which needs to be able to
-/// re-run resolution on code for which certain collection elements have been
-/// removed or changed due to dead code elimination..
-///
-/// This base class implementation gets elements directly from the collections;
-/// for other behaviors, create a class that extends or implements this class.
-class CollectionElementProvider {
-  const CollectionElementProvider();
-
-  /// Gets the elements contained in a [ListLiteral].
-  List<CollectionElement> getListElements(ListLiteral node) => node.elements;
-
-  /// Gets the elements contained in a [SetOrMapLiteral].
-  List<CollectionElement> getSetOrMapElements(SetOrMapLiteral node) =>
-      node.elements;
-}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index bec6557..d098560 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/super_context.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
@@ -126,7 +127,9 @@
    */
   ElementResolver(this._resolver,
       {this.reportConstEvaluationErrors = true,
-      ElementTypeProvider elementTypeProvider = const ElementTypeProvider()})
+      ElementTypeProvider elementTypeProvider = const ElementTypeProvider(),
+      MigratableAstInfoProvider migratableAstInfoProvider =
+          const MigratableAstInfoProvider()})
       : _definingLibrary = _resolver.definingLibrary,
         _extensionResolver = _resolver.extensionResolver,
         _typePropertyResolver = _resolver.typePropertyResolver,
@@ -136,6 +139,7 @@
     _methodInvocationResolver = MethodInvocationResolver(
       _resolver,
       elementTypeProvider,
+      migratableAstInfoProvider,
       inferenceHelper: _resolver.inferenceHelper,
     );
   }
@@ -1094,6 +1098,7 @@
       if (element1 is ClassElement) {
         constructor = _instantiateAnnotationClass(element1)
             .lookUpConstructor(null, _definingLibrary);
+        constructor = _resolver.toLegacyElement(constructor);
       } else if (element1 == null) {
         undefined = true;
       }
@@ -1107,6 +1112,7 @@
       // Class.CONST - not resolved yet
       if (element1 is ClassElement) {
         element2 = element1.lookUpGetter(nameNode2.name, _definingLibrary);
+        element2 = _resolver.toLegacyElement(element2);
       }
       // prefix.CONST or Class.CONST
       if (element2 is PropertyAccessorElement) {
@@ -1118,11 +1124,13 @@
       // prefix.Class()
       if (element2 is ClassElement) {
         constructor = element2.unnamedConstructor;
+        constructor = _resolver.toLegacyElement(constructor);
       }
       // Class.constructor(args)
       if (element1 is ClassElement) {
         constructor = _instantiateAnnotationClass(element1)
             .lookUpConstructor(nameNode2.name, _definingLibrary);
+        constructor = _resolver.toLegacyElement(constructor);
         nameNode2.staticElement = constructor;
       }
       if (element1 == null && element2 == null) {
@@ -1141,6 +1149,7 @@
         PropertyAccessorElement getter =
             element2.lookUpGetter(name3, _definingLibrary);
         if (getter != null) {
+          getter = _resolver.toLegacyElement(getter);
           nameNode3.staticElement = getter;
           annotation.element = getter;
           _resolveAnnotationElementGetter(annotation, getter);
@@ -1149,6 +1158,7 @@
         // prefix.Class.constructor(args)
         constructor = _instantiateAnnotationClass(element2)
             .lookUpConstructor(name3, _definingLibrary);
+        constructor = _resolver.toLegacyElement(constructor);
         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 fde14d2..7577076 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1967,16 +1967,35 @@
       visitedClasses.add(element);
 
       if (element.typeParameters.isNotEmpty) {
-        type = _toLegacyType(type);
-        var oldType = interfaces[element];
-        if (oldType == null) {
-          interfaces[element] = type;
-        } else if (type != oldType) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
-            node,
-            [_enclosingClass.name, oldType, type],
-          );
+        if (_typeSystem.isNonNullableByDefault) {
+          type = _typeSystem.normalize(type);
+          var oldType = interfaces[element];
+          if (oldType == null) {
+            interfaces[element] = type;
+          } else {
+            try {
+              var result = _typeSystem.topMerge(oldType, type);
+              interfaces[element] = result;
+            } catch (_) {
+              _errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+                node,
+                [_enclosingClass.name, oldType, type],
+              );
+            }
+          }
+        } else {
+          type = _toLegacyType(type);
+          var oldType = interfaces[element];
+          if (oldType == null) {
+            interfaces[element] = type;
+          } else if (type != oldType) {
+            _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+              node,
+              [_enclosingClass.name, oldType, type],
+            );
+          }
         }
       }
 
@@ -5261,9 +5280,12 @@
     if (!_isNonNullableByDefault) return;
 
     var parent = node.parent;
-    var defaultValuesAreAllowed = parent is ConstructorDeclaration ||
+    var defaultValuesAreExpected = parent is ConstructorDeclaration ||
         parent is FunctionExpression ||
-        parent is MethodDeclaration;
+        parent is MethodDeclaration &&
+            !parent.isAbstract &&
+            parent.externalKeyword == null &&
+            parent.body is! NativeFunctionBody;
 
     for (var parameter in node.parameters) {
       if (parameter is DefaultFormalParameter) {
@@ -5275,7 +5297,7 @@
               parameterName ?? parameter,
             );
           }
-        } else if (defaultValuesAreAllowed && parameter.defaultValue == null) {
+        } else if (defaultValuesAreExpected && parameter.defaultValue == null) {
           var type = parameter.declaredElement.type;
           if (_typeSystem.isPotentiallyNonNullable(type)) {
             var parameterName = _parameterName(parameter);
diff --git a/pkg/analyzer/lib/src/generated/migratable_ast_info_provider.dart b/pkg/analyzer/lib/src/generated/migratable_ast_info_provider.dart
new file mode 100644
index 0000000..0296c52
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/migratable_ast_info_provider.dart
@@ -0,0 +1,35 @@
+// 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/dart/ast/ast.dart';
+
+/// Abstraction layer allowing the NNBD migration engine to customize the
+/// mechanism for looking up various pieces of information AST nodes.
+///
+/// The information that is abstracted is precisely the information that the
+/// migration process might change, for example the elements of collections
+/// (which might disappear or change due to dead code elimination) and whether
+/// or not a property access is null aware.
+///
+/// This base class implementation gets elements directly from the AST nodes;
+/// for other behaviors, create a class that extends or implements this class.
+class MigratableAstInfoProvider {
+  const MigratableAstInfoProvider();
+
+  /// Gets the elements contained in a [ListLiteral].
+  List<CollectionElement> getListElements(ListLiteral node) => node.elements;
+
+  /// Gets the elements contained in a [SetOrMapLiteral].
+  List<CollectionElement> getSetOrMapElements(SetOrMapLiteral node) =>
+      node.elements;
+
+  /// Queries whether the given [node] is null-aware.
+  bool isIndexExpressionNullAware(IndexExpression node) => node.isNullAware;
+
+  /// Queries whether the given [node] is null-aware.
+  bool isMethodInvocationNullAware(MethodInvocation node) => node.isNullAware;
+
+  /// Queries whether the given [node] is null-aware.
+  bool isPropertyAccessNullAware(PropertyAccess node) => node.isNullAware;
+}
diff --git a/pkg/analyzer/lib/src/generated/migration.dart b/pkg/analyzer/lib/src/generated/migration.dart
index a19edfc..26f48f4 100644
--- a/pkg/analyzer/lib/src/generated/migration.dart
+++ b/pkg/analyzer/lib/src/generated/migration.dart
@@ -6,12 +6,12 @@
 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/generated/collection_element_provider.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
+import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 
 /// Hooks used by resolution to communicate with the migration engine.
 abstract class MigrationResolutionHooks
-    implements ElementTypeProvider, CollectionElementProvider {
+    implements ElementTypeProvider, MigratableAstInfoProvider {
   /// Called when the resolver is visiting an if statement, if element, or
   /// conditional expression, to determine whether the condition is known to
   /// evaluate to `true` or `false`.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index edd29ba..29fe5a7 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -37,11 +37,11 @@
 import 'package:analyzer/src/error/bool_expression_verifier.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/nullable_dereference_verifier.dart';
-import 'package:analyzer/src/generated/collection_element_provider.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
 import 'package:analyzer/src/generated/migration.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
@@ -199,7 +199,7 @@
 
   final ElementTypeProvider _elementTypeProvider;
 
-  final CollectionElementProvider _collectionElementProvider;
+  final MigratableAstInfoProvider _migratableAstInfoProvider;
 
   /// Helper for checking expression that should have the `bool` type.
   BoolExpressionVerifier boolExpressionVerifier;
@@ -315,7 +315,7 @@
             reportConstEvaluationErrors,
             flowAnalysisHelper,
             const ElementTypeProvider(),
-            const CollectionElementProvider());
+            const MigratableAstInfoProvider());
 
   ResolverVisitor._(
       this.inheritance,
@@ -330,7 +330,7 @@
       reportConstEvaluationErrors,
       this._flowAnalysis,
       this._elementTypeProvider,
-      this._collectionElementProvider)
+      this._migratableAstInfoProvider)
       : _featureSet = featureSet,
         super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
@@ -346,7 +346,7 @@
     );
     this._typedLiteralResolver = TypedLiteralResolver(
         this, _featureSet, typeSystem, typeProvider,
-        collectionElementProvider: _collectionElementProvider);
+        migratableAstInfoProvider: _migratableAstInfoProvider);
     this.extensionResolver = ExtensionMemberResolver(this);
     this.typePropertyResolver = TypePropertyResolver(this);
     this.inferenceHelper = InvocationInferenceHelper(
@@ -385,7 +385,8 @@
     );
     this.elementResolver = ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors,
-        elementTypeProvider: _elementTypeProvider);
+        elementTypeProvider: _elementTypeProvider,
+        migratableAstInfoProvider: _migratableAstInfoProvider);
     this.inferenceContext = InferenceContext._(this);
     this.typeAnalyzer = StaticTypeAnalyzer(
       this,
@@ -1418,7 +1419,8 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     node.target?.accept(this);
-    if (node.isNullAware && _isNonNullableByDefault) {
+    if (_migratableAstInfoProvider.isIndexExpressionNullAware(node) &&
+        _isNonNullableByDefault) {
       _flowAnalysis.flow.nullAwareAccess_rightBegin(node.target);
       _unfinishedNullShorts.add(node.nullShortingTermination);
     }
@@ -1586,7 +1588,8 @@
     // to be visited in the context of the property access node.
     //
     node.target?.accept(this);
-    if (node.isNullAware && _isNonNullableByDefault) {
+    if (_migratableAstInfoProvider.isPropertyAccessNullAware(node) &&
+        _isNonNullableByDefault) {
       _flowAnalysis.flow.nullAwareAccess_rightBegin(node.target);
       _unfinishedNullShorts.add(node.nullShortingTermination);
     }
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 0507f27..52ef3d6 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -949,6 +949,7 @@
 
     if (inferred != null &&
         inferred != _elementTypeProvider.getExecutableType(originalElement)) {
+      inferred = _resolver.toLegacyTypeIfOptOut(inferred);
       // Fix up the parameter elements based on inferred method.
       arguments.correspondingStaticParameters =
           ResolverVisitor.resolveArgumentsToParameters(
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 77045c8..b984405 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/src/dart/element/display_string_builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
+import 'package:analyzer/src/dart/element/normalize.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
 import 'package:analyzer/src/dart/element/top_merge.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -97,6 +98,18 @@
     @required this.typeProvider,
   }) : super(isNonNullableByDefault: isNonNullableByDefault);
 
+  InterfaceTypeImpl get nullNone =>
+      _nullNoneCached ??= (typeProvider.nullType as TypeImpl)
+          .withNullability(NullabilitySuffix.none);
+
+  InterfaceTypeImpl get objectNone =>
+      _objectNoneCached ??= (typeProvider.objectType as TypeImpl)
+          .withNullability(NullabilitySuffix.none);
+
+  InterfaceTypeImpl get objectQuestion =>
+      _objectQuestionCached ??= (typeProvider.objectType as TypeImpl)
+          .withNullability(NullabilitySuffix.question);
+
   InterfaceType get _interfaceTypeFunctionNone {
     return typeProvider.functionType.element.instantiate(
       typeArguments: const [],
@@ -104,18 +117,6 @@
     );
   }
 
-  InterfaceTypeImpl get _nullNone =>
-      _nullNoneCached ??= (typeProvider.nullType as TypeImpl)
-          .withNullability(NullabilitySuffix.none);
-
-  InterfaceTypeImpl get _objectNone =>
-      _objectNoneCached ??= (typeProvider.objectType as TypeImpl)
-          .withNullability(NullabilitySuffix.none);
-
-  InterfaceTypeImpl get _objectQuestion =>
-      _objectQuestionCached ??= (typeProvider.objectType as TypeImpl)
-          .withNullability(NullabilitySuffix.question);
-
   /// Returns true iff the type [t] accepts function types, and requires an
   /// implicit coercion if interface types with a `call` method are passed in.
   ///
@@ -234,8 +235,8 @@
     if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull) {
       // * Null if Null <: T2
       // * Never otherwise
-      if (isSubtypeOf(_nullNone, T2)) {
-        return _nullNone;
+      if (isSubtypeOf(nullNone, T2)) {
+        return nullNone;
       } else {
         return NeverTypeImpl.instance;
       }
@@ -245,8 +246,8 @@
     if (T2_nullability == NullabilitySuffix.none && T2.isDartCoreNull) {
       // * Null if Null <: T1
       // * Never otherwise
-      if (isSubtypeOf(_nullNone, T1)) {
-        return _nullNone;
+      if (isSubtypeOf(nullNone, T1)) {
+        return nullNone;
       } else {
         return NeverTypeImpl.instance;
       }
@@ -580,7 +581,7 @@
     // UP(T Function<...>(...), T2) = Object
     // UP(T1, T Function<...>(...)) = Object
     if (T1 is FunctionType || T2 is FunctionType) {
-      return _objectNone;
+      return objectNone;
     }
 
     // UP(T1, T2) = T2 if T1 <: T2
@@ -715,6 +716,35 @@
     return instantiateType(type, arguments);
   }
 
+  @override
+  DartType instantiateToBounds2({
+    ClassElement classElement,
+    FunctionTypeAliasElement functionTypeAliasElement,
+    @required NullabilitySuffix nullabilitySuffix,
+  }) {
+    if (classElement != null) {
+      var typeParameters = classElement.typeParameters;
+      var typeArguments = _defaultTypeArguments(typeParameters);
+      var type = classElement.instantiate(
+        typeArguments: typeArguments,
+        nullabilitySuffix: nullabilitySuffix,
+      );
+      type = toLegacyType(type);
+      return type;
+    } else if (functionTypeAliasElement != null) {
+      var typeParameters = functionTypeAliasElement.typeParameters;
+      var typeArguments = _defaultTypeArguments(typeParameters);
+      var type = functionTypeAliasElement.instantiate(
+        typeArguments: typeArguments,
+        nullabilitySuffix: nullabilitySuffix,
+      );
+      type = toLegacyType(type);
+      return type;
+    } else {
+      throw ArgumentError('Missing element');
+    }
+  }
+
   /**
    * Given uninstantiated [typeFormals], instantiate them to their bounds.
    * See the issue for the algorithm description.
@@ -1201,7 +1231,7 @@
     //   then `T0 <: T1` if `Object? <: T1`.
     if (identical(T0, DynamicTypeImpl.instance) ||
         identical(T0, VoidTypeImpl.instance)) {
-      if (isSubtypeOf(_objectQuestion, T1)) {
+      if (isSubtypeOf(objectQuestion, T1)) {
         return true;
       }
     }
@@ -1221,8 +1251,8 @@
       //   then `T0 <: T1`iff `S <: Object`.
       if (T0_nullability == NullabilitySuffix.none &&
           T0 is TypeParameterTypeImpl) {
-        var bound = T0.element.bound ?? _objectQuestion;
-        return isSubtypeOf(bound, _objectNone);
+        var bound = T0.element.bound ?? objectQuestion;
+        return isSubtypeOf(bound, objectNone);
       }
       // * if `T0` is `FutureOr<S>` for some `S`,
       //   then `T0 <: T1` iff `S <: Object`
@@ -1259,7 +1289,7 @@
           T1 is InterfaceTypeImpl &&
           T1.isDartAsyncFutureOr) {
         var S = T1.typeArguments[0];
-        return isSubtypeOf(_nullNone, S);
+        return isSubtypeOf(nullNone, S);
       }
       // If `T1` is `Null`, `S?` or `S*` for some `S`, then the query is true.
       if (T1_nullability == NullabilitySuffix.none && T1.isDartCoreNull ||
@@ -1309,15 +1339,15 @@
     //   * `T0 <: T1` iff `S0 <: T1` and `Null <: T1`.
     if (T0_nullability == NullabilitySuffix.question) {
       var S0 = T0.withNullability(NullabilitySuffix.none);
-      return isSubtypeOf(S0, T1) && isSubtypeOf(_nullNone, T1);
+      return isSubtypeOf(S0, T1) && isSubtypeOf(nullNone, T1);
     }
 
     // Right Promoted Variable: if `T1` is a promoted type variable `X1 & S1`:
     //   * `T0 <: T1` iff `T0 <: X1` and `T0 <: S1`
     if (T0 is TypeParameterTypeImpl) {
       if (T1 is TypeParameterTypeImpl && T0.definition == T1.definition) {
-        var S0 = T0.element.bound ?? _objectQuestion;
-        var S1 = T1.element.bound ?? _objectQuestion;
+        var S0 = T0.element.bound ?? objectQuestion;
+        var S1 = T1.element.bound ?? objectQuestion;
         if (isSubtypeOf(S0, S1)) {
           return true;
         }
@@ -1350,7 +1380,7 @@
       // * or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
       // * or `T0` is `X0 & S0` and `S0 <: T1`
       if (T0 is TypeParameterTypeImpl) {
-        var S0 = T0.element.bound ?? _objectQuestion;
+        var S0 = T0.element.bound ?? objectQuestion;
         if (isSubtypeOf(S0, T1)) {
           return true;
         }
@@ -1368,13 +1398,13 @@
         return true;
       }
       // * or `T0 <: Null`
-      if (isSubtypeOf(T0, _nullNone)) {
+      if (isSubtypeOf(T0, nullNone)) {
         return true;
       }
       // or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
       // or `T0` is `X0 & S0` and `S0 <: T1`
       if (T0 is TypeParameterTypeImpl) {
-        var S0 = T0.element.bound ?? _objectQuestion;
+        var S0 = T0.element.bound ?? objectQuestion;
         return isSubtypeOf(S0, T1);
       }
       // iff
@@ -1393,7 +1423,7 @@
     // Left Type Variable Bound: `T0` is a type variable `X0` with bound `B0`
     //   * and `B0 <: T1`
     if (T0 is TypeParameterTypeImpl) {
-      var S0 = T0.element.bound ?? _objectQuestion;
+      var S0 = T0.element.bound ?? objectQuestion;
       if (isSubtypeOf(S0, T1)) {
         return true;
       }
@@ -1453,235 +1483,7 @@
    * See `resources/type-system/normalization.md`
    */
   DartType normalize(DartType T) {
-    var T_impl = T as TypeImpl;
-    var T_nullability = T_impl.nullabilitySuffix;
-
-    // NORM(T) = T if T is primitive
-    if (identical(T, DynamicTypeImpl.instance) ||
-        identical(T, NeverTypeImpl.instance) ||
-        identical(T, VoidTypeImpl.instance) ||
-        T is InterfaceType &&
-            T_nullability == NullabilitySuffix.none &&
-            T.typeArguments.isEmpty) {
-      return T;
-    }
-
-    // NORM(FutureOr<T>)
-    if (T is InterfaceType &&
-        T.isDartAsyncFutureOr &&
-        T_nullability == NullabilitySuffix.none) {
-      // * let S be NORM(T)
-      var S = normalize(T.typeArguments[0]);
-      var S_impl = S as TypeImpl;
-      var S_nullability = (S_impl).nullabilitySuffix;
-      // * if S is a top type then S
-      if (isTop(S)) {
-        return S;
-      }
-      // * if S is Object then S
-      // * if S is Object* then S
-      if (S.isDartCoreObject) {
-        if (S_nullability == NullabilitySuffix.none ||
-            S_nullability == NullabilitySuffix.star) {
-          return S;
-        }
-      }
-      // * if S is Never then Future<Never>
-      if (identical(S, NeverTypeImpl.instance)) {
-        return typeProvider.futureElement.instantiate(
-          typeArguments: [NeverTypeImpl.instance],
-          nullabilitySuffix: NullabilitySuffix.none,
-        );
-      }
-      // * if S is Null then Future<Null>?
-      if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
-        return typeProvider.futureElement.instantiate(
-          typeArguments: [_nullNone],
-          nullabilitySuffix: NullabilitySuffix.question,
-        );
-      }
-      // * else FutureOr<S>
-      return typeProvider.futureOrElement.instantiate(
-        typeArguments: [S],
-        nullabilitySuffix: NullabilitySuffix.none,
-      );
-    }
-
-    // NORM(T?)
-    if (T_nullability == NullabilitySuffix.question) {
-      // * let S be NORM(T)
-      var T_none = T_impl.withNullability(NullabilitySuffix.none);
-      var S = normalize(T_none);
-      var S_impl = S as TypeImpl;
-      var S_nullability = (S_impl).nullabilitySuffix;
-      // * if S is a top type then S
-      if (isTop(S)) {
-        return S;
-      }
-      // * if S is Never then Null
-      if (identical(S, NeverTypeImpl.instance)) {
-        return _nullNone;
-      }
-      // * if S is Never* then Null
-      if (identical(S, NeverTypeImpl.instanceLegacy)) {
-        return _nullNone;
-      }
-      // * if S is Null then Null
-      if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
-        return _nullNone;
-      }
-      // * if S is FutureOr<R> and R is nullable then S
-      if (S is InterfaceType &&
-          S.isDartAsyncFutureOr &&
-          S_nullability == NullabilitySuffix.none) {
-        var R = S.typeArguments[0];
-        if (isNullable(R)) {
-          return S;
-        }
-      }
-      // * if S is FutureOr<R>* and R is nullable then FutureOr<R>
-      if (S is InterfaceType &&
-          S.isDartAsyncFutureOr &&
-          S_nullability == NullabilitySuffix.star) {
-        var R = S.typeArguments[0];
-        if (isNullable(R)) {
-          return typeProvider.futureOrElement.instantiate(
-            typeArguments: [R],
-            nullabilitySuffix: NullabilitySuffix.none,
-          );
-        }
-      }
-      // * if S is R? then R?
-      // * if S is R* then R?
-      // * else S?
-      return S_impl.withNullability(NullabilitySuffix.question);
-    }
-
-    // NORM(T*)
-    if (T_nullability == NullabilitySuffix.star) {
-      // * let S be NORM(T)
-      var T_none = T_impl.withNullability(NullabilitySuffix.none);
-      var S = normalize(T_none);
-      var S_impl = S as TypeImpl;
-      var S_nullability = (S_impl).nullabilitySuffix;
-      // * if S is a top type then S
-      if (isTop(S)) {
-        return S;
-      }
-      // * if S is Null then Null
-      if (S_nullability == NullabilitySuffix.none && S.isDartCoreNull) {
-        return _nullNone;
-      }
-      // * if S is R? then R?
-      if (S_nullability == NullabilitySuffix.question) {
-        return S;
-      }
-      // * if S is R* then R*
-      // * else S*
-      return S_impl.withNullability(NullabilitySuffix.star);
-    }
-
-    assert(T_nullability == NullabilitySuffix.none);
-
-    // NORM(X extends T)
-    // NORM(X & T)
-    if (T is TypeParameterType) {
-      var element = T.element;
-      var bound = element.bound;
-      if (bound != null) {
-        if (element is TypeParameterMember) {
-          // NORM(X & T)
-          // * let S be NORM(T)
-          var S = normalize(bound);
-          // * if S is Never then Never
-          if (identical(S, NeverTypeImpl.instance)) {
-            return NeverTypeImpl.instance;
-          }
-          // * if S is a top type then X
-          if (isTop(S)) {
-            return element.declaration.instantiate(
-              nullabilitySuffix: NullabilitySuffix.none,
-            );
-          }
-          // * if S is X then X
-          if (S is TypeParameterTypeImpl &&
-              S.nullabilitySuffix == NullabilitySuffix.none &&
-              S.element == element.declaration) {
-            return element.declaration.instantiate(
-              nullabilitySuffix: NullabilitySuffix.none,
-            );
-          }
-          // * if S is Object and NORM(B) is Object where B is the bound of X then X
-          if (S.nullabilitySuffix == NullabilitySuffix.none &&
-              S.isDartCoreObject) {
-            var B = element.declaration.bound;
-            if (B != null) {
-              var B_norm = normalize(B);
-              if (B_norm.nullabilitySuffix == NullabilitySuffix.none &&
-                  B_norm.isDartCoreObject) {
-                return element.declaration.instantiate(
-                  nullabilitySuffix: NullabilitySuffix.none,
-                );
-              }
-            }
-          }
-          // * else X & S
-          var promoted = TypeParameterMember(
-            element.declaration,
-            Substitution.empty,
-            S,
-          );
-          return promoted.instantiate(
-            nullabilitySuffix: NullabilitySuffix.none,
-          );
-        } else {
-          // NORM(X extends T)
-          // * let S be NORM(T)
-          var S = normalize(bound);
-          // * if S is Never then Never
-          if (identical(S, NeverTypeImpl.instance)) {
-            return NeverTypeImpl.instance;
-          }
-          // * else X extends S
-          var promoted = TypeParameterMember(element, Substitution.empty, S);
-          return promoted.instantiate(
-            nullabilitySuffix: NullabilitySuffix.none,
-          );
-        }
-      } else {
-        return T;
-      }
-    }
-
-    // NORM(C<T0, ..., Tn>) = C<R0, ..., Rn> where Ri is NORM(Ti)
-    if (T is InterfaceType) {
-      return T.element.instantiate(
-        typeArguments: T.typeArguments.map(normalize).toList(),
-        nullabilitySuffix: NullabilitySuffix.none,
-      );
-    }
-
-    // NORM(R Function<X extends B>(S)) = R1 Function(X extends B1>(S1)
-    var functionType = T as FunctionType;
-    return FunctionTypeImpl(
-      typeFormals: functionType.typeFormals.map((e) {
-        var newTypeParameter = TypeParameterElementImpl.synthetic(e.name);
-        if (e.bound != null) {
-          newTypeParameter.bound = normalize(e.bound);
-        }
-        return newTypeParameter;
-      }).toList(),
-      parameters: functionType.parameters.map((e) {
-        return ParameterElementImpl.synthetic(
-          e.name,
-          normalize(e.type),
-          // ignore: deprecated_member_use_from_same_package
-          e.parameterKind,
-        );
-      }).toList(),
-      returnType: normalize(functionType.returnType),
-      nullabilitySuffix: NullabilitySuffix.none,
-    );
+    return NormalizeHelper(this).normalize(T);
   }
 
   @override
@@ -1719,6 +1521,11 @@
         .refineBinaryExpressionType(leftType, operator, rightType, currentType);
   }
 
+  DartType toLegacyType(DartType type) {
+    if (isNonNullableByDefault) return type;
+    return NullabilityEliminator.perform(typeProvider, type);
+  }
+
   /**
    * Merges two types into a single type.
    * Compute the canonical representation of [T].
@@ -1728,7 +1535,7 @@
    * See `#classes-defined-in-opted-in-libraries`
    */
   DartType topMerge(DartType T, DartType S) {
-    return TopMergeHelper.topMerge(T, S);
+    return TopMergeHelper(this).topMerge(T, S);
   }
 
   @override
@@ -1761,6 +1568,15 @@
     return null;
   }
 
+  List<DartType> _defaultTypeArguments(
+    List<TypeParameterElement> typeParameters,
+  ) {
+    return typeParameters.map((typeParameter) {
+      var typeParameterImpl = typeParameter as TypeParameterElementImpl;
+      return typeParameterImpl.defaultType;
+    }).toList();
+  }
+
   /**
    * Eliminates type variables from the context [type], replacing them with
    * `Null` or `Object` as appropriate.
diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart
index 70719c2..4866a43 100644
--- a/pkg/analyzer/lib/src/lint/project.dart
+++ b/pkg/analyzer/lib/src/lint/project.dart
@@ -106,7 +106,7 @@
   final AnalysisDriver driver;
   final List<Source> sources;
   final Directory root;
-  final Set<LibraryElement> elements = <LibraryElement>{};
+  final Set<Element> elements = {};
 
   _ApiModel(this.driver, this.sources, this.root) {
     _calculate();
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 5393951..0083fed 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/summary2/link.dart' as summary2;
 import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2;
 import 'package:analyzer/src/summary2/reference.dart' as summary2;
+import 'package:meta/meta.dart';
 
 class SummaryBuilder {
   final Iterable<Source> librarySources;
@@ -63,11 +64,16 @@
   /**
    * Build the linked bundle and return its bytes.
    */
-  List<int> build() => _Builder(context, librarySources).build();
+  List<int> build({
+    @required FeatureSet featureSet,
+  }) {
+    return _Builder(context, featureSet, librarySources).build();
+  }
 }
 
 class _Builder {
   final AnalysisContext context;
+  final FeatureSet featureSet;
   final Iterable<Source> librarySources;
 
   final Set<String> libraryUris = <String>{};
@@ -75,7 +81,7 @@
 
   final PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
 
-  _Builder(this.context, this.librarySources);
+  _Builder(this.context, this.featureSet, this.librarySources);
 
   /**
    * Build the linked bundle and return its bytes.
@@ -132,14 +138,12 @@
     AnalysisErrorListener errorListener = AnalysisErrorListener.NULL_LISTENER;
     String code = source.contents.data;
     CharSequenceReader reader = CharSequenceReader(code);
-    // TODO(paulberry): figure out the appropriate featureSet to use here
-    var featureSet = FeatureSet.fromEnableFlags([]);
     Scanner scanner = Scanner(source, reader, errorListener)
       ..configureFeatures(featureSet);
     Token token = scanner.tokenize();
     LineInfo lineInfo = LineInfo(scanner.lineStarts);
     Parser parser = Parser(source, errorListener,
-        featureSet: featureSet,
+        featureSet: scanner.featureSet,
         useFasta: context.analysisOptions.useFastaParser);
     parser.enableOptionalNewAndConst = true;
     CompilationUnit unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 0f3fba8..62ec33b 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 import 'package:meta/meta.dart';
@@ -17,8 +18,8 @@
 class NamedTypeBuilder extends TypeBuilder {
   static DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
 
-  /// Indicates whether the library is opted into NNBD.
-  final bool isNNBD;
+  /// The type system of the library with the type name.
+  final TypeSystemImpl typeSystem;
 
   @override
   final Element element;
@@ -40,11 +41,11 @@
   DartType _type;
 
   NamedTypeBuilder(
-      this.isNNBD, this.element, this.arguments, this.nullabilitySuffix,
+      this.typeSystem, this.element, this.arguments, this.nullabilitySuffix,
       {this.node});
 
   factory NamedTypeBuilder.of(
-    bool isNNBD,
+    TypeSystemImpl typeSystem,
     TypeName node,
     Element element,
     NullabilitySuffix nullabilitySuffix,
@@ -57,7 +58,7 @@
       arguments = <DartType>[];
     }
 
-    return NamedTypeBuilder(isNNBD, element, arguments, nullabilitySuffix,
+    return NamedTypeBuilder(typeSystem, element, arguments, nullabilitySuffix,
         node: node);
   }
 
@@ -71,10 +72,12 @@
     if (element is ClassElement) {
       var parameters = element.typeParameters;
       var arguments = _buildArguments(parameters);
-      _type = element.instantiate(
+      var type = element.instantiate(
         typeArguments: arguments,
         nullabilitySuffix: nullabilitySuffix,
       );
+      type = typeSystem.toLegacyType(type);
+      _type = type;
     } else if (element is GenericTypeAliasElement) {
       var rawType = _getRawFunctionType(element);
       if (rawType is FunctionType) {
@@ -82,7 +85,7 @@
         var arguments = _buildArguments(parameters);
         var substitution = Substitution.fromPairs(parameters, arguments);
         var instantiated = substitution.substituteType(rawType) as FunctionType;
-        _type = FunctionTypeImpl(
+        var type = FunctionTypeImpl(
           typeFormals: instantiated.typeFormals,
           parameters: instantiated.parameters,
           returnType: instantiated.returnType,
@@ -90,6 +93,8 @@
           element: element,
           typeArguments: arguments,
         );
+        type = typeSystem.toLegacyType(type);
+        _type = type;
       } else {
         _type = _dynamicType;
       }
@@ -126,7 +131,7 @@
       return this;
     }
 
-    return NamedTypeBuilder(isNNBD, element, arguments, nullabilitySuffix,
+    return NamedTypeBuilder(typeSystem, element, arguments, nullabilitySuffix,
         node: node);
   }
 
@@ -224,7 +229,7 @@
   NullabilitySuffix _getNullabilitySuffix(bool hasQuestion) {
     if (hasQuestion) {
       return NullabilitySuffix.question;
-    } else if (isNNBD) {
+    } else if (typeSystem.isNonNullableByDefault) {
       return NullabilitySuffix.none;
     } else {
       return NullabilitySuffix.star;
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 23ffa03..e4ff77e 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
@@ -30,6 +31,7 @@
 /// the type is set, otherwise we keep it empty, so we will attempt to infer
 /// it later).
 class ReferenceResolver extends ThrowingAstVisitor<void> {
+  final TypeSystemImpl _typeSystem;
   final NodesToBuildType nodesToBuildType;
   final LinkedElementFactory elementFactory;
   final LibraryElement _libraryElement;
@@ -54,7 +56,8 @@
     this.unitReference,
     this.isNNBD,
     this.scope,
-  ) : reference = unitReference;
+  )   : _typeSystem = _libraryElement.typeSystem,
+        reference = unitReference;
 
   @override
   void visitBlockFunctionBody(BlockFunctionBody node) {}
@@ -514,7 +517,7 @@
       );
     } else {
       var builder = NamedTypeBuilder.of(
-        isNNBD,
+        _typeSystem,
         node,
         element,
         nullabilitySuffix,
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index b3fcd58..cfbb4ff 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/context.dart';
@@ -276,6 +277,8 @@
   factory Exception([var message]) => null;
 }
 
+class FormatException implements Exception {}
+
 class Function {}
 
 abstract class int extends num {
@@ -1022,7 +1025,10 @@
     List<Source> librarySources = sdkLibraries
         .map((SdkLibrary library) => mapDartUri(library.shortName))
         .toList();
-    return SummaryBuilder(librarySources, context).build();
+    var featureSet = FeatureSet.fromEnableFlags([]);
+    return SummaryBuilder(librarySources, context).build(
+      featureSet: featureSet,
+    );
   }
 }
 
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 07a9c56..d611abf 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -425,27 +425,36 @@
   ParameterElement namedParameter({
     @required String name,
     @required DartType type,
+    bool isCovariant = false,
   }) {
     var parameter = ParameterElementImpl(name, 0);
     parameter.parameterKind = ParameterKind.NAMED;
     parameter.type = type;
+    parameter.isExplicitlyCovariant = isCovariant;
     return parameter;
   }
 
   ParameterElement namedRequiredParameter({
     @required String name,
     @required DartType type,
+    bool isCovariant = false,
   }) {
     var parameter = ParameterElementImpl(name, 0);
     parameter.parameterKind = ParameterKind.NAMED_REQUIRED;
     parameter.type = type;
+    parameter.isExplicitlyCovariant = isCovariant;
     return parameter;
   }
 
-  ParameterElement positionalParameter({String name, @required DartType type}) {
+  ParameterElement positionalParameter({
+    String name,
+    @required DartType type,
+    bool isCovariant = false,
+  }) {
     var parameter = ParameterElementImpl(name ?? '', 0);
     parameter.parameterKind = ParameterKind.POSITIONAL;
     parameter.type = type;
+    parameter.isExplicitlyCovariant = isCovariant;
     return parameter;
   }
 
@@ -457,10 +466,15 @@
     return TypeParameterMember(element, null, bound);
   }
 
-  ParameterElement requiredParameter({String name, @required DartType type}) {
+  ParameterElement requiredParameter({
+    String name,
+    @required DartType type,
+    bool isCovariant = false,
+  }) {
     var parameter = ParameterElementImpl(name ?? '', 0);
     parameter.parameterKind = ParameterKind.REQUIRED;
     parameter.type = type;
+    parameter.isExplicitlyCovariant = isCovariant;
     return parameter;
   }
 
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 215da61..d388a8a 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1185,286 +1185,6 @@
     ]);
   }
 
-  test_undefinedGetter() async {
-    await assertErrorsInCode(r'''
-class T {}
-f(T e) { return e.m; }
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 29, 1),
-    ]);
-  }
-
-  test_undefinedGetter_generic_function_call() async {
-    // Referencing `.call` on a `Function` type works similarly to referencing
-    // it on `dynamic`--the reference is accepted at compile time, and all type
-    // checking is deferred until runtime.
-    await assertErrorsInCode('''
-f(Function f) {
-  return f.call;
-}
-''', []);
-  }
-
-  test_undefinedGetter_object_call() async {
-    await assertErrorsInCode('''
-f(Object o) {
-  return o.call;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 25, 4),
-    ]);
-  }
-
-  test_undefinedGetter_proxy_annotation_fakeProxy() async {
-    await assertErrorsInCode(r'''
-library L;
-class Fake {
-  const Fake();
-}
-const proxy = const Fake();
-@proxy class PrefixProxy {}
-main() {
-  new PrefixProxy().foo;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 127, 3),
-    ]);
-  }
-
-  test_undefinedGetter_static() async {
-    await assertErrorsInCode(r'''
-class A {}
-var a = A.B;''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 21, 1),
-    ]);
-  }
-
-  test_undefinedGetter_typeLiteral_cascadeTarget() async {
-    await assertErrorsInCode(r'''
-class T {
-  static int get foo => 42;
-}
-main() {
-  T..foo;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 54, 3),
-    ]);
-  }
-
-  test_undefinedGetter_typeLiteral_conditionalAccess() async {
-    // When applied to a type literal, the conditional access operator '?.'
-    // cannot be used to access instance getters of Type.
-    await assertErrorsInCode('''
-class A {}
-f() => A?.hashCode;
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_GETTER, 21, 8),
-    ]);
-  }
-
-  test_undefinedGetter_wrongNumberOfTypeArguments_tooLittle() async {
-    await assertErrorsInCode(r'''
-class A<K, V> {
-  K element;
-}
-main(A<int> a) {
-  a.element.anyGetterExistsInDynamic;
-}
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 36, 6),
-    ]);
-  }
-
-  test_undefinedGetter_wrongNumberOfTypeArguments_tooMany() async {
-    await assertErrorsInCode(r'''
-class A<E> {
-  E element;
-}
-main(A<int,int> a) {
-  a.element.anyGetterExistsInDynamic;
-}
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 33, 10),
-    ]);
-  }
-
-  test_undefinedGetter_wrongOfTypeArgument() async {
-    await assertErrorsInCode(r'''
-class A<E> {
-  E element;
-}
-main(A<NoSuchType> a) {
-  a.element.anyGetterExistsInDynamic;
-}
-''', [
-      error(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, 35, 10),
-    ]);
-  }
-
-  test_undefinedMethod_assignmentExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {
-  f(A a) {
-    A a2 = new A();
-    a += a2;
-  }
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 58, 2),
-    ]);
-  }
-
-  test_undefinedMethod_ignoreTypePropagation() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {
-  m() {}
-}
-class C {
-  f() {
-    A a = new B();
-    a.m();
-  }
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_METHOD, 85, 1),
-    ]);
-  }
-
-  test_undefinedMethod_leastUpperBoundWithNull() async {
-    await assertErrorsInCode('''
-f(bool b, int i) => (b ? null : i).foo();
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_METHOD, 35, 3),
-    ]);
-  }
-
-  test_undefinedMethod_ofNull() async {
-    // TODO(scheglov) Track https://github.com/dart-lang/sdk/issues/28430 to
-    // decide whether a warning should be reported here.
-    await assertErrorsInCode(r'''
-Null f(int x) => null;
-main() {
-  f(42).abs();
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_METHOD, 40, 3),
-    ]);
-  }
-
-  test_undefinedMethodWithConstructor() async {
-    await assertErrorsInCode(r'''
-class C {
-  C.m();
-}
-f() {
-  C c = C.m();
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 31, 1),
-    ]);
-  }
-
-  test_undefinedOperator_indexBoth() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a[0]++;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
-    ]);
-  }
-
-  test_undefinedOperator_indexGetter() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a[0];
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
-    ]);
-  }
-
-  test_undefinedOperator_indexSetter() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a[0] = 1;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
-    ]);
-  }
-
-  test_undefinedOperator_plus() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a + 1;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 1),
-    ]);
-  }
-
-  test_undefinedOperator_postfixExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a++;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 2),
-    ]);
-  }
-
-  test_undefinedOperator_prefixExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  ++a;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 22, 2),
-    ]);
-  }
-
-  test_undefinedSetter() async {
-    await assertErrorsInCode(r'''
-class T {}
-f(T e1) { e1.m = 0; }
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_SETTER, 24, 1),
-    ]);
-  }
-
-  test_undefinedSetter_static() async {
-    await assertErrorsInCode(r'''
-class A {}
-f() { A.B = 0;}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_SETTER, 19, 1),
-    ]);
-  }
-
-  test_undefinedSetter_typeLiteral_cascadeTarget() async {
-    await assertErrorsInCode(r'''
-class T {
-  static void set foo(_) {}
-}
-main() {
-  T..foo = 42;
-}
-''', [
-      error(StaticTypeWarningCode.UNDEFINED_SETTER, 54, 3),
-    ]);
-  }
-
   test_unqualifiedReferenceToNonLocalStaticMember_getter() async {
     await assertErrorsInCode(r'''
 class A {
@@ -1523,73 +1243,16 @@
     ]);
   }
 
-  test_wrongNumberOfTypeArguments_class_tooFew() async {
+  test_wrongNumberOfTypeArguments() async {
     await assertErrorsInCode(r'''
-class A<E, F> {}
-A<A> a = null;
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 17, 4),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_class_tooMany() async {
-    await assertErrorsInCode(r'''
-class A<E> {}
-A<A, A> a = null;
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 14, 7),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_classAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class M {}
-class B<F extends num> = A<F> with M;
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 47, 4),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_dynamic() async {
-    await assertErrorsInCode(r'''
-dynamic<int> v;
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 0, 12),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeParameter() async {
-    await assertErrorsInCode(r'''
-class C<T> {
-  T<int> f;
+class A<E> {
+  E element;
+}
+main(A<NoSuchType> a) {
+  a.element.anyGetterExistsInDynamic;
 }
 ''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 15, 6),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeTest_tooFew() async {
-    await assertErrorsInCode(r'''
-class A {}
-class C<K, V> {}
-f(p) {
-  return p is C<A>;
-}
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 49, 4),
-    ]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeTest_tooMany() async {
-    await assertErrorsInCode(r'''
-class A {}
-class C<E> {}
-f(p) {
-  return p is C<A, A>;
-}
-''', [
-      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 46, 7),
+      error(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, 35, 10),
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 1dcf937..c73ec4b 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -28,6 +28,10 @@
   /// The message text of the error or `null` if the message should not be checked.
   final String message;
 
+  /// A pattern that should be contained in the error message or `null` if the message
+  /// contents should not be checked.
+  final Pattern messageContains;
+
   /// The list of context messages that are expected to be associated with the
   /// error.
   final List<ExpectedContextMessage> expectedContextMessages;
@@ -35,6 +39,7 @@
   /// Initialize a newly created error description.
   ExpectedError(this.code, this.offset, this.length,
       {this.message,
+      this.messageContains,
       this.expectedContextMessages = const <ExpectedContextMessage>[]});
 
   /// Return `true` if the [error] matches this description of what it's
@@ -48,6 +53,10 @@
     if (message != null && error.message != message) {
       return false;
     }
+    if (messageContains != null &&
+        error.message?.contains(messageContains) != true) {
+      return false;
+    }
     List<DiagnosticMessage> contextMessages = error.contextMessages.toList();
     contextMessages.sort((first, second) {
       int result = first.filePath.compareTo(second.filePath);
diff --git a/pkg/analyzer/test/id_tests/nullability_test.dart b/pkg/analyzer/test/id_tests/nullability_test.dart
index efddffb..283e16e 100644
--- a/pkg/analyzer/test/id_tests/nullability_test.dart
+++ b/pkg/analyzer/test/id_tests/nullability_test.dart
@@ -80,8 +80,8 @@
         TypeImpl declaredType = (element as VariableElement).type;
         var isPromoted = promotedType != declaredType;
         if (isPromoted &&
-            _typeSystem.isNullable(declaredType) &&
-            !_typeSystem.isNullable(promotedType)) {
+            _typeSystem.isPotentiallyNullable(declaredType) &&
+            !_typeSystem.isPotentiallyNullable(promotedType)) {
           return 'nonNullable';
         }
       }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index f17faee..016cab85 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2,28 +2,24 @@
 // 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';
-
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/test_utilities/find_element.dart';
-import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../generated/elements_types_mixin.dart';
 import '../../../utils.dart';
+import '../resolution/driver_resolution.dart';
 import 'base.dart';
 
 main() {
@@ -43,37 +39,8 @@
  * Integration tests for resolution.
  */
 @reflectiveTest
-class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest
+class AnalysisDriverResolutionTest extends DriverResolutionTest
     with ElementsTypesMixin {
-  ResolvedUnitResult result;
-  FindNode findNode;
-  FindElement findElement;
-
-  ClassElement get boolElement => typeProvider.boolType.element;
-
-  ClassElement get doubleElement => typeProvider.doubleType.element;
-
-  InterfaceType get doubleType => typeProvider.doubleType;
-
-  ClassElement get futureElement => typeProvider.futureElement;
-
-  ClassElement get intElement => typeProvider.intType.element;
-
-  InterfaceType get intType => typeProvider.intType;
-
-  ClassElement get listElement => typeProvider.listElement;
-
-  ClassElement get mapElement => typeProvider.mapElement;
-
-  ClassElement get numElement => typeProvider.numType.element;
-
-  InterfaceType get numType => typeProvider.numType;
-
-  ClassElement get stringElement => typeProvider.stringType.element;
-
-  @override
-  TypeProvider get typeProvider => result.typeProvider;
-
   void assertDeclaredVariableType(SimpleIdentifier node, String expected) {
     VariableElement element = node.staticElement;
     assertType(element.type, expected);
@@ -84,80 +51,6 @@
     expect(element.type, isDynamicType);
   }
 
-  void assertElement(AstNode node, Element expected) {
-    Element actual = getNodeElement(node);
-    expect(actual, same(expected));
-  }
-
-  void assertElementNull(Expression node) {
-    Element actual = getNodeElement(node);
-    expect(actual, isNull);
-  }
-
-  void assertIdentifierTopGetRef(SimpleIdentifier ref, String name) {
-    var getter = findElement.topGet(name);
-    assertElement(ref, getter);
-
-    expect(ref.staticType, getter.returnType);
-  }
-
-  void assertInvokeType(InvocationExpression expression, String expected) {
-    DartType actual = expression.staticInvokeType;
-    assertType(actual, expected);
-  }
-
-  void assertInvokeTypeDynamic(InvocationExpression node) {
-    DartType actual = node.staticInvokeType;
-    expect(actual, isDynamicType);
-  }
-
-  void assertMember(
-    Object elementOrNode,
-    Element expectedBase,
-    Map<String, String> expectedSubstitution,
-  ) {
-    Member actual;
-    if (elementOrNode is Member) {
-      actual = elementOrNode;
-    } else {
-      actual = getNodeElement(elementOrNode as AstNode);
-    }
-
-    expect(actual.declaration, same(expectedBase));
-
-    var actualMapString = actual.substitution.map.map(
-      (k, v) => MapEntry(k.name, v.getDisplayString(withNullability: false)),
-    );
-    expect(actualMapString, expectedSubstitution);
-  }
-
-  void assertTopGetRef(String search, String name) {
-    var ref = findNode.simple(search);
-    assertIdentifierTopGetRef(ref, name);
-  }
-
-  void assertType(Object typeOrNode, String expected) {
-    DartType actual;
-    if (typeOrNode is DartType) {
-      actual = typeOrNode;
-    } else if (typeOrNode is Expression) {
-      actual = typeOrNode.staticType;
-    } else if (typeOrNode is GenericFunctionType) {
-      actual = typeOrNode.type;
-    } else if (typeOrNode is TypeName) {
-      actual = typeOrNode.type;
-    } else {
-      fail('Unsupported node: (${typeOrNode.runtimeType}) $typeOrNode');
-    }
-
-    if (expected == null) {
-      expect(actual, isNull);
-    } else {
-      var typeStr = actual.getDisplayString(withNullability: false);
-      expect(typeStr, expected);
-    }
-  }
-
   /// Test that [argumentList] has exactly two type items `int` and `double`.
   void assertTypeArguments(
       TypeArgumentList argumentList, List<DartType> expectedTypes) {
@@ -167,35 +60,6 @@
     }
   }
 
-  void assertTypeDynamic(Expression expression) {
-    DartType actual = expression.staticType;
-    expect(actual, isDynamicType);
-  }
-
-  void assertTypeName(
-      TypeName node, Element expectedElement, String expectedType,
-      {PrefixElement expectedPrefix}) {
-    assertType(node, expectedType);
-
-    if (expectedPrefix == null) {
-      var name = node.name as SimpleIdentifier;
-      assertElement(name, expectedElement);
-      assertTypeNull(name);
-    } else {
-      var name = node.name as PrefixedIdentifier;
-
-      assertElement(name.prefix, expectedPrefix);
-      expect(name.prefix.staticType, isNull);
-
-      assertElement(name.identifier, expectedElement);
-      expect(name.identifier.staticType, isNull);
-    }
-  }
-
-  void assertTypeNull(Identifier node) {
-    expect(node.staticType, isNull);
-  }
-
   void assertUnresolvedInvokeType(DartType invokeType) {
     expect(invokeType, isDynamicType);
   }
@@ -230,30 +94,6 @@
     };
   }
 
-  Element getNodeElement(Expression node) {
-    if (node is AssignmentExpression) {
-      return node.staticElement;
-    } else if (node is Identifier) {
-      return node.staticElement;
-    } else if (node is IndexExpression) {
-      return node.staticElement;
-    } else if (node is InstanceCreationExpression) {
-      return node.staticElement;
-    } else if (node is PostfixExpression) {
-      return node.staticElement;
-    } else if (node is PrefixExpression) {
-      return node.staticElement;
-    } else {
-      fail('Unsupported node: (${node.runtimeType}) $node');
-    }
-  }
-
-  Future resolveTestFile() async {
-    result = await driver.getResult(testFile);
-    findNode = FindNode(result.content, result.unit);
-    findElement = FindElement(result.unit);
-  }
-
   test_adjacentStrings() async {
     String content = r'''
 void main() {
@@ -875,17 +715,12 @@
   }
 
   test_asExpression() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   num v = 42;
   v as int;
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
+''');
 
     NodeList<Statement> statements = _getMainStatements(result);
 
@@ -3901,17 +3736,12 @@
   }
 
   test_isExpression() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   var v = 42;
   v is num;
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
+''');
 
     NodeList<Statement> statements = _getMainStatements(result);
 
@@ -3940,17 +3770,12 @@
   }
 
   test_isExpression_not() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   var v = 42;
   v is! num;
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
+''');
 
     NodeList<Statement> statements = _getMainStatements(result);
 
@@ -4478,16 +4303,11 @@
   }
 
   test_local_parameter() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 void main(int p) {
   p;
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
+''');
 
     InterfaceType intType = typeProvider.intType;
 
@@ -4871,15 +4691,12 @@
   }
 
   test_local_variable() async {
-    addTestFile(r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   var v = 42;
   v;
 }
 ''');
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
 
     InterfaceType intType = typeProvider.intType;
 
@@ -6658,18 +6475,13 @@
   }
 
   test_stringInterpolation() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   var v = 42;
   '$v$v $v';
   ' ${v + 1} ';
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
-    expect(result.errors, isEmpty);
+''');
 
     FunctionDeclaration main = result.unit.declarations[0];
     expect(main.declaredElement, isNotNull);
@@ -7181,7 +6993,7 @@
   }
 
   test_top_executables_class() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 class C {
   C(int p);
   C.named(int p);
@@ -7190,11 +7002,7 @@
   int get publicGetter => 0;
   void set publicSetter(double p) {}
 }
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
+''');
 
     InterfaceType doubleType = typeProvider.doubleType;
     InterfaceType intType = typeProvider.intType;
@@ -7313,15 +7121,11 @@
   }
 
   test_top_executables_top() async {
-    String content = r'''
+    await assertNoErrorsInCode(r'''
 int topFunction(double p) => 0;
 int get topGetter => 0;
 void set topSetter(double p) {}
-''';
-    addTestFile(content);
-
-    await resolveTestFile();
-    expect(result.path, testFile);
+''');
 
     InterfaceType doubleType = typeProvider.doubleType;
     InterfaceType intType = typeProvider.intType;
diff --git a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
index 20337de..d1aea54 100644
--- a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
@@ -44,45 +44,235 @@
     typeSystem = analysisContext.typeSystemNonNullableByDefault;
   }
 
-  test_functionType() {
+  test_functionType_parameter() {
     _check(
       functionTypeNone(
-        returnType: intNone,
-        typeFormals: [
-          typeParameter('T', bound: numNone),
-        ],
+        returnType: voidNone,
         parameters: [
-          requiredParameter(type: intNone),
+          requiredParameter(type: futureOrNone(objectNone)),
         ],
       ),
       functionTypeNone(
-        returnType: intNone,
-        typeFormals: [
-          typeParameter('T', bound: numNone),
-        ],
+        returnType: voidNone,
         parameters: [
-          requiredParameter(type: intNone),
+          requiredParameter(type: objectNone),
         ],
       ),
     );
 
     _check(
       functionTypeNone(
-        returnType: futureOrNone(objectNone),
-        typeFormals: [
-          typeParameter('T', bound: futureOrNone(objectNone)),
-        ],
+        returnType: voidNone,
         parameters: [
-          requiredParameter(type: futureOrNone(objectNone)),
+          namedParameter(name: 'a', type: futureOrNone(objectNone)),
         ],
       ),
       functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          namedParameter(name: 'a', type: objectNone),
+        ],
+      ),
+    );
+
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          namedRequiredParameter(name: 'a', type: futureOrNone(objectNone)),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          namedRequiredParameter(name: 'a', type: objectNone),
+        ],
+      ),
+    );
+
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          positionalParameter(type: futureOrNone(objectNone)),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          positionalParameter(type: objectNone),
+        ],
+      ),
+    );
+  }
+
+  test_functionType_parameter_covariant() {
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: futureOrNone(objectNone), isCovariant: true),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: objectNone, isCovariant: true),
+        ],
+      ),
+    );
+  }
+
+  test_functionType_parameter_typeParameter() {
+    TypeParameterElement T;
+    TypeParameterElement T2;
+
+    T = typeParameter('T', bound: neverNone);
+    T2 = typeParameter('T2', bound: neverNone);
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [T],
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T)),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [T2],
+        parameters: [
+          requiredParameter(type: neverNone),
+        ],
+      ),
+    );
+
+    T = typeParameter('T', bound: iterableNone(futureOrNone(dynamicNone)));
+    T2 = typeParameter('T2', bound: iterableNone(dynamicNone));
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [T],
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T)),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [T2],
+        parameters: [
+          requiredParameter(type: typeParameterTypeNone(T2)),
+        ],
+      ),
+    );
+  }
+
+  test_functionType_returnType() {
+    _check(
+      functionTypeNone(
+        returnType: futureOrNone(objectNone),
+      ),
+      functionTypeNone(
         returnType: objectNone,
+      ),
+    );
+
+    _check(
+      functionTypeNone(
+        returnType: intNone,
+      ),
+      functionTypeNone(
+        returnType: intNone,
+      ),
+    );
+  }
+
+  test_functionType_typeParameter_bound_normalized() {
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        typeFormals: [
+          typeParameter('T', bound: futureOrNone(objectNone)),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
         typeFormals: [
           typeParameter('T', bound: objectNone),
         ],
+      ),
+    );
+  }
+
+  test_functionType_typeParameter_bound_unchanged() {
+    _check(
+      functionTypeNone(
+        returnType: intNone,
+        typeFormals: [
+          typeParameter('T', bound: numNone),
+        ],
+      ),
+      functionTypeNone(
+        returnType: intNone,
+        typeFormals: [
+          typeParameter('T', bound: numNone),
+        ],
+      ),
+    );
+  }
+
+  test_functionType_typeParameter_fresh() {
+    var T = typeParameter('T');
+    var T2 = typeParameter('T');
+    _check(
+      functionTypeNone(
+        returnType: typeParameterTypeNone(T),
+        typeFormals: [T],
         parameters: [
-          requiredParameter(type: objectNone),
+          requiredParameter(
+            type: typeParameterTypeNone(T),
+          ),
+        ],
+      ),
+      functionTypeNone(
+        returnType: typeParameterTypeNone(T2),
+        typeFormals: [T2],
+        parameters: [
+          requiredParameter(
+            type: typeParameterTypeNone(T2),
+          ),
+        ],
+      ),
+    );
+  }
+
+  test_functionType_typeParameter_fresh_bound() {
+    var T = typeParameter('T');
+    var S = typeParameter('S', bound: typeParameterTypeNone(T));
+    var T2 = typeParameter('T');
+    var S2 = typeParameter('S', bound: typeParameterTypeNone(T2));
+    _check(
+      functionTypeNone(
+        returnType: typeParameterTypeNone(T),
+        typeFormals: [T, S],
+        parameters: [
+          requiredParameter(
+            type: typeParameterTypeNone(T),
+          ),
+          requiredParameter(
+            type: typeParameterTypeNone(S),
+          ),
+        ],
+      ),
+      functionTypeNone(
+        returnType: typeParameterTypeNone(T2),
+        typeFormals: [T2, S2],
+        parameters: [
+          requiredParameter(
+            type: typeParameterTypeNone(T2),
+          ),
+          requiredParameter(
+            type: typeParameterTypeNone(S2),
+          ),
         ],
       ),
     );
@@ -196,26 +386,30 @@
     check(intStar, intStar);
   }
 
+  /// NORM(X & T)
+  /// * let S be NORM(T)
   test_typeParameter_bound() {
     TypeParameterElement T;
 
+    // * if S is Never then Never
+    T = typeParameter('T', bound: neverNone);
+    _check(typeParameterTypeNone(T), neverNone);
+
+    // * else X
     T = typeParameter('T');
     _check(typeParameterTypeNone(T), typeParameterTypeNone(T));
 
-    T = typeParameter('T', bound: numNone);
-    _check(typeParameterTypeNone(T), typeParameterTypeNone(T));
-
+    // * else X
     T = typeParameter('T', bound: futureOrNone(objectNone));
-    _check(
-      typeParameterTypeNone(T),
-      typeParameterTypeNone(
-        promoteTypeParameter(T, objectNone),
-      ),
-    );
+    _check(typeParameterTypeNone(T), typeParameterTypeNone(T));
   }
 
-  /// NORM(X & T)
-  /// * let S be NORM(T)
+  test_typeParameter_bound_recursive() {
+    var T = typeParameter('T');
+    T.bound = iterableNone(typeParameterTypeNone(T));
+    _check(typeParameterTypeNone(T), typeParameterTypeNone(T));
+  }
+
   test_typeParameter_promoted() {
     var T = typeParameter('T');
 
@@ -293,6 +487,28 @@
 expected: $expectedStr
 actual: $resultStr
 ''');
+    _checkFormalParametersIsCovariant(result, expected);
+  }
+
+  void _checkFormalParametersIsCovariant(DartType T1, DartType T2) {
+    if (T1 is FunctionType && T2 is FunctionType) {
+      var parameters1 = T1.parameters;
+      var parameters2 = T2.parameters;
+      expect(parameters1, hasLength(parameters2.length));
+      for (var i = 0; i < parameters1.length; i++) {
+        var parameter1 = parameters1[i];
+        var parameter2 = parameters2[i];
+        if (parameter1.isCovariant != parameter2.isCovariant) {
+          fail('''
+parameter1: $parameter1, isCovariant: ${parameter1.isCovariant}
+parameter2: $parameter2, isCovariant: ${parameter2.isCovariant}
+T1: ${_typeString(T1 as TypeImpl)}
+T2: ${_typeString(T2 as TypeImpl)}
+''');
+        }
+        _checkFormalParametersIsCovariant(parameter1.type, parameter2.type);
+      }
+    }
   }
 
   String _typeParametersStr(TypeImpl type) {
diff --git a/pkg/analyzer/test/src/dart/element/top_merge_test.dart b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
index d58e17b..6f77a5f 100644
--- a/pkg/analyzer/test/src/dart/element/top_merge_test.dart
+++ b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
@@ -71,6 +71,50 @@
     );
   }
 
+  test_function_covariant() {
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: objectQuestion, isCovariant: true),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: dynamicNone),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: objectQuestion, isCovariant: true),
+        ],
+      ),
+    );
+
+    _check(
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: intNone, isCovariant: true),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: numNone),
+        ],
+      ),
+      functionTypeNone(
+        returnType: voidNone,
+        parameters: [
+          requiredParameter(type: numNone, isCovariant: true),
+        ],
+      ),
+    );
+  }
+
   test_function_parameters_mismatch() {
     _check(
       functionTypeNone(
@@ -225,6 +269,16 @@
     _check(dynamicNone, objectQuestion, objectQuestion);
   }
 
+  test_objectStar() {
+    // NNBD_TOP_MERGE(Object*, void) = void
+    // NNBD_TOP_MERGE(void, Object*) = void
+    _check(objectStar, voidNone, voidNone);
+
+    // NNBD_TOP_MERGE(Object*, dynamic) = Object?
+    // NNBD_TOP_MERGE(dynamic, Object*) = Object?
+    _check(objectStar, dynamicNone, objectQuestion);
+  }
+
   test_typeParameter() {
     var T = typeParameter('T');
 
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index f68311d..531f4b1 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -26,7 +26,13 @@
 }
 ''');
     AssignmentExpression assignment = findNode.assignment('+= 4');
-    assertElement(assignment, numElement.getMethod('+'));
+    assertElement(
+      assignment,
+      elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'num'); // num + int = num
 
     IndexExpression indexed = assignment.leftHandSide;
@@ -52,7 +58,13 @@
 }
 ''');
     var assignment = findNode.assignment('v += 3');
-    assertElement(assignment, numElement.getMethod('+'));
+    assertElement(
+      assignment,
+      elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'num'); // num + int = num
 
     SimpleIdentifier left = assignment.leftHandSide;
@@ -74,7 +86,13 @@
 }
 ''');
     var assignment = findNode.assignment('c.f += 2');
-    assertElement(assignment, numElement.getMethod('+'));
+    assertElement(
+      assignment,
+      elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'num'); // num + int = num
 
     PrefixedIdentifier left = assignment.leftHandSide;
@@ -102,7 +120,13 @@
 }
 ''');
     var assignment = findNode.assignment('f += 2');
-    assertElement(assignment, numElement.getMethod('+'));
+    assertElement(
+      assignment,
+      elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'num'); // num + int = num
 
     PropertyAccess left = assignment.leftHandSide;
diff --git a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
index ab574a6..16729fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
@@ -26,7 +26,10 @@
 
     assertBinaryExpression(
       findNode.binary('a != b'),
-      element: numElement.getMethod('=='),
+      element: elementMatcher(
+        numElement.getMethod('=='),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'bool',
     );
   }
@@ -40,7 +43,10 @@
 
     assertBinaryExpression(
       findNode.binary('a == b'),
-      element: numElement.getMethod('=='),
+      element: elementMatcher(
+        numElement.getMethod('=='),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'bool',
     );
   }
@@ -96,7 +102,10 @@
 
     assertBinaryExpression(
       findNode.binary('a + b'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'double',
     );
   }
@@ -110,7 +119,10 @@
 
     assertBinaryExpression(
       findNode.binary('a + b'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
@@ -138,7 +150,10 @@
 
     assertBinaryExpression(
       findNode.binary('a + 0'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'num',
     );
   }
@@ -152,7 +167,10 @@
 
     assertBinaryExpression(
       findNode.binary('a / b'),
-      element: numElement.getMethod('/'),
+      element: elementMatcher(
+        numElement.getMethod('/'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'double',
     );
   }
@@ -166,7 +184,10 @@
 
     assertBinaryExpression(
       findNode.binary('a * b'),
-      element: numElement.getMethod('*'),
+      element: elementMatcher(
+        numElement.getMethod('*'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'double',
     );
   }
@@ -180,7 +201,10 @@
 
     assertBinaryExpression(
       findNode.binary('a * b'),
-      element: numElement.getMethod('*'),
+      element: elementMatcher(
+        numElement.getMethod('*'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index 3533254..51e24c3 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -90,7 +90,13 @@
     assertType(indexExpression, 'num');
 
     var assignment = indexExpression.parent as AssignmentExpression;
-    assertElement(assignment, numPlusElement);
+    assertElement(
+      assignment,
+      elementMatcher(
+        numPlusElement,
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'num');
     assertParameterElement(
       assignment.rightHandSide,
@@ -124,7 +130,13 @@
     assertType(indexExpression, 'double');
 
     var assignment = indexExpression.parent as AssignmentExpression;
-    assertElement(assignment, doublePlusElement);
+    assertElement(
+      assignment,
+      elementMatcher(
+        doublePlusElement,
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
+    );
     assertType(assignment, 'double');
     assertParameterElement(
       assignment.rightHandSide,
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 4fabfe85..f764905 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -2,7 +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/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -12,6 +15,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MetadataResolutionTest);
+    defineReflectiveTests(MetadataResolutionWithNnbdTest);
   });
 }
 
@@ -174,3 +178,220 @@
     return buffer.toString();
   }
 }
+
+@reflectiveTest
+class MetadataResolutionWithNnbdTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.forTesting(
+        sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
+
+  ImportFindElement get import_a {
+    return findElement.importFind('package:test/a.dart');
+  }
+
+  @override
+  bool get typeToStringWithNullability => true;
+
+  test_optIn_fromOptOut_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const A(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+@A(0)
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A('),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@A'),
+      declaration: import_a.unnamedConstructor('A'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_class_constructor() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const A.named(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+@A.named(0)
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A.named('),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@A'),
+      declaration: import_a.constructor('named', of: 'A'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_class_getter() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const foo = 0;
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+@A.foo
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A.foo'),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@A.foo'),
+      declaration: import_a.getter('foo'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_getter() async {
+    newFile('/test/lib/a.dart', content: r'''
+const foo = 0;
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+@foo
+void f() {}
+''');
+
+    assertElement2(
+      findNode.annotation('@foo'),
+      declaration: import_a.topGet('foo'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_prefix_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const A(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart' as a;
+
+@a.A(0)
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A('),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@a.A'),
+      declaration: import_a.unnamedConstructor('A'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_prefix_class_constructor() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const A.named(int a);
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart' as a;
+
+@a.A.named(0)
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A.named('),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@a.A'),
+      declaration: import_a.constructor('named', of: 'A'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_prefix_class_getter() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  const foo = 0;
+}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart' as a;
+
+@a.A.foo
+void f() {}
+''');
+
+    assertElement2(
+      findNode.simple('A.foo'),
+      declaration: import_a.class_('A'),
+    );
+
+    assertElement2(
+      findNode.annotation('@a.A'),
+      declaration: import_a.getter('foo'),
+      isLegacy: true,
+    );
+  }
+
+  test_optIn_fromOptOut_prefix_getter() async {
+    newFile('/test/lib/a.dart', content: r'''
+const foo = 0;
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart' as a;
+
+@a.foo
+void f() {}
+''');
+
+    assertElement2(
+      findNode.annotation('@a.foo'),
+      declaration: import_a.topGet('foo'),
+      isLegacy: true,
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
index 0413283..fda3a9e 100644
--- a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
@@ -26,7 +26,10 @@
 
     assertPostfixExpression(
       findNode.postfix('x--'),
-      element: numElement.getMethod('-'),
+      element: elementMatcher(
+        numElement.getMethod('-'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
@@ -40,7 +43,10 @@
 
     assertPostfixExpression(
       findNode.postfix('x++'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index e1a40ee..3677dd0 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -84,7 +84,10 @@
 
     assertPrefixExpression(
       findNode.prefix('-x'),
-      element: intElement.getMethod('unary-'),
+      element: elementMatcher(
+        intElement.getMethod('unary-'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
@@ -122,7 +125,10 @@
 
     assertPrefixExpression(
       findNode.prefix('++x'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
@@ -140,7 +146,10 @@
 
     assertPrefixExpression(
       findNode.prefix('++x'),
-      element: numElement.getMethod('+'),
+      element: elementMatcher(
+        numElement.getMethod('+'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
@@ -154,7 +163,10 @@
 
     assertPrefixExpression(
       findNode.prefix('~x'),
-      element: intElement.getMethod('~'),
+      element: elementMatcher(
+        intElement.getMethod('~'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 0ca1c8b..368064b 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
@@ -48,20 +49,33 @@
 
   bool get enableUnusedLocalVariable => false;
 
+  ClassElement get futureElement => typeProvider.futureElement;
+
   ClassElement get intElement => typeProvider.intType.element;
 
   InterfaceType get intType => typeProvider.intType;
 
+  bool get isNullSafetySdkAndLegacyLibrary {
+    if (FeatureSetProvider.isNullSafetySdk) {
+      return !result.libraryElement.isNonNullableByDefault;
+    }
+    return false;
+  }
+
   ClassElement get listElement => typeProvider.listElement;
 
   ClassElement get mapElement => typeProvider.mapElement;
 
+  NeverElementImpl get neverElement => NeverElementImpl.instance;
+
   ClassElement get numElement => typeProvider.numType.element;
 
   ClassElement get objectElement => typeProvider.objectType.element;
 
   InterfaceType get objectType => typeProvider.objectType;
 
+  ClassElement get stringElement => typeProvider.stringType.element;
+
   InterfaceType get stringType => typeProvider.stringType;
 
   TypeProvider get typeProvider => result.typeProvider;
@@ -103,10 +117,10 @@
 
   void assertBinaryExpression(
     BinaryExpression node, {
-    @required ExecutableElement element,
+    @required Object element,
     @required String type,
   }) {
-    assertElement(node, element);
+    assertElement(node.staticElement, element);
     assertType(node, type);
   }
 
@@ -138,9 +152,41 @@
     );
   }
 
-  void assertElement(AstNode node, Element expected) {
-    Element actual = getNodeElement(node);
-    expect(actual, same(expected));
+  void assertElement(Object nodeOrElement, Object elementOrMatcher) {
+    Element element;
+    if (nodeOrElement is AstNode) {
+      element = getNodeElement(nodeOrElement);
+    } else {
+      element = nodeOrElement as Element;
+    }
+
+    expect(element, _elementMatcher(elementOrMatcher));
+  }
+
+  void assertElement2(
+    Object nodeOrElement, {
+    @required Element declaration,
+    bool isLegacy = false,
+    Map<String, String> substitution = const {},
+  }) {
+    Element element;
+    if (nodeOrElement is AstNode) {
+      element = getNodeElement(nodeOrElement);
+    } else {
+      element = nodeOrElement as Element;
+    }
+
+    var actualDeclaration = element?.declaration;
+    expect(actualDeclaration, same(declaration));
+
+    if (element is Member) {
+      expect(element.isLegacy, isLegacy);
+      assertSubstitution(element.substitution, substitution);
+    } else {
+      if (isLegacy || substitution.isNotEmpty) {
+        fail('Expected to be a Member: (${element.runtimeType}) $element');
+      }
+    }
   }
 
   void assertElementLibraryUri(Element element, String expected) {
@@ -162,6 +208,13 @@
     expect(actual, isNull);
   }
 
+  void assertElementString(Element element, String expected) {
+    var str = element.getDisplayString(
+      withNullability: typeToStringWithNullability,
+    );
+    expect(str, expected);
+  }
+
   void assertElementTypes(List<DartType> types, List<DartType> expected,
       {bool ordered = false}) {
     if (ordered) {
@@ -442,19 +495,19 @@
 
   void assertPostfixExpression(
     PostfixExpression node, {
-    @required MethodElement element,
+    @required Object element,
     @required String type,
   }) {
-    assertElement(node, element);
+    assertElement(node.staticElement, element);
     assertType(node, type);
   }
 
   void assertPrefixExpression(
     PrefixExpression node, {
-    @required MethodElement element,
+    @required Object element,
     @required String type,
   }) {
-    assertElement(node, element);
+    assertElement(node.staticElement, element);
     assertType(node, type);
   }
 
@@ -468,12 +521,12 @@
   }
 
   void assertSimpleIdentifier(
-    SimpleIdentifier identifier, {
-    @required Element element,
+    SimpleIdentifier node, {
+    @required Object element,
     @required String type,
   }) {
-    assertElement(identifier, element);
-    assertType(identifier, type);
+    assertElement(node.staticElement, element);
+    assertType(node, type);
   }
 
   void assertSubstitution(
@@ -571,12 +624,28 @@
     expect(node.staticType, isNull);
   }
 
+  Matcher elementMatcher(
+    Element declaration, {
+    bool isLegacy = false,
+    Map<String, String> substitution = const {},
+  }) {
+    return _ElementMatcher(
+      this,
+      declaration: declaration,
+      isLegacy: isLegacy,
+      substitution: substitution,
+    );
+  }
+
   ExpectedError error(ErrorCode code, int offset, int length,
           {String text,
+          Pattern messageContains,
           List<ExpectedContextMessage> contextMessages =
               const <ExpectedContextMessage>[]}) =>
       ExpectedError(code, offset, length,
-          message: text, expectedContextMessages: contextMessages);
+          message: text,
+          messageContains: messageContains,
+          expectedContextMessages: contextMessages);
 
   AuxiliaryElements getNodeAuxElements(AstNode node) {
     if (node is IndexExpression) {
@@ -640,14 +709,75 @@
     findElement = FindElement(result.unit);
   }
 
+  /// Choose the type display string, depending on whether the [result] is
+  /// non-nullable or legacy.
+  String typeStr(String nonNullable, String legacy) {
+    if (result.libraryElement.isNonNullableByDefault) {
+      return nonNullable;
+    } else {
+      return legacy;
+    }
+  }
+
   /// Return a textual representation of the [type] that is appropriate for
   /// tests.
   String typeString(DartType type) =>
       type.getDisplayString(withNullability: typeToStringWithNullability);
 
+  _ElementMatcher _elementMatcher(Object elementOrMatcher) {
+    if (elementOrMatcher is Element) {
+      return _ElementMatcher(this, declaration: elementOrMatcher);
+    } else {
+      return elementOrMatcher;
+    }
+  }
+
   static String _extractReturnType(String invokeType) {
     int functionIndex = invokeType.indexOf(' Function');
     expect(functionIndex, isNonNegative);
     return invokeType.substring(0, functionIndex);
   }
 }
+
+class _ElementMatcher extends Matcher {
+  final ResolutionTest test;
+  final Element declaration;
+  final bool isLegacy;
+  final Map<String, String> substitution;
+
+  _ElementMatcher(
+    this.test, {
+    this.declaration,
+    this.isLegacy = false,
+    this.substitution = const {},
+  });
+
+  @override
+  Description describe(Description description) {
+    return description
+        .add('declaration: $declaration\n')
+        .add('isLegacy: $isLegacy\n')
+        .add('substitution: $substitution\n');
+  }
+
+  @override
+  bool matches(element, Map matchState) {
+    if (element is Element) {
+      if (!identical(element.declaration, declaration)) {
+        return false;
+      }
+
+      if (element is Member) {
+        if (element.isLegacy != isLegacy) {
+          return false;
+        }
+
+        test.assertSubstitution(element.substitution, substitution);
+        return true;
+      } else {
+        return !isLegacy && substitution.isEmpty;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index e9b94a0aa..4fb7da7 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -49,6 +49,7 @@
 import 'simple_identifier_test.dart' as simple_identifier;
 import 'top_type_inference_test.dart' as top_type_inference;
 import 'type_inference/test_all.dart' as type_inference;
+import 'type_name_test.dart' as type_name;
 
 main() {
   defineReflectiveSuite(() {
@@ -93,6 +94,7 @@
     property_access.main();
     simple_identifier.main();
     top_type_inference.main();
+    type_name.main();
     type_inference.main();
   }, name: 'resolution');
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
new file mode 100644
index 0000000..c1a4cf0
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -0,0 +1,463 @@
+// Copyright (c) 2020, 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/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypeNameResolutionTest);
+    defineReflectiveTests(TypeNameResolutionWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class TypeNameResolutionTest extends DriverResolutionTest {
+  @override
+  bool get typeToStringWithNullability => true;
+
+  test_class() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      findElement.class_('A'),
+      typeStr('A', 'A*'),
+    );
+  }
+
+  test_class_generic_toBounds() async {
+    await assertNoErrorsInCode(r'''
+class A<T extends num> {}
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      findElement.class_('A'),
+      typeStr('A<num>', 'A<num*>*'),
+    );
+  }
+
+  test_class_generic_toBounds_dynamic() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {}
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      findElement.class_('A'),
+      typeStr('A<dynamic>', 'A<dynamic>*'),
+    );
+  }
+
+  test_class_generic_typeArguments() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {}
+
+f(A<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A<int> a'),
+      findElement.class_('A'),
+      typeStr('A<int>', 'A<int*>*'),
+    );
+  }
+
+  test_functionTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+typedef F = int Function();
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      findElement.functionTypeAlias('F'),
+      typeStr('int Function()', 'int* Function()*'),
+    );
+  }
+
+  test_functionTypeAlias_generic_toBounds() async {
+    await assertNoErrorsInCode(r'''
+typedef F<T extends num> = T Function();
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      findElement.functionTypeAlias('F'),
+      typeStr('num Function()', 'num* Function()*'),
+    );
+  }
+
+  test_functionTypeAlias_generic_toBounds_dynamic() async {
+    await assertNoErrorsInCode(r'''
+typedef F<T> = T Function();
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      findElement.functionTypeAlias('F'),
+      typeStr('dynamic Function()', 'dynamic Function()*'),
+    );
+  }
+
+  test_functionTypeAlias_generic_typeArguments() async {
+    await assertNoErrorsInCode(r'''
+typedef F<T> = T Function();
+
+f(F<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F<int> a'),
+      findElement.functionTypeAlias('F'),
+      typeStr('int Function()', 'int* Function()*'),
+    );
+  }
+
+  test_never() async {
+    await assertNoErrorsInCode(r'''
+f(Never a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('Never a'),
+      neverElement,
+      typeStr('Never', 'Never*'),
+    );
+  }
+}
+
+@reflectiveTest
+class TypeNameResolutionWithNnbdTest extends TypeNameResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.forTesting(
+        sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
+
+  ImportFindElement get import_a {
+    return findElement.importFind('package:test/a.dart');
+  }
+
+  test_optIn_fromOptOut_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A*',
+    );
+  }
+
+  test_optIn_fromOptOut_class_generic_toBounds() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T extends num> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A<num*>*',
+    );
+  }
+
+  test_optIn_fromOptOut_class_generic_toBounds_dynamic() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A<dynamic>*',
+    );
+  }
+
+  test_optIn_fromOptOut_class_generic_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(A<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A<int> a'),
+      import_a.class_('A'),
+      'A<int*>*',
+    );
+  }
+
+  test_optIn_fromOptOut_functionTypeAlias() async {
+    newFile('/test/lib/a.dart', content: r'''
+typedef F = int Function(bool);
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'int* Function(bool*)*',
+    );
+  }
+
+  test_optIn_fromOptOut_functionTypeAlias_generic_dynamic() async {
+    newFile('/test/lib/a.dart', content: r'''
+typedef F<T> = T Function(bool);
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'dynamic Function(bool*)*',
+    );
+  }
+
+  test_optIn_fromOptOut_functionTypeAlias_generic_toBounds() async {
+    newFile('/test/lib/a.dart', content: r'''
+typedef F<T extends num> = T Function(bool);
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'num* Function(bool*)*',
+    );
+  }
+
+  test_optIn_fromOptOut_functionTypeAlias_generic_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+typedef F<T> = T Function(bool);
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.7
+import 'a.dart';
+
+f(F<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F<int> a'),
+      import_a.functionTypeAlias('F'),
+      'int* Function(bool*)*',
+    );
+  }
+
+  test_optOut_fromOptIn_class() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+class A {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A',
+    );
+  }
+
+  test_optOut_fromOptIn_class_generic_toBounds() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+class A<T extends num> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A<num*>',
+    );
+  }
+
+  test_optOut_fromOptIn_class_generic_toBounds_dynamic() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+class A<T> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(A a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A a'),
+      import_a.class_('A'),
+      'A<dynamic>',
+    );
+  }
+
+  test_optOut_fromOptIn_class_generic_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+class A<T> {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(A<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('A<int> a'),
+      import_a.class_('A'),
+      'A<int>',
+    );
+  }
+
+  test_optOut_fromOptIn_functionTypeAlias() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+typedef F = int Function();
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'int* Function()',
+    );
+  }
+
+  test_optOut_fromOptIn_functionTypeAlias_generic_toBounds() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+typedef F<T extends num> = T Function();
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'num* Function()',
+    );
+  }
+
+  test_optOut_fromOptIn_functionTypeAlias_generic_toBounds_dynamic() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+typedef F<T> = T Function();
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(F a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F a'),
+      import_a.functionTypeAlias('F'),
+      'dynamic Function()',
+    );
+  }
+
+  test_optOut_fromOptIn_functionTypeAlias_generic_typeArguments() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+typedef F<T> = T Function();
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+f(F<int> a) {}
+''');
+
+    assertTypeName(
+      findNode.typeName('F<int> a'),
+      import_a.functionTypeAlias('F'),
+      'int* Function()',
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
index 8ce3236..f392af5 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart
@@ -124,4 +124,36 @@
 class C extends B implements A<int> {}
 ''');
   }
+
+  test_class_topMerge() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+
+class A<T> {}
+
+class B extends A<FutureOr<Object>> {}
+
+class C extends B implements A<Object> {}
+''');
+  }
+
+  test_class_topMerge_optIn_optOut() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T> {}
+''');
+
+    newFile('/test/lib/b.dart', content: r'''
+// @dart = 2.5
+import 'a.dart';
+
+class B extends A<int> {}
+''');
+
+    await assertNoErrorsInCode('''
+import 'a.dart';
+import 'b.dart';
+
+class C extends B implements A<int> {}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/default_value_on_required_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/default_value_on_required_parameter_test.dart
index 8dc7e2f..8700979 100644
--- a/pkg/analyzer/test/src/diagnostics/default_value_on_required_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/default_value_on_required_parameter_test.dart
@@ -22,19 +22,19 @@
     ..contextFeatures = FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
 
-  test_notRequired_default() async {
+  test_function_notRequired_default() async {
     await assertNoErrorsInCode('''
 void log({String message: 'no message'}) {}
 ''');
   }
 
-  test_notRequired_noDefault() async {
+  test_function_notRequired_noDefault() async {
     await assertNoErrorsInCode('''
 void log({String? message}) {}
 ''');
   }
 
-  test_required_default() async {
+  test_function_required_default() async {
     await assertErrorsInCode('''
 void log({required String? message: 'no message'}) {}
 ''', [
@@ -42,9 +42,29 @@
     ]);
   }
 
-  test_required_noDefault() async {
+  test_function_required_noDefault() async {
     await assertNoErrorsInCode('''
 void log({required String message}) {}
 ''');
   }
+
+  test_method_abstract_required_default() async {
+    await assertErrorsInCode('''
+abstract class C {
+  void foo({required int? a = 0});
+}
+''', [
+      error(CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER, 45, 1),
+    ]);
+  }
+
+  test_method_required_default() async {
+    await assertErrorsInCode('''
+class C {
+  void foo({required int? a = 0}) {}
+}
+''', [
+      error(CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER, 36, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/final_not_initialized_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/final_not_initialized_constructor_test.dart
index d624ad9..000bccc 100644
--- a/pkg/analyzer/test/src/diagnostics/final_not_initialized_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/final_not_initialized_constructor_test.dart
@@ -50,4 +50,36 @@
       error(StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS, 57, 1),
     ]);
   }
+
+  Future<void> test_redirecting_error() async {
+    await assertErrorsInCode('''
+class A {
+  final int x;
+  A() : this._();
+  A._();
+}
+''', [
+      error(StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1, 45, 1),
+    ]);
+  }
+
+  Future<void> test_redirecting_no_error() async {
+    await assertNoErrorsInCode('''
+class A {
+  final int x;
+  A() : this._();
+  A._() : x = 0;
+}
+''');
+  }
+
+  Future<void> test_two_constructors_no_errors() async {
+    await assertNoErrorsInCode('''
+class A {
+  final int x;
+  A.zero() : x = 0;
+  A.one() : x = 1;
+}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
index 027218b..858747c 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
@@ -158,7 +158,7 @@
       error(HintCode.UNUSED_FIELD, 65, 2),
     ]);
     await _resolveFile('/lib2.dart', [
-      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER, 41, 1),
+      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER, 41, 13),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
index ae73cac..98b2e99 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -211,7 +211,8 @@
       error(HintCode.UNUSED_FIELD, 49, 2),
     ]);
     await _resolveFile('/lib2.dart', [
-      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER, 40, 1),
+      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER, 40, 12,
+          messageContains: 'A.forTesting'),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
index 77fc4a8..8bc17df 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_default_value_for_parameter_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -195,6 +196,136 @@
 ''');
   }
 
+  test_method_abstract_nonNullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+abstract class C {
+  void foo({int a});
+}
+''');
+  }
+
+  test_method_abstract_nonNullable_positional_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+abstract class C {
+  void foo([int a]);
+}
+''');
+  }
+
+  test_method_abstract_nullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+abstract class C {
+  void foo({int? a});
+}
+''');
+  }
+
+  test_method_abstract_potentiallyNonNullable_named_optional() async {
+    await assertNoErrorsInCode('''
+abstract class A<T> {
+  void foo({T a});
+}
+''');
+  }
+
+  test_method_abstract_potentiallyNonNullable_positional_optional() async {
+    await assertNoErrorsInCode('''
+abstract class A<T extends Object?> {
+  void foo([T a]);
+}
+''');
+  }
+
+  test_method_external_nonNullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external void foo({int a});
+}
+''');
+  }
+
+  test_method_external_nonNullable_positional_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external void foo([int a]);
+}
+''');
+  }
+
+  test_method_external_nullable_named_optional_noDefault() async {
+    await assertNoErrorsInCode('''
+class C {
+  external void foo({int? a});
+}
+''');
+  }
+
+  test_method_external_potentiallyNonNullable_named_optional() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  external void foo({T a});
+}
+''');
+  }
+
+  test_method_external_potentiallyNonNullable_positional_optional() async {
+    await assertNoErrorsInCode('''
+class A<T extends Object?> {
+  external void foo([T a]);
+}
+''');
+  }
+
+  test_method_native_nonNullable_named_optional_noDefault() async {
+    await assertErrorsInCode('''
+class C {
+  void foo({int a}) native;
+}
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 30, 7),
+    ]);
+  }
+
+  test_method_native_nonNullable_positional_optional_noDefault() async {
+    await assertErrorsInCode('''
+class C {
+  void foo([int a]) native;
+}
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 30, 7),
+    ]);
+  }
+
+  test_method_native_nullable_named_optional_noDefault() async {
+    await assertErrorsInCode('''
+class C {
+  void foo({int? a}) native;
+}
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 31, 7),
+    ]);
+  }
+
+  test_method_native_potentiallyNonNullable_named_optional() async {
+    await assertErrorsInCode('''
+class A<T> {
+  void foo({T a}) native;
+}
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 31, 7),
+    ]);
+  }
+
+  test_method_native_potentiallyNonNullable_positional_optional() async {
+    await assertErrorsInCode('''
+class A<T extends Object?> {
+  void foo([T a]) native;
+}
+''', [
+      error(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, 47, 7),
+    ]);
+  }
+
   test_method_nonNullable_named_optional_noDefault() async {
     await assertErrorsInCode('''
 class C {
diff --git a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
index 482eb53..398f6bc 100644
--- a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
@@ -488,6 +488,21 @@
     );
   }
 
+  test_instanceCreation_generic_instantiateToBounds() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A<T extends num> {}
+''');
+    await assertNoErrorsInCode(r'''
+// @dart = 2.5
+import 'a.dart';
+
+var v = A();
+''');
+
+    var v = findElement.topVar('v');
+    assertType(v.type, 'A<num*>*');
+  }
+
   test_methodInvocation_extension_functionTarget() async {
     newFile('/test/lib/a.dart', content: r'''
 extension E on void Function() {
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index 441ecf9..593638f 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -516,7 +516,10 @@
 
     assertBinaryExpression(
       findNode.binary('=='),
-      element: objectElement.getMethod('=='),
+      element: elementMatcher(
+        objectElement.getMethod('=='),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'bool',
     );
 
@@ -565,7 +568,10 @@
 
     assertSimpleIdentifier(
       findNode.simple('toString'),
-      element: objectElement.getMethod('toString'),
+      element: elementMatcher(
+        objectElement.getMethod('toString'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'String Function()',
     );
   }
@@ -579,7 +585,10 @@
 
     assertSimpleIdentifier(
       findNode.simple('hashCode'),
-      element: objectElement.getGetter('hashCode'),
+      element: elementMatcher(
+        objectElement.getGetter('hashCode'),
+        isLegacy: isNullSafetySdkAndLegacyLibrary,
+      ),
       type: 'int',
     );
   }
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index f91af0a..177bd1f 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -46,6 +46,17 @@
     ]);
   }
 
+  test_generic_function_call() async {
+    // Referencing `.call` on a `Function` type works similarly to referencing
+    // it on `dynamic`--the reference is accepted at compile time, and all type
+    // checking is deferred until runtime.
+    await assertErrorsInCode('''
+f(Function f) {
+  return f.call;
+}
+''', []);
+  }
+
   test_ifElement_inList_notPromoted() async {
     await assertErrorsInCode('''
 f(int x) {
@@ -122,6 +133,15 @@
 ''');
   }
 
+  test_instance_undefined() async {
+    await assertErrorsInCode(r'''
+class T {}
+f(T e) { return e.m; }
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 29, 1),
+    ]);
+  }
+
   test_nullMember_undefined() async {
     await assertErrorsInCode(r'''
 m() {
@@ -133,6 +153,16 @@
     ]);
   }
 
+  test_object_call() async {
+    await assertErrorsInCode('''
+f(Object o) {
+  return o.call;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 25, 4),
+    ]);
+  }
+
   test_promotedTypeParameter_regress35305() async {
     await assertErrorsInCode(r'''
 void f<X extends num, Y extends X>(Y y) {
@@ -145,6 +175,22 @@
     ]);
   }
 
+  test_proxy_annotation_fakeProxy() async {
+    await assertErrorsInCode(r'''
+library L;
+class Fake {
+  const Fake();
+}
+const proxy = const Fake();
+@proxy class PrefixProxy {}
+main() {
+  new PrefixProxy().foo;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 127, 3),
+    ]);
+  }
+
   test_static_conditionalAcces_defined() async {
     // The conditional access operator '?.' can be used to access static
     // fields.
@@ -179,6 +225,30 @@
     ]);
   }
 
+  test_typeLiteral_cascadeTarget() async {
+    await assertErrorsInCode(r'''
+class T {
+  static int get foo => 42;
+}
+main() {
+  T..foo;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 54, 3),
+    ]);
+  }
+
+  test_typeLiteral_conditionalAccess() async {
+    // When applied to a type literal, the conditional access operator '?.'
+    // cannot be used to access instance getters of Type.
+    await assertErrorsInCode('''
+class A {}
+f() => A?.hashCode;
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_GETTER, 21, 8),
+    ]);
+  }
+
   test_typeSubstitution_defined() async {
     await assertNoErrorsInCode(r'''
 class A<E> {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
index 61a5b1e..97943ad 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
@@ -18,6 +18,15 @@
 
 @reflectiveTest
 class UndefinedMethodTest extends DriverResolutionTest {
+  test_constructor_defined() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  C.m();
+}
+C c = C.m();
+''');
+  }
+
   test_functionExpression_callMethod_defined() async {
     await assertNoErrorsInCode(r'''
 main() {
@@ -34,6 +43,42 @@
 ''');
   }
 
+  test_ignoreTypePropagation() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  m() {}
+}
+class C {
+  f() {
+    A a = new B();
+    a.m();
+  }
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_METHOD, 85, 1),
+    ]);
+  }
+
+  test_leastUpperBoundWithNull() async {
+    await assertErrorsInCode('''
+f(bool b, int i) => (b ? null : i).foo();
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_METHOD, 35, 3),
+    ]);
+  }
+
+  test_method_undefined_onNull() async {
+    await assertErrorsInCode(r'''
+Null f(int x) => null;
+main() {
+  f(42).abs();
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_METHOD, 40, 3),
+    ]);
+  }
+
   test_static_conditionalAccess_defined() async {
     // The conditional access operator '?.' can be used to access static
     // methods.
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
index fb7ebc4..02ea237 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
@@ -18,6 +18,20 @@
 
 @reflectiveTest
 class UndefinedOperatorTest extends DriverResolutionTest {
+  test_assignmentExpression_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {
+  f(A a) {
+    A a2 = new A();
+    a += a2;
+  }
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 58, 2),
+    ]);
+  }
+
   test_binaryExpression() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -107,6 +121,40 @@
     ]);
   }
 
+  test_indexBoth_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a[0]++;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
+    ]);
+  }
+
+  test_indexGetter_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a[0];
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
+    ]);
+  }
+
+  test_indexSetter_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a[0] = 1;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 3),
+    ]);
+  }
+
   test_minus_null() async {
     await assertErrorsInCode(r'''
 m() {
@@ -141,6 +189,17 @@
     ]);
   }
 
+  test_plus_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a + 1;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 1),
+    ]);
+  }
+
   test_plusEq_null() async {
     await assertErrorsInCode(r'''
 m() {
@@ -190,6 +249,17 @@
 ''');
   }
 
+  test_postfixExpression_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a++;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 23, 2),
+    ]);
+  }
+
   test_postfixInc_null() async {
     await assertErrorsInCode(r'''
 m() {
@@ -239,6 +309,17 @@
 ''');
   }
 
+  test_prefixExpression_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  ++a;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 22, 2),
+    ]);
+  }
+
   test_prefixInc_null() async {
     await assertErrorsInCode(r'''
 m() {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index 533395b..38e017a 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -31,6 +31,15 @@
 ''');
   }
 
+  test_instance_undefined() async {
+    await assertErrorsInCode(r'''
+class T {}
+f(T e1) { e1.m = 0; }
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_SETTER, 24, 1),
+    ]);
+  }
+
   test_inSubtype() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -83,6 +92,28 @@
       error(StaticTypeWarningCode.UNDEFINED_SETTER, 75, 1),
     ]);
   }
+
+  test_static_undefined() async {
+    await assertErrorsInCode(r'''
+class A {}
+f() { A.B = 0;}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_SETTER, 19, 1),
+    ]);
+  }
+
+  test_typeLiteral_cascadeTarget() async {
+    await assertErrorsInCode(r'''
+class T {
+  static void set foo(_) {}
+}
+main() {
+  T..foo = 42;
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_SETTER, 54, 3),
+    ]);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
index 745c468..83954f2 100644
--- a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
@@ -15,6 +15,34 @@
 
 @reflectiveTest
 class WrongNumberOfTypeArgumentsTest extends DriverResolutionTest {
+  test_class_tooFew() async {
+    await assertErrorsInCode(r'''
+class A<E, F> {}
+A<A> a = null;
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 17, 4),
+    ]);
+  }
+
+  test_class_tooMany() async {
+    await assertErrorsInCode(r'''
+class A<E> {}
+A<A, A> a = null;
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 14, 7),
+    ]);
+  }
+
+  test_classAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class M {}
+class B<F extends num> = A<F> with M;
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 47, 4),
+    ]);
+  }
+
   test_const_nonGeneric() async {
     await assertErrorsInCode('''
 class C {
@@ -57,6 +85,14 @@
     ]);
   }
 
+  test_dynamic() async {
+    await assertErrorsInCode(r'''
+dynamic<int> v;
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 0, 12),
+    ]);
+  }
+
   test_new_nonGeneric() async {
     await assertErrorsInCode('''
 class C {}
@@ -92,4 +128,64 @@
       error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 34, 11),
     ]);
   }
+
+  test_type_tooFew() async {
+    await assertErrorsInCode(r'''
+class A<K, V> {
+  K element;
+}
+main(A<int> a) {
+  a.element.anyGetterExistsInDynamic;
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 36, 6),
+    ]);
+  }
+
+  test_type_tooMany() async {
+    await assertErrorsInCode(r'''
+class A<E> {
+  E element;
+}
+main(A<int,int> a) {
+  a.element.anyGetterExistsInDynamic;
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 33, 10),
+    ]);
+  }
+
+  test_typeParameter() async {
+    await assertErrorsInCode(r'''
+class C<T> {
+  T<int> f;
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 15, 6),
+    ]);
+  }
+
+  test_typeTest_tooFew() async {
+    await assertErrorsInCode(r'''
+class A {}
+class C<K, V> {}
+f(p) {
+  return p is C<A>;
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 49, 4),
+    ]);
+  }
+
+  test_typeTest_tooMany() async {
+    await assertErrorsInCode(r'''
+class A {}
+class C<E> {}
+f(p) {
+  return p is C<A, A>;
+}
+''', [
+      error(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 46, 7),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 0ac4772..3d57873 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -37,12 +37,16 @@
   /// ony include docs that cannot be verified because of missing support in the
   /// verifier.
   static const List<String> unverifiedDocs = [
+    // Produces two diagnostics when it should only produce one.
+    'CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE',
+    // Produces two diagnostics when it should only produce one.
+    'CompileTimeErrorCode.INVALID_URI',
     // Need a way to make auxiliary files that (a) are not included in the
     // generated docs or (b) can be made persistent for fixes.
     'CompileTimeErrorCode.PART_OF_NON_PART',
     // The code has been replaced but is not yet removed.
     'HintCode.DEPRECATED_MEMBER_USE',
-    // Needs two expected errors.
+    // Needs to be able to specify two expected diagnostics.
     'StaticWarningCode.AMBIGUOUS_IMPORT',
   ];
 
@@ -64,12 +68,15 @@
   /// buffer.
   bool hasWrittenFilePath = false;
 
+  /// The name of the variable currently being verified.
+  String variableName;
+
   /// The name of the error code currently being verified.
   String codeName;
 
-  /// A flag indicating whether the [codeName] has already been written to the
-  /// buffer.
-  bool hasWrittenCodeName = false;
+  /// A flag indicating whether the [variableName] has already been written to
+  /// the buffer.
+  bool hasWrittenVariableName = false;
 
   /// Initialize a newly created documentation validator.
   DocumentationValidator(this.codePaths);
@@ -88,6 +95,16 @@
     }
   }
 
+  /// Return the name of the code as defined in the [initializer].
+  String _extractCodeName(VariableDeclaration variable) {
+    Expression initializer = variable.initializer;
+    if (initializer is MethodInvocation) {
+      var firstArgument = initializer.argumentList.arguments[0];
+      return (firstArgument as StringLiteral).stringValue;
+    }
+    return variable.name.name;
+  }
+
   /// Extract documentation from the given [field] declaration.
   List<String> _extractDoc(FieldDeclaration field) {
     Token comments = field.firstTokenAfterCommentAndMetadata.precedingComments;
@@ -196,9 +213,9 @@
       buffer.writeln('In $filePath');
       hasWrittenFilePath = true;
     }
-    if (!hasWrittenCodeName) {
-      buffer.writeln('  $codeName');
-      hasWrittenCodeName = true;
+    if (!hasWrittenVariableName) {
+      buffer.writeln('  $variableName');
+      hasWrittenVariableName = true;
     }
     buffer.writeln('    $problem');
     for (AnalysisError error in errors) {
@@ -227,14 +244,14 @@
             List<String> docs = _extractDoc(member);
             if (docs != null) {
               VariableDeclaration variable = member.fields.variables[0];
-              String variableName = variable.name.name;
-              codeName = '$className.$variableName';
-              if (unverifiedDocs.contains(codeName)) {
+              codeName = _extractCodeName(variable);
+              variableName = '$className.${variable.name.name}';
+              if (unverifiedDocs.contains(variableName)) {
                 continue;
               }
-              hasWrittenCodeName = false;
+              hasWrittenVariableName = false;
 
-              int exampleStart = docs.indexOf('#### Example');
+              int exampleStart = docs.indexOf('#### Examples');
               int fixesStart = docs.indexOf('#### Common fixes');
 
               List<_SnippetData> exampleSnippets =
@@ -287,7 +304,7 @@
         _reportProblem('Expected one error but found none ($section $index).');
       } else if (errorCount == 1) {
         AnalysisError error = errors[0];
-        if (error.errorCode.uniqueName != codeName) {
+        if (error.errorCode.name != codeName) {
           _reportProblem('Expected an error with code $codeName, '
               'found ${error.errorCode} ($section $index).');
         }
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 4374529..04c9f2d 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -73,7 +73,7 @@
 referenced using `super`, but there is no concrete implementation of the
 member in the superclass chain. Abstract members can't be invoked.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `B` doesn't inherit a
 concrete implementation of `a`:
@@ -112,7 +112,7 @@
 extended type that's more specific than the extended types of all of the
 other extensions, making the reference to the member ambiguous.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because there's no way to
 choose between the member in `E1` and the member in `E2`:
@@ -161,7 +161,7 @@
 The analyzer produces this diagnostic when a name is referenced that is
 declared in two or more imported libraries.
 
-#### Example
+#### Examples
 
 Given a library (`a.dart`) that defines a class (`C` in this example):
 
@@ -238,7 +238,7 @@
 impossible for the analyzer to determine whether you are writing a map
 literal or a set literal.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -290,7 +290,7 @@
 a type that allows the analyzer to decide whether you were writing a map
 literal or a set literal.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -354,7 +354,7 @@
 The analyzer produces this diagnostic when the static type of an argument
 can't be assigned to the static type of the corresponding parameter.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because a `num` can't be
 assigned to a `String`:
@@ -409,7 +409,7 @@
 setter, but there's no setter because the field with the same name was
 declared to be `final` or `const`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `v` is final:
 
@@ -438,6 +438,41 @@
 }
 {% endprettify %}
 
+### assignment_to_final_local
+
+_The final variable '{0}' can only be set once._
+
+#### Description
+
+The analyzer produces this diagnostic when a local variable that was
+declared to be final is assigned after it was initialized.
+
+#### Examples
+
+The following code produces this diagnostic because `x` is final, so it
+can't have a value assigned to it after it was initialized:
+
+{% prettify dart %}
+void f() {
+  final x = 0;
+  [!x!] = 3;
+  print(x);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the keyword `final`, and replace it with `var` if there's no type
+annotation:
+
+{% prettify dart %}
+void f() {
+  var x = 0;
+  x = 3;
+  print(x);
+}
+{% endprettify %}
+
 ### assignment_to_final_no_setter
 
 _There isn’t a setter named '{0}' in class '{1}'._
@@ -448,7 +483,7 @@
 found; there is no setter defined for the type; but there is a getter
 defined with the same name.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because there is no setter
 named `x` in `C`, but there is a getter named `x`:
@@ -494,6 +529,34 @@
 }
 {% endprettify %}
 
+### assignment_to_method
+
+_Methods can't be assigned a value._
+
+#### Description
+
+The analyzer produces this diagnostic when the target of an assignment is a
+method.
+
+#### Examples
+
+The following code produces this diagnostic because `f` can't be assigned a
+value because it's a method:
+
+{% prettify dart %}
+class C {
+  void f() {}
+
+  void g() {
+    [!f!] = null;
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Rewrite the code so that there isn't an assignment to a method.
+
 ### built_in_identifier_as_extension_name
 
 _The built-in identifier '{0}' can't be used as an extension name._
@@ -503,7 +566,7 @@
 The analyzer produces this diagnostic when the name of an extension is a
 built-in identifier. Built-in identifiers can’t be used as extension names.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `mixin` is a built-in
 identifier:
@@ -516,6 +579,75 @@
 
 Choose a different name for the extension.
 
+### built_in_identifier_as_type
+
+_The built-in identifier '{0}' can't be used as a type._
+
+#### Description
+
+The analyzer produces this diagnostic when a built-in identifier is used
+where a type name is expected.
+
+#### Examples
+
+The following code produces this diagnostic because `import` can't be used
+as a type because it's a built-in identifier:
+
+{% prettify dart %}
+[!import!]<int> x;
+{% endprettify %}
+
+#### Common fixes
+
+Replace the built-in identifier with the name of a valid type:
+
+{% prettify dart %}
+List<int> x;
+{% endprettify %}
+
+### case_block_not_terminated
+
+_The last statement of the 'case' should be 'break', 'continue', 'rethrow',
+'return', or 'throw'._
+
+#### Description
+
+The analyzer produces this diagnostic when the last statement in a case
+block isn't one of the required terminators: `break`, `continue`,
+`rethrow`, `return`, or `throw`.
+
+#### Examples
+
+The following code produces this diagnostic because the case block ends
+with an assignment:
+
+{% prettify dart %}
+void f(int x) {
+  switch (x) {
+    [!case!] 0:
+      x += 2;
+    default:
+      x += 1;
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add one of the required terminators:
+
+{% prettify dart %}
+void f(int x) {
+  switch (x) {
+    case 0:
+      x += 2;
+      break;
+    default:
+      x += 1;
+  }
+}
+{% endprettify %}
+
 ### cast_to_non_type
 
 _The name '{0}' isn't a type, so it can't be used in an 'as' expression._
@@ -525,7 +657,7 @@
 The analyzer produces this diagnostic when the name following the `as` in a
 cast expression is defined to be something other than a type.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is a variable, not
 a type:
@@ -554,7 +686,7 @@
 found that doesn't have a concrete implementation. Concrete classes aren't
 allowed to contain abstract members.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` is an abstract
 method but `C` isn't an abstract class:
@@ -585,6 +717,52 @@
 }
 {% endprettify %}
 
+### const_constructor_with_non_final_field
+
+_Can't define a const constructor for a class with non-final fields._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor is marked as a
+const constructor, but the constructor is defined in a class that has at
+least one non-final instance field (either directly or by inheritance).
+
+#### Examples
+
+The following code produces this diagnostic because the field `x` isn't
+final:
+
+{% prettify dart %}
+class C {
+  int x;
+
+  const [!C!](this.x);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If it's possible to mark all of the fields as final, then do so:
+
+{% prettify dart %}
+class C {
+  final int x;
+
+  const C(this.x);
+}
+{% endprettify %}
+
+If it isn't possible to mark all of the fields as final, then remove the
+keyword `const` from the constructor:
+
+{% prettify dart %}
+class C {
+  int x;
+
+  C(this.x);
+}
+{% endprettify %}
+
 ### const_initialized_with_non_constant_value
 
 _Const variables must be initialized with a constant value._
@@ -595,7 +773,7 @@
 known to be a constant is assigned to a variable that's declared to be a
 'const' variable.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` isn't declared to
 be `const`:
@@ -632,7 +810,7 @@
 The analyzer produces this diagnostic when an instance field is marked as
 being const.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` is an instance
 field:
@@ -671,7 +849,7 @@
 The analyzer produces this diagnostic when a variable that is declared to
 be a constant doesn't have an initializer.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `c` isn't initialized:
 
@@ -697,7 +875,7 @@
 operator in a constant list or set evaluates to something other than a list
 or a set.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the value of `list1` is
 `null`, which is neither a list nor a set:
@@ -726,7 +904,7 @@
 The analyzer produces this diagnostic when the expression of a spread
 operator in a constant map evaluates to something other than a map.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the value of `map1` is
 `null`, which isn't a map:
@@ -754,7 +932,7 @@
 The analyzer produces this diagnostic when the keyword `const` is used to
 invoke a constructor that isn't marked with `const`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the constructor in `A`
 isn't a const constructor:
@@ -800,7 +978,7 @@
 The analyzer produces this diagnostic when a const constructor is invoked
 with an argument that isn't a constant expression.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `i` isn't a constant:
 
@@ -834,7 +1012,7 @@
 The analyzer produces this diagnostic when code is found that won't be
 executed because execution will never reach the code.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the invocation of
 `print` occurs after the function has returned:
@@ -890,7 +1068,7 @@
 object is selected, and both of those forms will match any object, so no
 catch clauses that follow them will be selected.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -941,7 +1119,7 @@
 matches anything matchable by the highlighted clause, so the highlighted
 clause will never be selected.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -989,7 +1167,7 @@
 The analyzer produces this diagnostic when a deprecated library or class
 member is used in a different package.
 
-#### Example
+#### Examples
 
 If the method `m` in the class `C` is annotated with `@deprecated`, then
 the following code produces this diagnostic:
@@ -1016,7 +1194,7 @@
 The analyzer produces this diagnostic when a deprecated library member or
 class member is used in the same package in which it's declared.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is deprecated:
 
@@ -1032,6 +1210,84 @@
 documentation for deprecated declarations should indicate what code to use
 in place of the deprecated code.
 
+### duplicate_constructor
+
+_The constructor with name '{0}' is already defined._
+
+_The default constructor is already defined._
+
+#### Description
+
+The analyzer produces this diagnostic when a class declares more than one
+unnamed constructor or when it declares more than one constructor with the
+same name.
+
+#### Examples
+
+The following code produces this diagnostic because there are two
+declarations for the unnamed constructor:
+
+{% prettify dart %}
+class C {
+  C();
+
+  [!C!]();
+}
+{% endprettify %}
+
+The following code produces this diagnostic because there are two
+declarations for the constructor named `m`:
+
+{% prettify dart %}
+class C {
+  C.m();
+
+  [!C.m!]();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If there are multiple unnamed constructors and all of the constructors are
+needed, then give all of them, or all except one of them, a name:
+
+{% prettify dart %}
+class C {
+  C();
+
+  C.n();
+}
+{% endprettify %}
+
+If there are multiple unnamed constructors and all except one of them are
+unneeded, then remove the constructors that aren't needed:
+
+{% prettify dart %}
+class C {
+  C();
+}
+{% endprettify %}
+
+If there are multiple named constructors and all of the constructors are
+needed, then rename all except one of them:
+
+{% prettify dart %}
+class C {
+  C.m();
+
+  C.n();
+}
+{% endprettify %}
+
+If there are multiple named constructors and all except one of them are
+unneeded, then remove the constructorsthat aren't needed:
+
+{% prettify dart %}
+class C {
+  C.m();
+}
+{% endprettify %}
+
 ### duplicate_definition
 
 _The name '{0}' is already defined._
@@ -1041,7 +1297,7 @@
 The analyzer produces this diagnostic when a name is declared, and there is
 a previous declaration with the same name in the same scope.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `x` is
 declared twice:
@@ -1070,7 +1326,7 @@
 that is the same as an import before it in the file. The second import
 doesn’t add value and should be removed.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -1091,6 +1347,56 @@
 @sealed class C {}
 {% endprettify %}
 
+### duplicate_named_argument
+
+_The argument for the named parameter '{0}' was already specified._
+
+#### Description
+
+The analyzer produces this diagnostic when an invocation has two or more
+named arguments that have the same name.
+
+#### Examples
+
+The following code produces this diagnostic because there are two arguments
+with the name `a`:
+
+{% prettify dart %}
+void f(C c) {
+  c.m(a: 0, [!a!]: 1);
+}
+
+class C {
+  void m({int a, int b}) {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+If one of the arguments should have a different name, then change the name:
+
+{% prettify dart %}
+void f(C c) {
+  c.m(a: 0, b: 1);
+}
+
+class C {
+  void m({int a, int b}) {}
+}
+{% endprettify %}
+
+If one of the arguments is wrong, then remove it:
+
+{% prettify dart %}
+void f(C c) {
+  c.m(a: 1);
+}
+
+class C {
+  void m({int a, int b}) {}
+}
+{% endprettify %}
+
 ### equal_elements_in_const_set
 
 _Two values in a constant set can't be equal._
@@ -1101,7 +1407,7 @@
 literal have the same value. The set can only contain each value once,
 which means that one of the values is unnecessary.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the string `'a'` is
 specified twice:
@@ -1133,7 +1439,7 @@
 second value would overwrite the first value, which makes having both pairs
 pointless.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the key `1` is used
 twice:
@@ -1171,7 +1477,7 @@
 The analyzer produces this diagnostic when the analyzer finds an
 expression, rather than a map entry, in what appears to be a map literal.
 
-#### Example
+#### Examples
 
 The following code generates this diagnostic:
 
@@ -1198,7 +1504,7 @@
 The analyzer produces this diagnostic when an extends clause contains a
 name that is declared to be something other than a class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` is declared to be a
 function:
@@ -1243,7 +1549,7 @@
 representing the type of the class. Extensions, on the other hand, don't
 define a type and can't be used as a type literal.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `E` is an extension:
 
@@ -1281,7 +1587,7 @@
 because it's unclear which member is being referenced by an unqualified use
 of the name within the body of the extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `a` is being
 used for two different members:
@@ -1313,7 +1619,7 @@
 The analyzer produces this diagnostic when an abstract declaration is
 declared in an extension. Extensions can declare only concrete members.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the method `a` doesn't
 have a body:
@@ -1339,7 +1645,7 @@
 extensions aren't classes, and it isn't possible to create an instance of
 an extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because there is a constructor
 declaration in `E`:
@@ -1364,7 +1670,7 @@
 found in an extension. It isn't valid to define an instance field because
 extensions can only add behavior, not state.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `s` is an instance
 field:
@@ -1392,7 +1698,7 @@
 `Object`. Such a member can never be used because the member in `Object` is
 always found first.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `toString` is defined
 by `Object`:
@@ -1426,7 +1732,7 @@
 classes, the static members of an extension should be accessed using the
 name of the extension, not an extension override.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` is static:
 
@@ -1464,7 +1770,7 @@
 The analyzer produces this diagnostic when the argument to an extension
 override isn't assignable to the type being extended by the extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `3` isn't a `String`:
 
@@ -1508,7 +1814,7 @@
 extension override syntax doesn't have any runtime semantics; it only
 controls which member is selected at compile time.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `E(i)` isn't an
 expression:
@@ -1562,7 +1868,7 @@
 `e..m` is the value of the target `e`, but extension overrides are not
 expressions and don't have a value.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `E(3)` isn't an
 expression:
@@ -1601,7 +1907,7 @@
 The analyzer produces this diagnostic when a method or function invocation
 has more positional arguments than the method or function allows.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` defines 2
 parameters but is invoked with 3 arguments:
@@ -1634,7 +1940,7 @@
 has more positional arguments than the method or function allows, but the
 method or function defines named parameters.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` defines 2
 positional parameters but has a named parameter that could be used for the
@@ -1678,7 +1984,7 @@
 The analyzer produces this diagnostic when a final field or variable isn't
 initialized.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` doesn't have an
 initializer:
@@ -1733,7 +2039,7 @@
 initialized when the instance is created, either by the field's initializer
 or by the constructor.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -1816,7 +2122,7 @@
 The analyzer produces this diagnostic when the expression following `in` in
 a for-in loop has a type that isn't a subclass of `Iterable`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` is a `Map`, and
 `Map` isn't a subclass of `Iterable`:
@@ -1851,7 +2157,7 @@
 clause of a class or mixin declaration is defined to be something other
 than a class or mixin.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is a variable
 rather than a class or mixin:
@@ -1884,7 +2190,7 @@
 The analyzer produces this diagnostic when a single class is specified more
 than once in an implements clause.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `A` is in the list
 twice:
@@ -1912,7 +2218,7 @@
 The analyzer produces this diagnostic when it finds a reference to an
 instance member in a constructor's initializer list.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `defaultX` is an
 instance member:
@@ -1965,7 +2271,7 @@
 Constructors can't initialize fields that aren't declared and fields that
 are inherited from superclasses.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the initializer is
 initializing `x`, but `x` isn't a field in the class:
@@ -2013,7 +2319,7 @@
 initialized. Constructors can't initialize fields that aren't declared and
 fields that are inherited from superclasses.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the field `x` isn't
 defined:
@@ -2072,6 +2378,44 @@
 }
 {% endprettify %}
 
+### instance_access_to_static_member
+
+_Static {1} '{0}' can't be accessed through an instance._
+
+#### Description
+
+The analyzer produces this diagnostic when an access operator is used to
+access a static member through an instance of the class.
+
+#### Examples
+
+The following code produces this diagnostic because `zero` is a static
+field, but it’s being accessed as if it were an instance field:
+
+{% prettify dart %}
+void f(C c) {
+  c.[!zero!];
+}
+
+class C {
+  static int zero = 0;
+}
+{% endprettify %}
+
+#### Common fixes
+
+Use the class to access the static member:
+
+{% prettify dart %}
+void f(C c) {
+  C.zero;
+}
+
+class C {
+  static int zero = 0;
+}
+{% endprettify %}
+
 ### instance_member_access_from_factory
 
 _Instance members can't be accessed from a factory constructor._
@@ -2086,7 +2430,7 @@
 factory constructor, the instance isn't created before executing the body,
 so `this` can't be used to reference it.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` isn't in scope in
 the factory constructor:
@@ -2124,7 +2468,7 @@
 The analyzer produces this diagnostic when a static method contains an
 unqualified reference to an instance member.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the instance field `x`
 is being referenced in a static method:
@@ -2178,7 +2522,7 @@
 though you can't create an instance of an abstract class, abstract classes
 can declare constructors that can be invoked by subclasses.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `C` is an abstract
 class:
@@ -2204,7 +2548,7 @@
 that is assigned to a variable isn't assignable to the type of the
 variable.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the type of the
 initializer (`int`) isn't assignable to the type of the variable
@@ -2248,7 +2592,7 @@
 the value of `this` within the extension method, so there must be one
 argument.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because there are no arguments:
 
@@ -2299,7 +2643,7 @@
 The analyzer produces this diagnostic when the name of a factory
 constructor isn't the same as the name of the surrounding class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name of the factory
 constructor (`A`) isn't the same as the surrounding class (`C`):
@@ -2357,7 +2701,7 @@
 The analyzer produces this diagnostic when the `@literal` annotation is
 applied to anything other than a const constructor.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the constructor is not
 a `const` constructor:
@@ -2422,7 +2766,7 @@
 * The return type of the override is assignable to the return type of the
   overridden member.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the type of the
 parameter `s` (`String`) isn't assignable to the type of the parameter `i`
@@ -2477,7 +2821,7 @@
 only defined in the context of an instance method or a generative
 constructor.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `v` is a top-level
 variable:
@@ -2499,6 +2843,28 @@
 class C {}
 {% endprettify %}
 
+### invalid_uri
+
+_Invalid URI syntax: '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a URI in a directive doesn't
+conform to the syntax of a valid URI.
+
+#### Examples
+
+The following code produces this diagnostic because `'#'` isn't a valid
+URI:
+
+{% prettify dart %}
+import [!'#'!];
+{% endprettify %}
+
+#### Common fixes
+
+Replace the invalid URI with a valid URI.
+
 ### invalid_use_of_covariant_in_extension
 
 _Can't have modifier '#lexeme' in an extension._
@@ -2510,7 +2876,7 @@
 Extensions aren't classes and don't have subclasses, so the keyword serves
 no purpose.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `i` is marked as being
 covariant:
@@ -2541,7 +2907,7 @@
 The analyzer produces this diagnostic when either the `@visibleForTemplate`
 or `@visibleForTesting` annotation is applied to a non-public declaration.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -2586,7 +2952,7 @@
 The analyzer produces this diagnostic when an extension override is used to
 invoke a function but the extension doesn't declare a `call` method.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the extension `E`
 doesn't define a `call` method:
@@ -2629,7 +2995,7 @@
 but the name of the function being invoked is defined to be something other
 than a function.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `Binary` is the name of
 a function type, not a function:
@@ -2656,7 +3022,7 @@
 but the name being referenced isn't the name of a function, or when the
 expression computing the function doesn't compute a function.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` isn't a function:
 
@@ -2702,7 +3068,7 @@
 The analyzer produces this diagnostic when the type of an element in a list
 literal isn't assignable to the element type of the list.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `2.5` is a double, and
 the list can hold only integers:
@@ -2742,7 +3108,7 @@
 The analyzer produces this diagnostic when a map entry (a key/value pair)
 is found in a set literal.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the literal has a map
 entry even though it's a set literal:
@@ -2781,7 +3147,7 @@
 The analyzer produces this diagnostic when a key of a key-value pair in a
 map literal has a type that isn't assignable to the key type of the map.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `2` is an `int`, but
 the keys of the map are required to be `String`s:
@@ -2815,7 +3181,7 @@
 map literal has a type that isn't assignable to the the value type of the
 map.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `2` is an `int`, but/
 the values of the map are required to be `String`s:
@@ -2851,7 +3217,7 @@
 Note that `null` is always a possible value for an enum and therefore also
 must be handled.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the enum constant `e2`
 isn't handled:
@@ -2913,7 +3279,7 @@
 named parameter that is annotated as being required is invoked without
 providing a value for the parameter.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the named parameter `x`
 is required:
@@ -2953,7 +3319,7 @@
 throw implicitly returns `null`. This is rarely the desired behavior. The
 analyzer produces this diagnostic when it finds an implicit return.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` doesn't end with a
 return:
@@ -2980,7 +3346,7 @@
 The analyzer produces this diagnostic when a name in a mixin clause is
 defined to be something other than a mixin or a class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `F` is defined to be a
 function type:
@@ -3013,7 +3379,7 @@
 Classes that are sealed can't be extended, implemented, mixed in, or used
 as a superclass constraint.
 
-#### Example
+#### Examples
 
 If the package 'p' defines a sealed class:
 
@@ -3048,7 +3414,7 @@
 The analyzer produces this diagnostic when a type following the `on`
 keyword in a mixin declaration is neither a class nor a mixin.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `F` is neither a class
 nor a mixin:
@@ -3078,7 +3444,7 @@
 marked as being immutable using the annotation `@immutable` or if it's a
 subclass of an immutable class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the field `x` isn't
 final:
@@ -3120,6 +3486,56 @@
 }
 {% endprettify %}
 
+### must_call_super
+
+_This method overrides a method annotated as '@mustCallSuper' in '{0}', but
+doesn't invoke the overridden method._
+
+#### Description
+
+The analyzer produces this diagnostic when a method that overrides a method
+that is annotated as `@mustCallSuper` doesn't invoke the overridden method
+as required.
+
+#### Examples
+
+The following code produces this diagnostic because the method `m` in `B`
+doesn't invoke the overridden method `m` in `A`:
+
+{% prettify dart %}
+import 'package:meta/meta.dart';
+
+class A {
+  @mustCallSuper
+  m() {}
+}
+
+class B extends A {
+  @override
+  [!m!]() {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add an invocation of the overridden method in the overriding method:
+
+{% prettify dart %}
+import 'package:meta/meta.dart';
+
+class A {
+  @mustCallSuper
+  m() {}
+}
+
+class B extends A {
+  @override
+  m() {
+    super.m();
+  }
+}
+{% endprettify %}
+
 ### new_with_undefined_constructor_default
 
 _The class '{0}' doesn't have a default constructor._
@@ -3130,7 +3546,7 @@
 invoked on a class that defines named constructors but the class doesn’t
 have an unnamed constructor.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `A` doesn't define an
 unnamed constructor:
@@ -3185,7 +3601,7 @@
 more abstract members, and doesn't provide or inherit an implementation for
 at least one of those abstract members.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the class `B` doesn't
 have a concrete implementation of `m`:
@@ -3248,7 +3664,7 @@
 The analyzer produces this diagnostic when a condition, such as an `if` or
 `while` loop, doesn't have the static type `bool`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` has the static type
 `int`:
@@ -3282,7 +3698,7 @@
 The analyzer produces this diagnostic when the first expression in an
 assert has a type other than `bool`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the type of `p` is
 `int`, but a `bool` is required:
@@ -3312,7 +3728,7 @@
 The analyzer produces this diagnostic when the operand of the unary
 negation operator (`!`) doesn't have the type `bool`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is an `int` when it
 must be a `bool`:
@@ -3340,7 +3756,7 @@
 The analyzer produces this diagnostic when one of the operands of either
 the `&&` or `||` operator doesn't have the type `bool`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `a` isn't a Boolean
 value:
@@ -3368,7 +3784,7 @@
 The analyzer produces this diagnostic when the expression in a case clause
 isn't a constant expression.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `j` isn't a constant:
 
@@ -3405,7 +3821,7 @@
 named or positional, has a default value that isn't a compile-time
 constant.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -3447,7 +3863,7 @@
 explicitly (because it's prefixed by the `const` keyword) or implicitly
 (because it appears in a [constant context](#constant-context)).
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` isn't a constant,
 even though it appears in an implicitly constant list literal:
@@ -3487,7 +3903,7 @@
 The analyzer produces this diagnostic when an if element or a spread
 element in a constant map isn't a constant element.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because it is attempting to
 spread a non-constant map:
@@ -3533,7 +3949,7 @@
 The analyzer produces this diagnostic when a key in a constant map literal
 isn't a constant value.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic beause `a` isn't a constant:
 
@@ -3568,7 +3984,7 @@
 The analyzer produces this diagnostic when a value in a constant map
 literal isn't a constant value.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `a` isn't a constant:
 
@@ -3603,7 +4019,7 @@
 The analyzer produces this diagnostic when a constant set literal contains
 an element that isn't a compile-time constant.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `i` isn't a constant:
 
@@ -3647,7 +4063,7 @@
 that the constructor should be used to create a constant value whenever
 possible.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic:
 
@@ -3686,7 +4102,7 @@
 The analyzer produces this diagnostic when an identifier that isn't a type
 is used as a type argument.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is a variable, not
 a type:
@@ -3705,6 +4121,44 @@
 List<int> xList = [];
 {% endprettify %}
 
+### non_type_in_catch_clause
+
+_The name '{0}' isn't a type and can't be used in an on-catch clause._
+
+#### Description
+
+The analyzer produces this diagnostic when the identifier following the
+`on` in a catch clause is defined to be something other than a type.
+
+#### Examples
+
+The following code produces this diagnostic because `f` is a function, not
+a type:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } on [!f!] {
+    // ...
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Change the name to the type of object that should be caught:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } on FormatException {
+    // ...
+  }
+}
+{% endprettify %}
+
 ### not_a_type
 
 _{0} isn't a type._
@@ -3714,7 +4168,7 @@
 The analyzer produces this diagnostic when a name is used as a type but
 declared to be something other than a type.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` is a function:
 
@@ -3737,7 +4191,7 @@
 has fewer positional arguments than the number of required positional
 parameters.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` declares two
 required parameters, but only one argument is provided:
@@ -3770,7 +4224,7 @@
 expression of a spread element that appears in either a list literal or a
 set literal doesn't implement the type `Iterable`.
 
-#### Example
+#### Examples
 
 The following code generates this diagnostic:
 
@@ -3799,7 +4253,7 @@
 expression of a spread element that appears in a map literal doesn't
 implement the type `Map`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `l` isn't a `Map`:
 
@@ -3818,6 +4272,45 @@
 var m = <int, String>{...l.asMap()};
 {% endprettify %}
 
+### no_annotation_constructor_arguments
+
+_Annotation creation must have arguments._
+
+#### Description
+
+The analyzer produces this diagnostic when an annotation consists of a
+single identifier, but that identifier is the name of a class rather than a
+variable. To create an instance of the class, the identifier must be
+followed by an argument list.
+
+#### Examples
+
+The following code produces this diagnostic because `C` is a class, and a
+class can't be used as an annotation without invoking a `const` constructor
+from the class:
+
+{% prettify dart %}
+class C {
+  const C();
+}
+
+[!@C!]
+var x;
+{% endprettify %}
+
+#### Common fixes
+
+Add the missing argument list:
+
+{% prettify dart %}
+class C {
+  const C();
+}
+
+@C()
+var x;
+{% endprettify %}
+
 ### override_on_non_overriding_member
 
 _The field doesn't override an inherited getter or setter._
@@ -3834,7 +4327,7 @@
 the `@override` annotation, but the member isn’t declared in any of the
 supertypes of the class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` isn't declared in
 any of the supertypes of `C`:
@@ -3872,7 +4365,7 @@
 The analyzer produces this diagnostic when a part directive is found and
 the referenced file doesn't have a part-of directive.
 
-#### Example
+#### Examples
 
 Given a file (`a.dart`) containing:
 
@@ -3905,6 +4398,132 @@
 import 'a.dart';
 {% endprettify %}
 
+### redirect_to_invalid_function_type
+
+_The redirected constructor '{0}' has incompatible parameters with '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a factory constructor attempts
+to redirect to another constructor, but the two have incompatible
+parameters. The parameters are compatible if all of the parameters of the
+redirecting constructor can be passed to the other constructor and if the
+other constructor doesn't require any parameters that aren't declared by
+the redirecting constructor.
+
+#### Examples
+
+The following code produces this diagnostic because the constructor for `A`
+doesn't declare a parameter that the constructor for `B` requires:
+
+{% prettify dart %}
+abstract class A {
+  factory A() = [!B!];
+}
+
+class B implements A {
+  B(int x);
+  B.zero();
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the constructor for `A`
+declares a named parameter (`y`) that the constructor for `B` doesn't
+allow:
+
+{% prettify dart %}
+abstract class A {
+  factory A(int x, {int y}) = [!B!];
+}
+
+class B implements A {
+  B(int x);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If there's a different constructor that is compatible with the redirecting
+constructor, then redirect to that constructor:
+
+{% prettify dart %}
+abstract class A {
+  factory A() = B.zero;
+}
+
+class B implements A {
+  B(int x);
+  B.zero();
+}
+{% endprettify %}
+
+Otherwise, update the redirecting constructor to be compatible:
+
+{% prettify dart %}
+abstract class A {
+  factory A(int x) = B;
+}
+
+class B implements A {
+  B(int x);
+}
+{% endprettify %}
+
+### redirect_to_invalid_return_type
+
+_The return type '{0}' of the redirected constructor isn't assignable to '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a factory constructor redirects
+to a constructor whose return type isn't a subtype of the type that the
+factory constructor is declared to produce.
+
+#### Examples
+
+The following code produces this diagnostic because `A` isn't a subclass
+of `C`, which means that the value returned by the constructor `A()`
+couldn't be returned from the constructor `C()`:
+
+{% prettify dart %}
+class A {}
+
+class B implements C {}
+
+class C {
+  factory C() = [!A!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the factory constructor is redirecting to a constructor in the wrong
+class, then update the factory constructor to redirect to the correct
+constructor:
+
+{% prettify dart %}
+class A {}
+
+class B implements C {}
+
+class C {
+  factory C() = B;
+}
+{% endprettify %}
+
+If the class defining the constructor being redirected to is the class that
+should be returned, then make it a subtype of the factory's return type:
+
+{% prettify dart %}
+class A implements C {}
+
+class B implements C {}
+
+class C {
+  factory C() = A;
+}
+{% endprettify %}
+
 ### redirect_to_non_class
 
 _The name '{0}' isn't a type and can't be used in a redirected constructor._
@@ -3916,7 +4535,7 @@
 produces this diagnostic when the redirect is to something other than a
 constructor.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` is a function:
 
@@ -3961,7 +4580,7 @@
 The analyzer also produces a context message that indicates where the
 declaration is located.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `i` is used before it
 is declared:
@@ -4010,7 +4629,7 @@
 The analyzer produces this diagnostic when a method or function returns a
 value whose type isn't assignable to the declared return type.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` has a return type
 of `String` but is returning an `int`:
@@ -4044,7 +4663,7 @@
 expression isn't assignable to the return type that the closure is required
 to have.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` is defined to be a
 function that returns a `String`, but the closure assigned to it returns an
@@ -4063,6 +4682,36 @@
 String Function(String) f = (s) => 3.toString();
 {% endprettify %}
 
+### return_without_value
+
+_The  return value is missing after 'return'._
+
+#### Description
+
+The analyzer produces this diagnostic when it finds a return statement
+without an expression in a function that declares a return type.
+
+#### Examples
+
+The following code produces this diagnostic because the function `f` is
+expected to return an `int`, but no value is being returned:
+
+{% prettify dart %}
+int f() {
+  [!return!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add an expression that computes the value to be returned:
+
+{% prettify dart %}
+int f() {
+  return 0;
+}
+{% endprettify %}
+
 ### sdk_version_async_exported_from_core
 
 _The class '{0}' wasn't exported from 'dart:core' until version 2.1, but this
@@ -4076,7 +4725,7 @@
 earlier versions, these classes weren't defined in `dart:core`, so the
 import was necessary.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.1.0:
@@ -4126,7 +4775,7 @@
 versions, so this code won't be able to run against earlier versions of the
 SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.3.2:
@@ -4177,7 +4826,7 @@
 [constant context](#constant-context) wasn't supported in earlier versions,
 so this code won't be able to run against earlier versions of the SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.3.2:
@@ -4230,7 +4879,7 @@
 supported in earlier versions, so this code won't be able to run against
 earlier versions of the SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.3.2:
@@ -4284,7 +4933,7 @@
 versions, so this code won't be able to run against earlier versions of the
 SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.6.0:
@@ -4340,7 +4989,7 @@
 versions, so this code won't be able to run against earlier versions of the
 SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.3.2:
@@ -4390,7 +5039,7 @@
 literals weren't supported in earlier versions, so this code won't be able
 to run against earlier versions of the SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.2.0:
@@ -4437,7 +5086,7 @@
 versions, so this code won't be able to run against earlier versions of the
 SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.3.0:
@@ -4493,7 +5142,7 @@
 supported in earlier versions, so this code won't be able to run against
 earlier versions of the SDK.
 
-#### Example
+#### Examples
 
 Here's an example of a pubspec that defines an SDK constraint with a lower
 bound of less than 2.5.0:
@@ -4547,7 +5196,7 @@
 an instance field. Instance fields don't exist on a class; they exist only
 on an instance of the class.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `x` is an instance
 field:
@@ -4601,7 +5250,7 @@
 extension uses the `super` keyword . Extensions aren't classes and don't
 have superclasses, so the `super` keyword serves no purpose.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `super` can't be used
 in an extension:
@@ -4622,6 +5271,30 @@
 }
 {% endprettify %}
 
+### super_in_invalid_context
+
+_Invalid context for 'super' invocation._
+
+#### Description
+
+The analyzer produces this diagnostic when the keyword `super` is used
+outside of a instance method.
+
+#### Examples
+
+The following code produces this diagnostic because `super` is used in a
+top-level function:
+
+{% prettify dart %}
+void f() {
+  [!super!].f();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Rewrite the code to not use `super`.
+
 ### type_argument_not_matching_bounds
 
 _'{0}' doesn't extend '{1}'._
@@ -4631,7 +5304,7 @@
 The analyzer produces this diagnostic when a type argument isn't the same
 as or a subclass of the bounds of the corresponding type parameter.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `String` isn't a
 subclass of `num`:
@@ -4661,7 +5334,7 @@
 The analyzer produces this diagnostic when the name following the `is` in a
 type test expression isn't defined.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `Srting` isn't
 defined:
@@ -4695,7 +5368,7 @@
 The analyzer produces this diagnostic when a name that isn't defined is
 used as an annotation.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `undefined`
 isn't defined:
@@ -4736,7 +5409,7 @@
 appears to be the name of a class but either isn't defined or isn't visible
 in the scope in which it's being referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `Piont` isn't defined:
 
@@ -4761,6 +5434,71 @@
 If the class is defined but isn't visible, then you probably need to add an
 import.
 
+### undefined_constructor_in_initializer
+
+_The class '{0}' doesn't have a constructor named '{1}'._
+
+_The class '{0}' doesn't have an unnamed constructor._
+
+#### Description
+
+The analyzer produces this diagnostic when a superclass constructor is
+invoked in the initializer list of a constructor, but the superclass
+doesn't define the constructor being invoked.
+
+#### Examples
+
+The following code produces this diagnostic because `A` doesn't have an
+unnamed constructor:
+
+{% prettify dart %}
+class A {
+  A.n();
+}
+class B extends A {
+  B() : [!super()!];
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `A` doesn't have a
+constructor named `m`:
+
+{% prettify dart %}
+class A {
+  A.n();
+}
+class B extends A {
+  B() : [!super.m()!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the superclass defines a constructor that should be invoked, then change
+the constructor being invoked:
+
+{% prettify dart %}
+class A {
+  A.n();
+}
+class B extends A {
+  B() : super.n();
+}
+{% endprettify %}
+
+If the superclass doesn't define an appropriate constructor, then define
+the constructor being invoked:
+
+{% prettify dart %}
+class A {
+  A.m();
+  A.n();
+}
+class B extends A {
+  B() : super.m();
+}
+{% endprettify %}
+
 ### undefined_extension_getter
 
 _The getter '{0}' isn't defined for the extension '{1}'._
@@ -4772,7 +5510,7 @@
 The analyzer also produces this diagnostic when a static getter is
 referenced but isn't defined by the specified extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the extension `E`
 doesn't declare an instance getter named `b`:
@@ -4865,7 +5603,7 @@
 The analyzer also produces this diagnostic when a static method is
 referenced but isn't defined by the specified extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the extension `E`
 doesn't declare an instance method named `b`:
@@ -4958,7 +5696,7 @@
 The analyzer also produces this diagnostic when a static setter is
 referenced but isn't defined by the specified extension.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the extension `E`
 doesn't declare an instance setter named `b`:
@@ -5052,7 +5790,7 @@
 appears to be the name of a function but either isn't defined or isn't
 visible in the scope in which it's being referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `emty` isn't
 defined:
@@ -5092,7 +5830,7 @@
 appears to be the name of a getter but either isn't defined or isn't
 visible in the scope in which it's being referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `String` has no member
 named `len`:
@@ -5111,6 +5849,37 @@
 int f(String s) => s.length;
 {% endprettify %}
 
+### undefined_hidden_name
+
+_The library '{0}' doesn't export a member with the hidden name '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a hide combinator includes a
+name that isn't defined by the library being imported.
+
+#### Examples
+
+The following code produces this diagnostic because `dart:math` doesn't
+define the name `String`:
+
+{% prettify dart %}
+import 'dart:math' hide [!String!], max;
+
+var x = min(0, 1);
+{% endprettify %}
+
+#### Common fixes
+
+If a different name should be hidden, then correct the name. Otherwise,
+remove the name from the list:
+
+{% prettify dart %}
+import 'dart:math' hide max;
+
+var x = min(0, 1);
+{% endprettify %}
+
 ### undefined_identifier
 
 _Undefined name '{0}'._
@@ -5121,7 +5890,7 @@
 either isn't defined or isn't visible in the scope in which it's being
 referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the name `rihgt` isn't
 defined:
@@ -5153,7 +5922,7 @@
 appears to be the name of a method but either isn't defined or isn't
 visible in the scope in which it's being referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the identifier
 `removeMiddle` isn't defined:
@@ -5182,7 +5951,7 @@
 has a named argument, but the method or function being invoked doesn't
 define a parameter with the same name.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` doesn't declare a
 named parameter named `a`:
@@ -5250,7 +6019,7 @@
 The analyzer produces this diagnostic when a user-definable operator is
 invoked on an object for which the operator isn't defined.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the class `C` doesn't
 define the operator `+`:
@@ -5284,7 +6053,7 @@
 where the prefix is valid, but the identifier isn't declared in any of the
 libraries imported using that prefix.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `dart:core` doesn't
 define anything named `a`:
@@ -5315,7 +6084,7 @@
 appears to be the name of a setter but either isn't defined or isn't
 visible in the scope in which the identifier is being referenced.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because there isn't a setter
 named `z`:
@@ -5344,6 +6113,37 @@
 }
 {% endprettify %}
 
+### undefined_shown_name
+
+_The library '{0}' doesn't export a member with the shown name '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when a show combinator includes a
+name that isn't defined by the library being imported.
+
+#### Examples
+
+The following code produces this diagnostic because `dart:math` doesn't
+define the name `String`:
+
+{% prettify dart %}
+import 'dart:math' show min, [!String!];
+
+var x = min(0, 1);
+{% endprettify %}
+
+#### Common fixes
+
+If a different name should be shown, then correct the name. Otherwise,
+remove the name from the list:
+
+{% prettify dart %}
+import 'dart:math' show min;
+
+var x = min(0, 1);
+{% endprettify %}
+
 ### undefined_super_method
 
 _The method '{0}' isn't defined in a superclass of '{1}'._
@@ -5354,7 +6154,7 @@
 referenced using `super`, but there’s no method with that name in the
 superclass chain.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `Object` doesn't define
 a member named `n`:
@@ -5378,6 +6178,40 @@
 If not, then either add the method to one of the superclasses or remove the
 invocation.
 
+### unnecessary_cast
+
+_Unnecessary cast._
+
+#### Description
+
+The analyzer produces this diagnostic when the value being cast is already
+known to be of the type that it's being cast to.
+
+#### Examples
+
+The following code produces this diagnostic because `n` is already known to
+be an `int` as a result of the `is` test:
+
+{% prettify dart %}
+void f(num n) {
+  if (n is int) {
+    ([!n as int!]).isEven;
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the unnecessary cast:
+
+{% prettify dart %}
+void f(num n) {
+  if (n is int) {
+    n.isEven;
+  }
+}
+{% endprettify %}
+
 ### unqualified_reference_to_static_member_of_extended_type
 
 _Static members from the extended type or one of its superclasses must be
@@ -5389,7 +6223,7 @@
 the name is the same as a static member of the extended type or one of its
 superclasses.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `m` is a static member
 of the extended type `C`:
@@ -5440,6 +6274,83 @@
 }
 {% endprettify %}
 
+### unused_catch_clause
+
+_The exception variable '{0}' isn't used, so the 'catch' clause can be removed._
+
+#### Description
+
+The analyzer produces this diagnostic when a catch clause is found, and
+neither the exception parameter nor the optional stack trace parameter are
+used in the catch block.
+
+#### Examples
+
+The following code produces this diagnostic because `e` isn't referenced:
+
+{% prettify dart %}
+void f() {
+  try {
+    int.parse(';');
+  } on FormatException catch ([!e!]) {
+    // ignored
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the unused catch clause:
+
+{% prettify dart %}
+void f() {
+  try {
+    int.parse(';');
+  } on FormatException {
+    // ignored
+  }
+}
+{% endprettify %}
+
+### unused_catch_stack
+
+_The stack trace variable '{0}' isn't used and can be removed._
+
+#### Description
+
+The analyzer produces this diagnostic when the stack trace parameter in a
+catch clause isn't referenced within the body of the catch block.
+
+#### Examples
+
+The following code produces this diagnostic because `stackTrace` isn't
+referenced:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } catch (exception, [!stackTrace!]) {
+    // ...
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the stack trace parameter, then add a reference to
+it. Otherwise, remove it:
+
+{% prettify dart %}
+void f() {
+  try {
+    // ...
+  } catch (exception) {
+    // ...
+  }
+}
+{% endprettify %}
+
 ### unused_element
 
 _The declaration '{0}' isn't referenced._
@@ -5450,7 +6361,7 @@
 typedef, top level variable, top level function, or method is declared but
 never referenced.
 
-#### Example
+#### Examples
 
 Assuming that no code in the library references `_C`, the following code
 produces this diagnostic:
@@ -5474,7 +6385,7 @@
 The analyzer produces this diagnostic when a private field is declared but
 never read, even if it's written in one or more places.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `_x` isn't referenced
 anywhere in the library:
@@ -5501,7 +6412,7 @@
 none of the names that are imported are referenced within the importing
 library.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because nothing defined in
 `dart:async` is referenced in the library:
@@ -5519,6 +6430,51 @@
 If some of the imported names are intended to be used, then add the missing
 code.
 
+### unused_label
+
+_The label '{0}' isn't used._
+
+#### Description
+
+The analyzer produces this diagnostic when a label that isn't used is
+found.
+
+#### Examples
+
+The following code produces this diagnostic because the label `loop` isn't
+referenced anywhere in the method:
+
+{% prettify dart %}
+void f(int limit) {
+  [!loop:!] for (int i = 0; i < limit; i++) {
+    print(i);
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the label isn't needed, then remove it:
+
+{% prettify dart %}
+void f(int limit) {
+  for (int i = 0; i < limit; i++) {
+    print(i);
+  }
+}
+{% endprettify %}
+
+If the label is needed, then use it:
+
+{% prettify dart %}
+void f(int limit) {
+  loop: for (int i = 0; i < limit; i++) {
+    print(i);
+    break loop;
+  }
+}
+{% endprettify %}
+
 ### unused_local_variable
 
 _The value of the local variable '{0}' isn't used._
@@ -5528,7 +6484,7 @@
 The analyzer produces this diagnostic when a local variable is declared but
 never read, even if it's written in one or more places.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the value of `count` is
 never read:
@@ -5545,6 +6501,37 @@
 
 If the variable was intended to be used, then add the missing code.
 
+### unused_shown_name
+
+_The name {0} is shown, but isn’t used._
+
+#### Description
+
+The analyzer produces this diagnostic when a show combinator includes a
+name that isn't used within the library. Because it isn't referenced, the
+name can be removed.
+
+#### Examples
+
+The following code produces this diagnostic because the function `max`
+isn't used:
+
+{% prettify dart %}
+import 'dart:math' show min, [!max!];
+
+var x = min(0, 1);
+{% endprettify %}
+
+#### Common fixes
+
+Either use the name or remove it:
+
+{% prettify dart %}
+import 'dart:math' show min;
+
+var x = min(0, 1);
+{% endprettify %}
+
 ### uri_does_not_exist
 
 _Target of URI doesn't exist: '{0}'._
@@ -5554,7 +6541,7 @@
 The analyzer produces this diagnostic when an import, export, or part
 directive is found where the URI refers to a file that doesn't exist.
 
-#### Example
+#### Examples
 
 If the file `lib.dart` doesn't exist, the following code produces this
 diagnostic:
@@ -5586,7 +6573,7 @@
 - `.pbjson.dart`
 - `.template.dart`
 
-#### Example
+#### Examples
 
 If the file `lib.g.dart` doesn't exist, the following code produces this
 diagnostic:
@@ -5614,7 +6601,7 @@
 expected, such as before a member access or on the right-hand side of an
 assignment.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `f` doesn't produce an
 object on which `toString` can be invoked:
@@ -5641,7 +6628,7 @@
 The analyzer produces this diagnostic when the evaluation of a constant
 expression would result in a `CastException`.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the value of `x` is an
 `int`, which can't be assigned to `y` because an `int` isn't a `String`:
@@ -5678,7 +6665,7 @@
 The analyzer produces this diagnostic when a declaration of an operator has
 the wrong number of parameters.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because the operator `+` must
 have a single parameter corresponding to the right operand:
@@ -5699,6 +6686,46 @@
 }
 {% endprettify %}
 
+### wrong_number_of_parameters_for_setter
+
+_Setters must declare exactly one required positional parameter._
+
+#### Description
+
+The analyzer produces this diagnostic when a setter is found that doesn't
+declare exactly one required positional parameter.
+
+#### Examples
+
+The following code produces this diagnostic because the setter `s` declares
+two required parameters:
+
+{% prettify dart %}
+class C {
+  set [!s!](int x, int y) {}
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the setter `s` declares
+one optional parameter:
+
+{% prettify dart %}
+class C {
+  set [!s!]([int x]) {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+Change the declaration so that there's exactly one required positional
+parameter:
+
+{% prettify dart %}
+class C {
+  set s(int x) {}
+}
+{% endprettify %}
+
 ### wrong_number_of_type_arguments
 
 _The type '{0}' is declared with {1} type parameters, but {2} type arguments
@@ -5710,7 +6737,7 @@
 is used and type arguments are provided, but the number of type arguments
 isn't the same as the number of type parameters.
 
-#### Example
+#### Examples
 
 The following code produces this diagnostic because `C` has one type
 parameter but two type arguments are provided:
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index 8292a9f..7bfc71e 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -1,8 +1,14 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import 'dart:io';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/summary/summary_file_builder.dart';
+import 'package:meta/meta.dart';
 
 void main(List<String> args) {
   String command;
@@ -36,8 +42,20 @@
   //
   // Handle commands.
   //
-  if (command == 'build-strong') {
-    _buildSummary(sdkPath, outFilePath);
+  if (command == 'build-non-nullable') {
+    _buildSummary(
+      sdkPath,
+      outFilePath,
+      enabledExperiments: ['non-nullable'],
+      title: 'non-nullable',
+    );
+  } else if (command == 'build-legacy' || command == 'build-strong') {
+    _buildSummary(
+      sdkPath,
+      outFilePath,
+      enabledExperiments: [],
+      title: 'legacy',
+    );
   } else {
     _printUsage();
     return;
@@ -49,10 +67,18 @@
  */
 const BINARY_NAME = "build_sdk_summaries";
 
-void _buildSummary(String sdkPath, String outPath) {
-  print('Generating strong mode summary.');
+void _buildSummary(
+  String sdkPath,
+  String outPath, {
+  @required List<String> enabledExperiments,
+  @required String title,
+}) {
+  print('Generating $title summary.');
   Stopwatch sw = Stopwatch()..start();
-  List<int> bytes = SummaryBuilder.forSdk(sdkPath).build();
+  var featureSet = FeatureSet.fromEnableFlags(enabledExperiments);
+  List<int> bytes = SummaryBuilder.forSdk(sdkPath).build(
+    featureSet: featureSet,
+  );
   File(outPath).writeAsBytesSync(bytes, mode: FileMode.writeOnly);
   print('\tDone in ${sw.elapsedMilliseconds} ms.');
 }
@@ -63,6 +89,8 @@
 void _printUsage() {
   print('Usage: $BINARY_NAME command arguments');
   print('Where command can be one of the following:');
-  print('  build-strong output_file [sdk_path]');
-  print('    Generate strong mode summary file.');
+  print('  build-non-nullable output_file [sdk_path]');
+  print('    Generate non-nullable summary file.');
+  print('  build-legacy output_file [sdk_path]');
+  print('    Generate legacy summary file.');
 }
diff --git a/pkg/analyzer_cli/analysis_options.yaml b/pkg/analyzer_cli/analysis_options.yaml
index 745a8b3..7a3c1f2 100644
--- a/pkg/analyzer_cli/analysis_options.yaml
+++ b/pkg/analyzer_cli/analysis_options.yaml
@@ -13,7 +13,7 @@
     #
     # From pedantic 1.9.0:
     #
-    #- always_declare_return_types # 89
+    - always_declare_return_types
     - always_require_non_null_named_parameters
     - annotate_overrides
     - avoid_empty_else
diff --git a/pkg/analyzer_cli/bin/analyzer.dart b/pkg/analyzer_cli/bin/analyzer.dart
index e039793..3568e65 100644
--- a/pkg/analyzer_cli/bin/analyzer.dart
+++ b/pkg/analyzer_cli/bin/analyzer.dart
@@ -11,7 +11,7 @@
 ///
 /// [sendPort] may be passed in when started in an isolate. If provided, it is
 /// used for bazel worker communication instead of stdin/stdout.
-main(List<String> args, [SendPort sendPort]) async {
+void main(List<String> args, [SendPort sendPort]) async {
   CommandLineStarter starter = CommandLineStarter();
 
   // Wait for the starter to complete.
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index f3dc01d..e92cb2c 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -6,6 +6,7 @@
 import 'dart:io' as io;
 import 'dart:isolate';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
@@ -158,9 +159,12 @@
       print('\nGenerating strong mode summary...');
       final Stopwatch stopwatch = Stopwatch()..start();
 
-      SummaryBuilder.forSdk(options.dartSdkPath).build();
-      SummaryBuilder.forSdk(options.dartSdkPath).build();
-      SummaryBuilder.forSdk(options.dartSdkPath).build();
+      for (var i = 0; i < 3; i++) {
+        var featureSet = FeatureSet.fromEnableFlags([]);
+        SummaryBuilder.forSdk(options.dartSdkPath).build(
+          featureSet: featureSet,
+        );
+      }
 
       print('Done in ${stopwatch.elapsedMilliseconds} ms.');
     }
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 8b7d220a..14abffa 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -563,7 +563,7 @@
     }
   }
 
-  static _showUsage(ArgParser parser, {bool fromHelp = false}) {
+  static void _showUsage(ArgParser parser, {bool fromHelp = false}) {
     errorSink.writeln(
         'Usage: $_binaryName [options...] <directory or list of files>');
 
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index 5cf091b..329bd32 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -14,7 +14,7 @@
 import 'reporter_test.dart' as reporter_test;
 import 'strong_mode_test.dart' as strong_mode_test;
 
-main() {
+void main() {
   analysis_options_test.main();
   build_mode_test.main();
   driver_test.main();
diff --git a/pkg/analyzer_cli/test/analysis_options_test.dart b/pkg/analyzer_cli/test/analysis_options_test.dart
index 8820b05..b3d9a3b 100644
--- a/pkg/analyzer_cli/test/analysis_options_test.dart
+++ b/pkg/analyzer_cli/test/analysis_options_test.dart
@@ -13,7 +13,7 @@
 
 import 'utils.dart' show recursiveCopy, testDirectory, withTempDirAsync;
 
-main() {
+void main() {
   defineReflectiveTests(OptionsTest);
 }
 
@@ -30,7 +30,7 @@
     runner = null;
   }
 
-  test_options() async {
+  Future<void> test_options() async {
     // Copy to temp dir so that existing analysis options
     // in the test directory hierarchy do not interfere
     var projDir = path.join(testDirectory, 'data', 'flutter_analysis_options');
diff --git a/pkg/analyzer_cli/test/build_mode_test.dart b/pkg/analyzer_cli/test/build_mode_test.dart
index 6c98653..fece8a0 100644
--- a/pkg/analyzer_cli/test/build_mode_test.dart
+++ b/pkg/analyzer_cli/test/build_mode_test.dart
@@ -14,7 +14,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-main() {
+void main() {
   defineReflectiveTests(WorkerLoopTest);
 }
 
@@ -47,7 +47,7 @@
 
   void setUp() {}
 
-  test_run() async {
+  Future<void> test_run() async {
     var request = WorkRequest();
     request.arguments.addAll([
       '--build-summary-input=/tmp/1.sum',
@@ -86,7 +86,7 @@
     expect(stdoutStream.writes[0], _serializeProto(response));
   }
 
-  test_run_invalidOptions() async {
+  Future<void> test_run_invalidOptions() async {
     var request = WorkRequest();
     request.arguments.addAll(['--unknown-option', '/foo.dart', '/bar.dart']);
     stdinStream.addInputBytes(_serializeProto(request));
@@ -99,7 +99,7 @@
     expect(response.output, anything);
   }
 
-  test_run_invalidRequest_noArgumentsInputs() async {
+  Future<void> test_run_invalidRequest_noArgumentsInputs() async {
     stdinStream.addInputBytes(_serializeProto(WorkRequest()));
     stdinStream.close();
 
@@ -111,7 +111,7 @@
     expect(response.output, anything);
   }
 
-  test_run_invalidRequest_randomBytes() async {
+  Future<void> test_run_invalidRequest_randomBytes() async {
     stdinStream.addInputBytes([1, 2, 3]);
     stdinStream.close();
     await TestAnalyzerWorkerLoop(connection).run();
@@ -122,7 +122,7 @@
     expect(response.output, anything);
   }
 
-  test_run_stopAtEOF() async {
+  Future<void> test_run_stopAtEOF() async {
     stdinStream.close();
     await TestAnalyzerWorkerLoop(connection).run();
   }
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 40571d1..805f5d9 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -23,7 +23,7 @@
 
 import 'utils.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(BuildModeTest);
     defineReflectiveTests(BuildModeSummaryDependenciesTest);
@@ -218,7 +218,7 @@
   String tempDir;
 
   /// Any direct export is a dependency.
-  test_export_direct() async {
+  Future<void> test_export_direct() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
       await _assertDependencies('c', [a], '''
@@ -229,7 +229,7 @@
 
   /// Imports of dependencies are not necessary dependencies.
   /// Here our dependency does not use its dependency.
-  test_import2_notUsed() async {
+  Future<void> test_import2_notUsed() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], '');
       var b = await _buildPackage('b', [a], '''
@@ -241,7 +241,7 @@
     });
   }
 
-  test_import2_usedAsFieldType() async {
+  Future<void> test_import2_usedAsFieldType() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
       var b = await _buildPackage('b', [a], '''
@@ -286,7 +286,7 @@
     });
   }
 
-  test_import2_usedAsSupertype() async {
+  Future<void> test_import2_usedAsSupertype() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
       var b = await _buildPackage('b', [a], '''
@@ -325,7 +325,7 @@
     });
   }
 
-  test_import2_usedAsTopLevelVariableType() async {
+  Future<void> test_import2_usedAsTopLevelVariableType() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
       var b = await _buildPackage('b', [a], '''
@@ -393,7 +393,7 @@
   }
 
   /// Any direct import is a dependency.
-  test_import_direct() async {
+  Future<void> test_import_direct() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], '');
       var b = await _buildPackage('b', [], '');
@@ -405,7 +405,7 @@
   }
 
   /// Exports of dependencies are dependencies.
-  test_import_export() async {
+  Future<void> test_import_export() async {
     await _withTempDir(() async {
       var a = await _buildPackage('a', [], 'class A {}');
       var b = await _buildPackage('b', [a], '''
@@ -474,7 +474,7 @@
 
 @reflectiveTest
 class BuildModeTest extends AbstractBuildModeTest {
-  test_buildLinked() async {
+  Future<void> test_buildLinked() async {
     await withTempDirAsync((tempDir) async {
       var outputPath = path.join(tempDir, 'test_file.dart.sum');
       await _doDrive(path.join('data', 'test_file.dart'), additionalArgs: [
@@ -498,7 +498,7 @@
     });
   }
 
-  test_buildLinked_invalidPartUri() async {
+  Future<void> test_buildLinked_invalidPartUri() async {
     await withTempDirAsync((tempDir) async {
       var aDart = path.join(tempDir, 'a.dart');
 
@@ -521,19 +521,19 @@
     });
   }
 
-  test_buildSuppressExitCode_fail_whenFileNotFound() async {
+  Future<void> test_buildSuppressExitCode_fail_whenFileNotFound() async {
     await _doDrive(path.join('data', 'non_existent_file.dart'),
         additionalArgs: ['--build-suppress-exit-code']);
     expect(exitCode, isNot(0));
   }
 
-  test_buildSuppressExitCode_success_evenIfHasError() async {
+  Future<void> test_buildSuppressExitCode_success_evenIfHasError() async {
     await _doDrive(path.join('data', 'file_with_error.dart'),
         additionalArgs: ['--build-suppress-exit-code']);
     expect(exitCode, 0);
   }
 
-  test_consumeLinked() async {
+  Future<void> test_consumeLinked() async {
     await withTempDirAsync((tempDir) async {
       var aDart = path.join(tempDir, 'a.dart');
       var bDart = path.join(tempDir, 'b.dart');
@@ -600,7 +600,7 @@
     });
   }
 
-  test_dartSdkSummaryPath_strong() async {
+  Future<void> test_dartSdkSummaryPath_strong() async {
     await withTempDirAsync((tempDir) async {
       String sdkPath = _findSdkDirForSummaries();
       String strongSummaryPath =
@@ -622,7 +622,7 @@
     });
   }
 
-  test_error_notUriPipePath() async {
+  Future<void> test_error_notUriPipePath() async {
     await withTempDirAsync((tempDir) async {
       var testDart = path.join(tempDir, 'test.dart');
       File(testDart).writeAsStringSync('var v = 42;');
@@ -633,12 +633,12 @@
     });
   }
 
-  test_fail_whenHasError() async {
+  Future<void> test_fail_whenHasError() async {
     await _doDrive(path.join('data', 'file_with_error.dart'));
     expect(exitCode, isNot(0));
   }
 
-  test_noStatistics() async {
+  Future<void> test_noStatistics() async {
     await _doDrive(path.join('data', 'test_file.dart'));
     // Should not print statistics summary.
     expect(outSink.toString(), isEmpty);
@@ -646,7 +646,7 @@
     expect(exitCode, 0);
   }
 
-  test_onlyErrors_partFirst() async {
+  Future<void> test_onlyErrors_partFirst() async {
     await withTempDirAsync((tempDir) async {
       var aDart = path.join(tempDir, 'a.dart');
       var bDart = path.join(tempDir, 'b.dart');
@@ -690,7 +690,7 @@
 
 @reflectiveTest
 class ExitCodesTest extends BaseTest {
-  test_bazelWorkspace_relativePath() async {
+  Future<void> test_bazelWorkspace_relativePath() async {
     // Copy to temp dir so that existing analysis options
     // in the test directory hierarchy do not interfere
     await withTempDirAsync((String tempDirPath) async {
@@ -722,38 +722,38 @@
     });
   }
 
-  test_enableAssertInitializer() async {
+  Future<void> test_enableAssertInitializer() async {
     await drive('data/file_with_assert_initializers.dart',
         args: ['--enable-assert-initializers']);
     expect(exitCode, 0);
   }
 
-  test_fatalErrors() async {
+  Future<void> test_fatalErrors() async {
     await drive('data/file_with_error.dart');
     expect(exitCode, 3);
   }
 
-  test_fatalHints() async {
+  Future<void> test_fatalHints() async {
     await drive('data/file_with_hint.dart', args: ['--fatal-hints']);
     expect(exitCode, 1);
   }
 
-  test_missingDartFile() async {
+  Future<void> test_missingDartFile() async {
     await drive('data/NO_DART_FILE_HERE.dart');
     expect(exitCode, 3);
   }
 
-  test_missingOptionsFile() async {
+  Future<void> test_missingOptionsFile() async {
     await drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
     expect(exitCode, 3);
   }
 
-  test_notFatalHints() async {
+  Future<void> test_notFatalHints() async {
     await drive('data/file_with_hint.dart');
     expect(exitCode, 0);
   }
 
-  test_partFile() async {
+  Future<void> test_partFile() async {
     await driveMany([
       path.join(testDirectory, 'data/library_and_parts/lib.dart'),
       path.join(testDirectory, 'data/library_and_parts/part1.dart')
@@ -761,12 +761,12 @@
     expect(exitCode, 0);
   }
 
-  test_partFile_dangling() async {
+  Future<void> test_partFile_dangling() async {
     await drive('data/library_and_parts/part2.dart');
     expect(exitCode, 3);
   }
 
-  test_partFile_extra() async {
+  Future<void> test_partFile_extra() async {
     await driveMany([
       path.join(testDirectory, 'data/library_and_parts/lib.dart'),
       path.join(testDirectory, 'data/library_and_parts/part1.dart'),
@@ -775,7 +775,7 @@
     expect(exitCode, 3);
   }
 
-  test_partFile_reversed() async {
+  Future<void> test_partFile_reversed() async {
     Driver driver = Driver(isTesting: true);
     await driver.start([
       path.join(testDirectory, 'data/library_and_parts/part1.dart'),
@@ -795,7 +795,7 @@
 class LinterTest extends BaseTest {
   String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
 
-  test_containsLintRuleEntry() async {
+  Future<void> test_containsLintRuleEntry() async {
     YamlMap options = _parseOptions('''
 linter:
   rules:
@@ -813,19 +813,19 @@
     expect(containsLintRuleEntry(options), true);
     options = _parseOptions('''
 linter:
- # rules:
+  # rules:
     # - foo
         ''');
     expect(containsLintRuleEntry(options), false);
   }
 
-  test_defaultLints_generatedLints() async {
+  Future<void> test_defaultLints_generatedLints() async {
     await _runLinter_defaultLints();
     expect(bulletToDash(outSink),
         contains('lint - Name types using UpperCamelCase'));
   }
 
-  test_defaultLints_getsDefaultLints() async {
+  Future<void> test_defaultLints_getsDefaultLints() async {
     await _runLinter_defaultLints();
 
     /// Lints should be enabled.
@@ -836,13 +836,13 @@
     expect(lintNames, contains('camel_case_types'));
   }
 
-  test_lintsInOptions_generatedLints() async {
+  Future<void> test_lintsInOptions_generatedLints() async {
     await _runLinter_lintsInOptions();
     expect(bulletToDash(outSink),
         contains('lint - Name types using UpperCamelCase'));
   }
 
-  test_lintsInOptions_getAnalysisOptions() async {
+  Future<void> test_lintsInOptions_getAnalysisOptions() async {
     await _runLinter_lintsInOptions();
 
     /// Lints should be enabled.
@@ -853,17 +853,17 @@
     expect(lintNames, orderedEquals(['camel_case_types']));
   }
 
-  test_noLints_lintsDisabled() async {
+  Future<void> test_noLints_lintsDisabled() async {
     await _runLinter_noLintsFlag();
     expect(analysisOptions.lint, isFalse);
   }
 
-  test_noLints_noGeneratedWarnings() async {
+  Future<void> test_noLints_noGeneratedWarnings() async {
     await _runLinter_noLintsFlag();
     expect(outSink.toString(), contains('No issues found'));
   }
 
-  test_noLints_noRegisteredLints() async {
+  Future<void> test_noLints_noRegisteredLints() async {
     await _runLinter_noLintsFlag();
     expect(analysisOptions.lintRules, isEmpty);
   }
@@ -895,7 +895,7 @@
 
 @reflectiveTest
 class NonDartFilesTest extends BaseTest {
-  test_analysisOptionsYaml() async {
+  Future<void> test_analysisOptionsYaml() async {
     await withTempDirAsync((tempDir) async {
       String filePath =
           path.join(tempDir, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -912,7 +912,7 @@
     });
   }
 
-  test_manifestFileChecks() async {
+  Future<void> test_manifestFileChecks() async {
     await withTempDirAsync((tempDir) async {
       String filePath =
           path.join(tempDir, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -939,7 +939,7 @@
     });
   }
 
-  test_pubspecYaml() async {
+  Future<void> test_pubspecYaml() async {
     await withTempDirAsync((tempDir) async {
       String filePath = path.join(tempDir, AnalysisEngine.PUBSPEC_YAML_FILE);
       File(filePath).writeAsStringSync('''
@@ -967,13 +967,14 @@
   ErrorProcessor processorFor(AnalysisError error) =>
       processors.firstWhere((p) => p.appliesTo(error));
 
-  test_analysisOptions_excludes() async {
+  Future<void> test_analysisOptions_excludes() async {
     await drive('data/exclude_test_project',
         options: 'data/exclude_test_project/$optionsFileName');
     _expectUndefinedClassErrorsWithoutExclusions();
   }
 
-  test_analysisOptions_excludesRelativeToAnalysisOptions_explicit() async {
+  Future<void>
+      test_analysisOptions_excludesRelativeToAnalysisOptions_explicit() async {
     // The exclude is relative to the project, not/ the analyzed path, and it
     // has to then understand that.
     await drive('data/exclude_test_project',
@@ -981,7 +982,8 @@
     _expectUndefinedClassErrorsWithoutExclusions();
   }
 
-  test_analysisOptions_excludesRelativeToAnalysisOptions_inferred() async {
+  Future<void>
+      test_analysisOptions_excludesRelativeToAnalysisOptions_inferred() async {
     // By passing no options, and the path `lib`, it should discover the
     // analysis_options above lib. The exclude is relative to the project, not
     // the analyzed path, and it has to then understand that.
@@ -989,7 +991,7 @@
     _expectUndefinedClassErrorsWithoutExclusions();
   }
 
-  test_analyzeFilesInDifferentContexts() async {
+  Future<void> test_analyzeFilesInDifferentContexts() async {
     await driveMany([
       'data/linter_project/test_file.dart',
       'data/no_lints_project/test_file.dart',
@@ -1004,7 +1006,7 @@
     expect(outSink.toString(), contains('1 lint found.'));
   }
 
-  test_basic_filters() async {
+  Future<void> test_basic_filters() async {
     await _driveBasic();
     expect(processors, hasLength(3));
 
@@ -1026,7 +1028,7 @@
     expect(outSink.toString(), contains('1 error and 1 warning found.'));
   }
 
-  test_includeDirective() async {
+  Future<void> test_includeDirective() async {
     String testDir = path.join(
         testDirectory, 'data', 'options_include_directive_tests_project');
     await drive(
@@ -1045,12 +1047,12 @@
     expect(outSink.toString(), contains('Avoid empty else statements'));
   }
 
-  test_todo() async {
+  Future<void> test_todo() async {
     await drive('data/file_with_todo.dart');
     expect(outSink.toString().contains('[info]'), isFalse);
   }
 
-  test_withFlags_overrideFatalWarning() async {
+  Future<void> test_withFlags_overrideFatalWarning() async {
     await drive('data/options_tests_project/test_file.dart',
         args: ['--fatal-warnings'],
         options: 'data/options_tests_project/$optionsFileName');
@@ -1094,7 +1096,7 @@
   String get fullName => '/package/lib/test.dart';
 
   @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class _DependencyPackage {
diff --git a/pkg/analyzer_cli/test/embedder_test.dart b/pkg/analyzer_cli/test/embedder_test.dart
index b77e768..a088c8e 100644
--- a/pkg/analyzer_cli/test/embedder_test.dart
+++ b/pkg/analyzer_cli/test/embedder_test.dart
@@ -12,7 +12,7 @@
 
 import 'utils.dart';
 
-main() {
+void main() {
   group('_embedder.yaml', () {
     StringSink savedOutSink, savedErrorSink;
     int savedExitCode;
diff --git a/pkg/analyzer_cli/test/errors_reported_once_test.dart b/pkg/analyzer_cli/test/errors_reported_once_test.dart
index deeb052..d110077 100644
--- a/pkg/analyzer_cli/test/errors_reported_once_test.dart
+++ b/pkg/analyzer_cli/test/errors_reported_once_test.dart
@@ -12,7 +12,7 @@
 
 import 'utils.dart';
 
-main() {
+void main() {
   defineReflectiveTests(ErrorsReportedOnceTest);
 }
 
@@ -39,7 +39,7 @@
     exitHandler = savedExitHandler;
   }
 
-  test_once() async {
+  Future<void> test_once() async {
     String testDir = path.join(testDirectory, 'data', 'errors_reported_once');
     Driver driver = Driver(isTesting: true);
     await driver.start(
@@ -54,7 +54,7 @@
     expect(unusedWarning.allMatches(output).toList(), hasLength(1));
   }
 
-  test_once_machine() async {
+  Future<void> test_once_machine() async {
     String testDir = path.join(testDirectory, 'data', 'errors_reported_once');
     Driver driver = Driver(isTesting: true);
     await driver.start([
diff --git a/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart b/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
index b0cb1df..1be1384 100644
--- a/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
+++ b/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
@@ -12,7 +12,7 @@
 
 import 'utils.dart';
 
-main() {
+void main() {
   defineReflectiveTests(ErrorUpgradeFailsCli);
 }
 
@@ -39,7 +39,7 @@
     exitHandler = savedExitHandler;
   }
 
-  test_once() async {
+  Future<void> test_once() async {
     String testDir =
         path.join(testDirectory, 'data', 'error_upgrade_fails_cli');
     Driver driver = Driver(isTesting: true);
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index f14765d..592f09a 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -65,7 +65,7 @@
   bool color = false;
 
   @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockErrorCode implements ErrorCode {
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index f144a28..807b70f 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -12,7 +12,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-main() {
+void main() {
   group('CommandLineOptions', () {
     group('parse', () {
       StringBuffer outStringBuffer = StringBuffer();
@@ -282,7 +282,7 @@
   int savedExitCode;
   ExitHandler savedExitHandler;
 
-  setUp() {
+  void setUp() {
     savedOutSink = outSink;
     savedErrorSink = errorSink;
     savedExitHandler = exitHandler;
@@ -294,7 +294,7 @@
     errorSink = errorStringBuffer;
   }
 
-  tearDown() {
+  void tearDown() {
     outSink = savedOutSink;
     errorSink = savedErrorSink;
     exitCode = savedExitCode;
@@ -306,7 +306,7 @@
 class CommandLineOptionsTest extends AbstractStatusTest {
   CommandLineOptions options;
 
-  test_buildAnalysisOutput() {
+  void test_buildAnalysisOutput() {
     _parse([
       '--build-mode',
       '--build-analysis-output=//path/to/output.analysis',
@@ -316,18 +316,18 @@
     expect(options.buildAnalysisOutput, '//path/to/output.analysis');
   }
 
-  test_buildMode() {
+  void test_buildMode() {
     _parse(['--build-mode', 'package:p/foo.dart|/path/to/p/lib/foo.dart']);
     expect(options.buildMode, isTrue);
   }
 
-  test_buildMode_allowsEmptyFileList() {
+  void test_buildMode_allowsEmptyFileList() {
     _parse(['--build-mode']);
     expect(options.buildMode, isTrue);
     expect(options.sourceFiles, isEmpty);
   }
 
-  test_buildSummaryInputs_commaSeparated() {
+  void test_buildSummaryInputs_commaSeparated() {
     _parse([
       '--build-mode',
       '--build-summary-input=/path/to/aaa.sum,/path/to/bbb.sum',
@@ -338,7 +338,7 @@
         options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
   }
 
-  test_buildSummaryInputs_commaSeparated_normalMode() {
+  void test_buildSummaryInputs_commaSeparated_normalMode() {
     _parse([
       '--build-summary-input=/path/to/aaa.sum,/path/to/bbb.sum',
       '/path/to/p/lib/foo.dart'
@@ -348,7 +348,7 @@
         options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
   }
 
-  test_buildSummaryInputs_separateFlags() {
+  void test_buildSummaryInputs_separateFlags() {
     _parse([
       '--build-mode',
       '--build-summary-input=/path/to/aaa.sum',
@@ -360,7 +360,7 @@
         options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
   }
 
-  test_buildSummaryInputs_separateFlags_normalMode() {
+  void test_buildSummaryInputs_separateFlags_normalMode() {
     _parse([
       '--build-summary-input=/path/to/aaa.sum',
       '--build-summary-input=/path/to/bbb.sum',
@@ -371,7 +371,7 @@
         options.buildSummaryInputs, ['/path/to/aaa.sum', '/path/to/bbb.sum']);
   }
 
-  test_buildSummaryOnly() {
+  void test_buildSummaryOnly() {
     _parse([
       '--build-mode',
       '--build-summary-output=/path/to/aaa.sum',
@@ -382,7 +382,7 @@
     expect(options.buildSummaryOnly, isTrue);
   }
 
-  test_buildSummaryOutput() {
+  void test_buildSummaryOutput() {
     _parse([
       '--build-mode',
       '--build-summary-output=//path/to/output.sum',
@@ -392,7 +392,7 @@
     expect(options.buildSummaryOutput, '//path/to/output.sum');
   }
 
-  test_buildSummaryOutputSemantic() {
+  void test_buildSummaryOutputSemantic() {
     _parse([
       '--build-mode',
       '--build-summary-output-semantic=//path/to/output.sum',
@@ -402,7 +402,7 @@
     expect(options.buildSummaryOutputSemantic, '//path/to/output.sum');
   }
 
-  test_buildSuppressExitCode() {
+  void test_buildSuppressExitCode() {
     _parse([
       '--build-mode',
       '--build-suppress-exit-code',
diff --git a/pkg/analyzer_cli/test/package_prefix_test.dart b/pkg/analyzer_cli/test/package_prefix_test.dart
index ca00ef5..8112b0b 100644
--- a/pkg/analyzer_cli/test/package_prefix_test.dart
+++ b/pkg/analyzer_cli/test/package_prefix_test.dart
@@ -12,7 +12,7 @@
 
 import 'utils.dart' show testDirectory;
 
-main() {
+void main() {
   group('--x-package-warnings-prefix', () {
     _Runner runner;
 
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
index a4a2543..c75d94a 100644
--- a/pkg/analyzer_cli/test/perf_report_test.dart
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -9,7 +9,7 @@
 import 'package:analyzer_cli/src/perf_report.dart';
 import 'package:test/test.dart';
 
-main() {
+void main() {
   test('makePerfReport', () {
     var options = CommandLineOptions.parse(['somefile.dart']);
     var encoded = makePerfReport(1000, 1234, options, 0, AnalysisStats());
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 11f55c3..6976b5f 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -11,7 +11,7 @@
 
 import 'mocks.dart';
 
-main() {
+void main() {
   group('reporter', () {
     StringBuffer out;
     AnalysisStats stats;
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
index 1dd5b43..914a3ef 100644
--- a/pkg/analyzer_cli/test/strong_mode_test.dart
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -10,7 +10,7 @@
 
 import 'driver_test.dart';
 
-main() {
+void main() {
   defineReflectiveTests(StrongModeTest);
 }
 
@@ -23,7 +23,7 @@
 /// full analysis context.
 @reflectiveTest
 class StrongModeTest extends BaseTest {
-  test_producesStricterErrors() async {
+  Future<void> test_producesStricterErrors() async {
     await drive('data/strong_example.dart');
 
     expect(exitCode, 3);
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index 80e4630..d50e5db 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -24,7 +24,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 
-main(List<String> args) async {
+void main(List<String> args) async {
   // TODO(sigmund): provide sdk folder as well.
   if (args.length < 2) {
     print('usage: perf.dart <bench-id> <entry.dart>');
diff --git a/pkg/analyzer_cli/tool/perf_test.dart b/pkg/analyzer_cli/tool/perf_test.dart
index b137ec4..48c857a 100644
--- a/pkg/analyzer_cli/tool/perf_test.dart
+++ b/pkg/analyzer_cli/tool/perf_test.dart
@@ -6,4 +6,4 @@
 /// the code here just has a dummy import to the rest of the code.
 import 'perf.dart' as m;
 
-main() => print('done ${m.scanTotalChars}');
+void main() => print('done ${m.scanTotalChars}');
diff --git a/pkg/analyzer_plugin/analysis_options.yaml b/pkg/analyzer_plugin/analysis_options.yaml
index 42d4036..7e21576 100644
--- a/pkg/analyzer_plugin/analysis_options.yaml
+++ b/pkg/analyzer_plugin/analysis_options.yaml
@@ -8,7 +8,7 @@
     #
     # From pedantic 1.9.0:
     #
-    #- always_declare_return_types # 951
+    - always_declare_return_types
     - always_require_non_null_named_parameters
     - annotate_overrides
     - avoid_empty_else
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 0758b85..d63209a 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -58,7 +58,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['type'] = 'add';
     result['content'] = content;
     return result;
@@ -77,7 +77,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, 704418402);
     hash = JenkinsSmiHash.combine(hash, content.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -307,7 +307,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['severity'] = severity.toJson();
     result['type'] = type.toJson();
     result['location'] = location.toJson();
@@ -352,7 +352,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, severity.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
@@ -567,7 +567,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['type'] = 'change';
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
     return result;
@@ -587,7 +587,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, 873118866);
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1090,7 +1090,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['relevance'] = relevance;
     result['completion'] = completion;
@@ -1179,7 +1179,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, relevance.hashCode);
     hash = JenkinsSmiHash.combine(hash, completion.hashCode);
@@ -1391,7 +1391,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['message'] = message;
     result['location'] = location.toJson();
     return result;
@@ -1410,7 +1410,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1634,7 +1634,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
     if (location != null) {
@@ -1672,7 +1672,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
@@ -2059,7 +2059,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2081,7 +2081,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2169,7 +2169,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['type'] = type.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -2191,7 +2191,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2903,7 +2903,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['source'] = source.toJson();
     if (kind != null) {
       result['kind'] = kind;
@@ -2935,7 +2935,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, source.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, target.hashCode);
@@ -3075,7 +3075,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['signature'] = signature;
     result['corpus'] = corpus;
     result['root'] = root;
@@ -3101,7 +3101,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, signature.hashCode);
     hash = JenkinsSmiHash.combine(hash, corpus.hashCode);
     hash = JenkinsSmiHash.combine(hash, root.hashCode);
@@ -3204,7 +3204,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['positions'] =
         positions.map((Position value) => value.toJson()).toList();
     result['length'] = length;
@@ -3242,7 +3242,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, positions.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, suggestions.hashCode);
@@ -3311,7 +3311,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['value'] = value;
     result['kind'] = kind.toJson();
     return result;
@@ -3330,7 +3330,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, value.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3525,7 +3525,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -3551,7 +3551,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -3645,7 +3645,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['targets'] = targets;
@@ -3667,7 +3667,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
@@ -3823,7 +3823,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['fileIndex'] = fileIndex;
     result['offset'] = offset;
@@ -3851,7 +3851,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, fileIndex.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -3943,7 +3943,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['element'] = element.toJson();
     result['offsets'] = offsets;
     result['length'] = length;
@@ -3965,7 +3965,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     hash = JenkinsSmiHash.combine(hash, offsets.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -4126,7 +4126,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['element'] = element.toJson();
     result['offset'] = offset;
     result['length'] = length;
@@ -4157,7 +4157,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, element.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -4268,7 +4268,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['name'] = name;
     result['type'] = type;
@@ -4294,7 +4294,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
@@ -4424,7 +4424,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -4443,7 +4443,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4675,7 +4675,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (id != null) {
       result['id'] = id;
     }
@@ -4705,7 +4705,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, id.hashCode);
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
@@ -4858,7 +4858,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['severity'] = severity.toJson();
     result['message'] = message;
     if (location != null) {
@@ -4882,7 +4882,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, severity.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, location.hashCode);
@@ -5001,7 +5001,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['type'] = 'remove';
     return result;
   }
@@ -5019,7 +5019,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, 114870849);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5166,7 +5166,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['message'] = message;
     result['edits'] =
         edits.map((SourceFileEdit value) => value.toJson()).toList();
@@ -5218,7 +5218,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
     hash = JenkinsSmiHash.combine(hash, linkedEditGroups.hashCode);
@@ -5346,7 +5346,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['replacement'] = replacement;
@@ -5375,7 +5375,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacement.hashCode);
@@ -5480,7 +5480,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['fileStamp'] = fileStamp;
     result['edits'] = edits.map((SourceEdit value) => value.toJson()).toList();
@@ -5508,7 +5508,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, fileStamp.hashCode);
     hash = JenkinsSmiHash.combine(hash, edits.hashCode);
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
index fa05691..22b7fc2 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
@@ -83,7 +83,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['error'] = error.toJson();
     result['fixes'] =
         fixes.map((PrioritizedSourceChange value) => value.toJson()).toList();
@@ -105,7 +105,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, error.hashCode);
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -181,7 +181,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['errors'] =
         errors.map((AnalysisError value) => value.toJson()).toList();
@@ -207,7 +207,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, errors.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -283,7 +283,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((FoldingRegion value) => value.toJson()).toList();
@@ -309,7 +309,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -405,7 +405,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -432,7 +432,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -541,7 +541,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     result['targets'] =
         targets.map((NavigationTarget value) => value.toJson()).toList();
@@ -572,7 +572,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
@@ -631,7 +631,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['events'] =
         events.map((WatchEvent value) => value.toJson()).toList();
     return result;
@@ -656,7 +656,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, events.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -757,7 +757,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((HighlightRegion value) => value.toJson()).toList();
@@ -783,7 +783,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -907,7 +907,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['regions'] =
         regions.map((NavigationRegion value) => value.toJson()).toList();
@@ -939,7 +939,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, regions.hashCode);
     hash = JenkinsSmiHash.combine(hash, targets.hashCode);
@@ -1018,7 +1018,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['occurrences'] =
         occurrences.map((Occurrences value) => value.toJson()).toList();
@@ -1044,7 +1044,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1120,7 +1120,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['outline'] = outline.map((Outline value) => value.toJson()).toList();
     return result;
@@ -1144,7 +1144,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, outline.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1272,7 +1272,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['roots'] = roots.map((ContextRoot value) => value.toJson()).toList();
     return result;
   }
@@ -1296,7 +1296,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, roots.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1376,7 +1376,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] = files;
     return result;
   }
@@ -1399,7 +1399,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1486,7 +1486,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['subscriptions'] = mapMap(subscriptions,
         keyCallback: (AnalysisService value) => value.toJson());
     return result;
@@ -1514,7 +1514,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1605,7 +1605,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['files'] =
         mapMap(files, valueCallback: (dynamic value) => value.toJson());
     return result;
@@ -1629,7 +1629,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -1727,7 +1727,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -1751,7 +1751,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -1873,7 +1873,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['replacementOffset'] = replacementOffset;
     result['replacementLength'] = replacementLength;
     result['results'] =
@@ -1902,7 +1902,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, replacementOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode);
     hash = JenkinsSmiHash.combine(hash, results.hashCode);
@@ -1994,7 +1994,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['root'] = root;
     result['exclude'] = exclude;
     if (optionsFile != null) {
@@ -2018,7 +2018,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, root.hashCode);
     hash = JenkinsSmiHash.combine(hash, exclude.hashCode);
     hash = JenkinsSmiHash.combine(hash, optionsFile.hashCode);
@@ -2186,7 +2186,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2213,7 +2213,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2273,7 +2273,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['assists'] =
         assists.map((PrioritizedSourceChange value) => value.toJson()).toList();
     return result;
@@ -2298,7 +2298,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, assists.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -2389,7 +2389,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     result['length'] = length;
@@ -2416,7 +2416,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
@@ -2487,7 +2487,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kinds'] =
         kinds.map((RefactoringKind value) => value.toJson()).toList();
     return result;
@@ -2512,7 +2512,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kinds.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -2583,7 +2583,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     result['offset'] = offset;
     return result;
@@ -2607,7 +2607,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2666,7 +2666,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['fixes'] =
         fixes.map((AnalysisErrorFixes value) => value.toJson()).toList();
     return result;
@@ -2691,7 +2691,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -2853,7 +2853,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['kind'] = kind.toJson();
     result['file'] = file;
     result['offset'] = offset;
@@ -2888,7 +2888,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, kind.hashCode);
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
@@ -3090,7 +3090,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['initialProblems'] = initialProblems
         .map((RefactoringProblem value) => value.toJson())
         .toList();
@@ -3139,7 +3139,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, initialProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, optionsProblems.hashCode);
     hash = JenkinsSmiHash.combine(hash, finalProblems.hashCode);
@@ -3288,7 +3288,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (coveringExpressionOffsets != null) {
       result['coveringExpressionOffsets'] = coveringExpressionOffsets;
     }
@@ -3320,7 +3320,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, coveringExpressionOffsets.hashCode);
     hash = JenkinsSmiHash.combine(hash, coveringExpressionLengths.hashCode);
     hash = JenkinsSmiHash.combine(hash, names.hashCode);
@@ -3404,7 +3404,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['extractAll'] = extractAll;
     return result;
@@ -3423,7 +3423,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, extractAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -3637,7 +3637,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['returnType'] = returnType;
@@ -3675,7 +3675,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
@@ -3845,7 +3845,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['returnType'] = returnType;
     result['createGetter'] = createGetter;
     result['name'] = name;
@@ -3877,7 +3877,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, returnType.hashCode);
     hash = JenkinsSmiHash.combine(hash, createGetter.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
@@ -3949,7 +3949,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['name'] = name;
     result['occurrences'] = occurrences;
     return result;
@@ -3968,7 +3968,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, occurrences.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4079,7 +4079,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     if (className != null) {
       result['className'] = className;
     }
@@ -4103,7 +4103,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
     hash = JenkinsSmiHash.combine(hash, methodName.hashCode);
     hash = JenkinsSmiHash.combine(hash, isDeclaration.hashCode);
@@ -4183,7 +4183,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['deleteSource'] = deleteSource;
     result['inlineAll'] = inlineAll;
     return result;
@@ -4202,7 +4202,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, deleteSource.hashCode);
     hash = JenkinsSmiHash.combine(hash, inlineAll.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4258,7 +4258,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['file'] = file;
     return result;
   }
@@ -4281,7 +4281,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4366,7 +4366,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['entries'] =
         entries.map((KytheEntry value) => value.toJson()).toList();
     result['files'] = files;
@@ -4393,7 +4393,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, entries.hashCode);
     hash = JenkinsSmiHash.combine(hash, files.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -4466,7 +4466,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newFile'] = newFile;
     return result;
   }
@@ -4484,7 +4484,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newFile.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -4585,7 +4585,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isFatal'] = isFatal;
     result['message'] = message;
     result['stackTrace'] = stackTrace;
@@ -4611,7 +4611,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isFatal.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -4765,7 +4765,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['byteStorePath'] = byteStorePath;
     result['sdkPath'] = sdkPath;
     result['version'] = version;
@@ -4792,7 +4792,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, byteStorePath.hashCode);
     hash = JenkinsSmiHash.combine(hash, sdkPath.hashCode);
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
@@ -4947,7 +4947,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['isCompatible'] = isCompatible;
     result['name'] = name;
     result['version'] = version;
@@ -4981,7 +4981,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, isCompatible.hashCode);
     hash = JenkinsSmiHash.combine(hash, name.hashCode);
     hash = JenkinsSmiHash.combine(hash, version.hashCode);
@@ -5055,7 +5055,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['priority'] = priority;
     result['change'] = change.toJson();
     return result;
@@ -5074,7 +5074,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, priority.hashCode);
     hash = JenkinsSmiHash.combine(hash, change.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -5098,7 +5098,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -5115,7 +5115,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -5136,7 +5136,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     return result;
   }
 
@@ -5153,7 +5153,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -5261,7 +5261,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['offset'] = offset;
     result['length'] = length;
     result['elementKindName'] = elementKindName;
@@ -5285,7 +5285,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     hash = JenkinsSmiHash.combine(hash, length.hashCode);
     hash = JenkinsSmiHash.combine(hash, elementKindName.hashCode);
@@ -5342,7 +5342,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['newName'] = newName;
     return result;
   }
@@ -5360,7 +5360,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, newName.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -5447,7 +5447,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['code'] = code.toJson();
     result['message'] = message;
     if (stackTrace != null) {
@@ -5471,7 +5471,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, code.hashCode);
     hash = JenkinsSmiHash.combine(hash, message.hashCode);
     hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode);
@@ -5621,7 +5621,7 @@
 
   @override
   Map<String, dynamic> toJson() {
-    Map<String, dynamic> result = {};
+    var result = <String, dynamic>{};
     result['type'] = type.toJson();
     result['path'] = path;
     return result;
@@ -5640,7 +5640,7 @@
 
   @override
   int get hashCode {
-    int hash = 0;
+    var hash = 0;
     hash = JenkinsSmiHash.combine(hash, type.hashCode);
     hash = JenkinsSmiHash.combine(hash, path.hashCode);
     return JenkinsSmiHash.finish(hash);
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index b384255..bb3a129 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -250,7 +250,7 @@
   }
 }
 
-class _OpTypeAstVisitor extends GeneralizingAstVisitor {
+class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
   /// The entity (AstNode or Token) which will be replaced or displaced by the
   /// added text.
   final Object entity;
@@ -464,7 +464,7 @@
   }
 
   @override
-  visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
@@ -472,7 +472,7 @@
   }
 
   @override
-  visitConstructorName(ConstructorName node) {
+  void visitConstructorName(ConstructorName node) {
     // some PrefixedIdentifier nodes are transformed into
     // ConstructorName nodes during the resolution process.
     if (identical(entity, node.name)) {
@@ -567,7 +567,7 @@
   }
 
   @override
-  visitFieldDeclaration(FieldDeclaration node) {
+  void visitFieldDeclaration(FieldDeclaration node) {
     if (offset <= node.semicolon.offset) {
       optype.includeVarNameSuggestions = true;
     }
@@ -584,7 +584,7 @@
   }
 
   @override
-  visitForEachParts(ForEachParts node) {
+  void visitForEachParts(ForEachParts node) {
     if (node is ForEachPartsWithIdentifier &&
         identical(entity, node.identifier)) {
       optype.includeTypeNameSuggestions = true;
@@ -606,7 +606,7 @@
   }
 
   @override
-  visitForElement(ForElement node) {
+  void visitForElement(ForElement node) {
     // for (^) {}
     // for (Str^ str = null;) {}
     // In theory it is possible to specify any expression in initializer,
@@ -658,7 +658,7 @@
   }
 
   @override
-  visitForParts(ForParts node) {
+  void visitForParts(ForParts node) {
     var entity = this.entity;
     if (_isEntityPrevTokenSynthetic()) {
       // Actual: for (var v i^)
@@ -719,7 +719,7 @@
   }
 
   @override
-  visitIfElement(IfElement node) {
+  void visitIfElement(IfElement node) {
     if (identical(entity, node.condition)) {
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
@@ -833,7 +833,7 @@
   }
 
   @override
-  visitMixinDeclaration(MixinDeclaration node) {
+  void visitMixinDeclaration(MixinDeclaration node) {
     // Make suggestions in the body of the mixin declaration
     if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
       optype.includeTypeNameSuggestions = true;
@@ -1019,7 +1019,7 @@
   }
 
   @override
-  visitSpreadElement(SpreadElement node) {
+  void visitSpreadElement(SpreadElement node) {
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index f42fcaf..764e342 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -83,7 +83,7 @@
         skipChildClass: skipChildClass);
   }
 
-  _addSuggestionsForType(InterfaceType type, OpType optype,
+  void _addSuggestionsForType(InterfaceType type, OpType optype,
       {bool isFunctionalArgument = false}) {
     if (!isFunctionalArgument) {
       for (PropertyAccessorElement elem in type.accessors) {
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
index 9bfaea1..5d03ac8 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
@@ -758,7 +758,10 @@
   /// If it doesn't match, record a closure in [mismatches] which can describe
   /// the mismatch. [describeSubstructure] is used to describe which
   /// substructure did not match.
-  checkSubstructure(item, Matcher matcher, List<MismatchDescriber> mismatches,
+  void checkSubstructure(
+      item,
+      Matcher matcher,
+      List<MismatchDescriber> mismatches,
       Description Function(Description description) describeSubstructure) {
     Map subState = {};
     if (!matcher.matches(item, subState)) {
diff --git a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
index adc4965a..cb6bfc8 100644
--- a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
@@ -40,7 +40,7 @@
     plugin.start(channel);
   }
 
-  test_handleEditGetAssists() async {
+  Future<void> test_handleEditGetAssists() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
index 1b78395..33f2bec 100644
--- a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
@@ -40,7 +40,7 @@
     plugin.start(channel);
   }
 
-  test_handleCompletionGetSuggestions() async {
+  Future<void> test_handleCompletionGetSuggestions() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
index 75f8eda..9138f9e 100644
--- a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
@@ -44,7 +44,7 @@
     plugin.start(channel);
   }
 
-  test_handleEditGetFixes() async {
+  Future<void> test_handleEditGetFixes() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index 7929a6d..fc5879c 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -41,7 +41,7 @@
     plugin.start(channel);
   }
 
-  test_sendFoldingNotification() async {
+  Future<void> test_sendFoldingNotification() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
index b577e6a..708df39 100644
--- a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
@@ -41,7 +41,7 @@
     plugin.start(channel);
   }
 
-  test_sendHighlightsNotification() async {
+  Future<void> test_sendHighlightsNotification() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
index e3eb010..2ebb6fa 100644
--- a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
@@ -40,7 +40,7 @@
     plugin.start(channel);
   }
 
-  test_handleEditGetAssists() async {
+  Future<void> test_handleEditGetAssists() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index 6943f59..ee54ad3 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -141,12 +141,12 @@
   MockResolvedUnitResult({this.errors, this.lineInfo, this.path});
 
   @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockResourceProvider implements ResourceProvider {
   @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /// A concrete implementation of a server plugin that is suitable for testing.
diff --git a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
index 8b4c5b7..51107a6 100644
--- a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
@@ -41,7 +41,7 @@
     plugin.start(channel);
   }
 
-  test_handleAnalysisGetNavigation() async {
+  Future<void> test_handleAnalysisGetNavigation() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -54,7 +54,7 @@
     expect(result.regions, hasLength(2));
   }
 
-  test_sendNavigationNotification() async {
+  Future<void> test_sendNavigationNotification() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
index 8a4adbf..cc88fbb 100644
--- a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
@@ -41,7 +41,7 @@
     plugin.start(channel);
   }
 
-  test_sendOccurrencesNotification() async {
+  Future<void> test_sendOccurrencesNotification() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
index 42e19c6..bdf0fc5 100644
--- a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
@@ -41,7 +41,7 @@
     plugin.start(channel);
   }
 
-  test_sendOutlineNotification() async {
+  Future<void> test_sendOutlineNotification() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
diff --git a/pkg/analyzer_plugin/test/plugin/plugin_test.dart b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
index bfb7a5b..939f971 100644
--- a/pkg/analyzer_plugin/test/plugin/plugin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
@@ -48,7 +48,7 @@
     plugin.start(channel);
   }
 
-  test_contextRootContaining_insideRoot() async {
+  Future<void> test_contextRootContaining_insideRoot() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -59,26 +59,26 @@
     expect(plugin.contextRootContaining(filePath1), isNull);
   }
 
-  test_contextRootContaining_outsideRoot() async {
+  Future<void> test_contextRootContaining_outsideRoot() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
     expect(plugin.contextRootContaining(filePath2), isNull);
   }
 
-  test_handleAnalysisGetNavigation() async {
+  Future<void> test_handleAnalysisGetNavigation() async {
     var result = await plugin
         .handleAnalysisGetNavigation(AnalysisGetNavigationParams('', 1, 2));
     expect(result, isNotNull);
   }
 
-  test_handleAnalysisHandleWatchEvents() async {
+  Future<void> test_handleAnalysisHandleWatchEvents() async {
     var result = await plugin
         .handleAnalysisHandleWatchEvents(AnalysisHandleWatchEventsParams([]));
     expect(result, isNotNull);
   }
 
-  test_handleAnalysisSetContextRoots() async {
+  Future<void> test_handleAnalysisSetContextRoots() async {
     var result = await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
     expect(result, isNotNull);
@@ -87,7 +87,7 @@
     expect((driver as MockAnalysisDriver).addedFiles, hasLength(1));
   }
 
-  test_handleAnalysisSetPriorityFiles() async {
+  Future<void> test_handleAnalysisSetPriorityFiles() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -96,7 +96,7 @@
     expect(result, isNotNull);
   }
 
-  test_handleAnalysisSetSubscriptions() async {
+  Future<void> test_handleAnalysisSetSubscriptions() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
     expect(plugin.subscriptionManager.servicesForFile(filePath1), isEmpty);
@@ -110,7 +110,7 @@
         [AnalysisService.OUTLINE]);
   }
 
-  test_handleAnalysisUpdateContent_addChangeRemove() async {
+  Future<void> test_handleAnalysisUpdateContent_addChangeRemove() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
     var addResult = await plugin.handleAnalysisUpdateContent(
@@ -127,7 +127,7 @@
     expect(removeResult, isNotNull);
   }
 
-  test_handleAnalysisUpdateContent_changeNoAdd() async {
+  Future<void> test_handleAnalysisUpdateContent_changeNoAdd() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
     try {
@@ -140,7 +140,7 @@
     }
   }
 
-  test_handleAnalysisUpdateContent_invalidChange() async {
+  Future<void> test_handleAnalysisUpdateContent_invalidChange() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
     await plugin.handleAnalysisUpdateContent(AnalysisUpdateContentParams(
@@ -155,7 +155,7 @@
     }
   }
 
-  test_handleCompletionGetSuggestions() async {
+  Future<void> test_handleCompletionGetSuggestions() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -165,7 +165,7 @@
     expect(result, isNotNull);
   }
 
-  test_handleEditGetAssists() async {
+  Future<void> test_handleEditGetAssists() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -174,7 +174,7 @@
     expect(result, isNotNull);
   }
 
-  test_handleEditGetAvailableRefactorings() async {
+  Future<void> test_handleEditGetAvailableRefactorings() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -184,7 +184,7 @@
     expect(result, isNotNull);
   }
 
-  test_handleEditGetFixes() async {
+  Future<void> test_handleEditGetFixes() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -194,7 +194,7 @@
   }
 
   @failingTest
-  test_handleEditGetRefactoring() async {
+  Future<void> test_handleEditGetRefactoring() async {
     await plugin.handleAnalysisSetContextRoots(
         AnalysisSetContextRootsParams([contextRoot1]));
 
@@ -204,12 +204,12 @@
     expect(result, isNotNull);
   }
 
-  test_handlePluginShutdown() async {
+  Future<void> test_handlePluginShutdown() async {
     var result = await plugin.handlePluginShutdown(PluginShutdownParams());
     expect(result, isNotNull);
   }
 
-  test_handlePluginVersionCheck() async {
+  Future<void> test_handlePluginVersionCheck() async {
     PluginVersionCheckResult result = await plugin.handlePluginVersionCheck(
         PluginVersionCheckParams('byteStorePath', 'sdkPath', '0.1.0'));
     expect(result, isNotNull);
@@ -232,18 +232,18 @@
     channel.sendError(ArgumentError(), StackTrace.fromString(''));
   }
 
-  test_onRequest_analysisGetNavigation() async {
+  Future<void> test_onRequest_analysisGetNavigation() async {
     var result =
         await channel.sendRequest(AnalysisGetNavigationParams('', 1, 2));
     expect(result, isNotNull);
   }
 
-  test_onRequest_analysisHandleWatchEvents() async {
+  Future<void> test_onRequest_analysisHandleWatchEvents() async {
     var result = await channel.sendRequest(AnalysisHandleWatchEventsParams([]));
     expect(result, isNotNull);
   }
 
-  test_onRequest_analysisSetContextRoots() async {
+  Future<void> test_onRequest_analysisSetContextRoots() async {
     var result = await channel
         .sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
     expect(result, isNotNull);
@@ -252,7 +252,7 @@
     expect((driver as MockAnalysisDriver).addedFiles, hasLength(1));
   }
 
-  test_onRequest_analysisSetPriorityFiles() async {
+  Future<void> test_onRequest_analysisSetPriorityFiles() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result =
@@ -260,7 +260,7 @@
     expect(result, isNotNull);
   }
 
-  test_onRequest_analysisSetSubscriptions() async {
+  Future<void> test_onRequest_analysisSetSubscriptions() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
     expect(plugin.subscriptionManager.servicesForFile(filePath1), isEmpty);
 
@@ -272,7 +272,7 @@
         [AnalysisService.OUTLINE]);
   }
 
-  test_onRequest_analysisUpdateContent_addChangeRemove() async {
+  Future<void> test_onRequest_analysisUpdateContent_addChangeRemove() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
     var addResult = await channel.sendRequest(AnalysisUpdateContentParams(
         {filePath1: AddContentOverlay('class C {}')}));
@@ -286,7 +286,7 @@
     expect(removeResult, isNotNull);
   }
 
-  test_onRequest_completionGetSuggestions() async {
+  Future<void> test_onRequest_completionGetSuggestions() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result = await channel
@@ -294,7 +294,7 @@
     expect(result, isNotNull);
   }
 
-  test_onRequest_editGetAssists() async {
+  Future<void> test_onRequest_editGetAssists() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result =
@@ -302,7 +302,7 @@
     expect(result, isNotNull);
   }
 
-  test_onRequest_editGetAvailableRefactorings() async {
+  Future<void> test_onRequest_editGetAvailableRefactorings() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result = await channel
@@ -310,14 +310,14 @@
     expect(result, isNotNull);
   }
 
-  test_onRequest_editGetFixes() async {
+  Future<void> test_onRequest_editGetFixes() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result = await channel.sendRequest(EditGetFixesParams(filePath1, 13));
     expect(result, isNotNull);
   }
 
-  test_onRequest_editGetRefactoring() async {
+  Future<void> test_onRequest_editGetRefactoring() async {
     await channel.sendRequest(AnalysisSetContextRootsParams([contextRoot1]));
 
     var result = await channel.sendRequest(EditGetRefactoringParams(
@@ -325,12 +325,12 @@
     expect(result, isNotNull);
   }
 
-  test_onRequest_pluginShutdown() async {
+  Future<void> test_onRequest_pluginShutdown() async {
     var result = await channel.sendRequest(PluginShutdownParams());
     expect(result, isNotNull);
   }
 
-  test_onRequest_pluginVersionCheck() async {
+  Future<void> test_onRequest_pluginVersionCheck() async {
     var response = (await channel.sendRequest(
         PluginVersionCheckParams('byteStorePath', 'sdkPath', '0.1.0')));
     PluginVersionCheckResult result =
@@ -342,7 +342,7 @@
     expect(result.version, '0.1.0');
   }
 
-  test_sendNotificationsForFile() {
+  void test_sendNotificationsForFile() {
     AnalysisService service1 = AnalysisService.FOLDING;
     AnalysisService service2 = AnalysisService.NAVIGATION;
     AnalysisService service3 = AnalysisService.OUTLINE;
@@ -358,7 +358,7 @@
     expect(services, unorderedEquals([service1, service2]));
   }
 
-  test_sendNotificationsForSubscriptions() {
+  void test_sendNotificationsForSubscriptions() {
     Map<String, List<AnalysisService>> subscriptions =
         <String, List<AnalysisService>>{};
 
diff --git a/pkg/analyzer_plugin/test/plugin/test_all.dart b/pkg/analyzer_plugin/test/plugin/test_all.dart
index 80af37d..5d10fe6 100644
--- a/pkg/analyzer_plugin/test/plugin/test_all.dart
+++ b/pkg/analyzer_plugin/test/plugin/test_all.dart
@@ -15,7 +15,7 @@
 import 'outline_mixin_test.dart' as outline_mixin_test;
 import 'plugin_test.dart' as plugin_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     assist_mixin_test.main();
     completion_mixin_test.main();
diff --git a/pkg/analyzer_plugin/test/src/channel/test_all.dart b/pkg/analyzer_plugin/test/src/channel/test_all.dart
index cfeb586..439416c 100644
--- a/pkg/analyzer_plugin/test/src/channel/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/channel/test_all.dart
@@ -6,7 +6,7 @@
 
 import 'isolate_channel_test.dart' as isolate_channel_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     isolate_channel_test.main();
   }, name: 'channel');
diff --git a/pkg/analyzer_plugin/test/src/test_all.dart b/pkg/analyzer_plugin/test/src/test_all.dart
index a0f35df..def51f2 100644
--- a/pkg/analyzer_plugin/test/src/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/test_all.dart
@@ -7,7 +7,7 @@
 import 'channel/test_all.dart' as channel;
 import 'utilities/test_all.dart' as utilities;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     channel.main();
     utilities.main();
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
index 1ee96bb..f4dd95c 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_core_test.dart
@@ -9,7 +9,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ChangeBuilderImplTest);
     defineReflectiveTests(EditBuilderImplTest);
@@ -20,7 +20,7 @@
 
 @reflectiveTest
 class ChangeBuilderImplTest {
-  test_createFileEditBuilder() async {
+  Future<void> test_createFileEditBuilder() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     String path = '/test.dart';
     FileEditBuilderImpl fileEditBuilder =
@@ -66,7 +66,7 @@
     expect(sourceChange.selection, isNull);
   }
 
-  test_sourceChange_oneChange() async {
+  Future<void> test_sourceChange_oneChange() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     String path = '/test.dart';
     await builder.addFileEdit(path, (FileEditBuilder builder) {
@@ -86,7 +86,7 @@
 class EditBuilderImplTest {
   String path = '/test.dart';
 
-  test_addLinkedEdit() async {
+  Future<void> test_addLinkedEdit() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     int offset = 10;
     String text = 'content';
@@ -111,7 +111,7 @@
     expect(positions[0].offset, offset);
   }
 
-  test_addSimpleLinkedEdit() async {
+  Future<void> test_addSimpleLinkedEdit() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     int offset = 10;
     String text = 'content';
@@ -134,7 +134,7 @@
     expect(positions[0].offset, offset);
   }
 
-  test_createLinkedEditBuilder() async {
+  Future<void> test_createLinkedEditBuilder() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(10, (EditBuilder builder) {
@@ -145,7 +145,7 @@
     });
   }
 
-  test_selectHere() async {
+  Future<void> test_selectHere() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(10, (EditBuilder builder) {
@@ -155,7 +155,7 @@
     expect(builder.sourceChange.selection.offset, 10);
   }
 
-  test_write() async {
+  Future<void> test_write() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     int offset = 10;
     String text = 'write';
@@ -183,7 +183,7 @@
     expect(edit.replacement, text);
   }
 
-  test_writeln_withoutText() async {
+  Future<void> test_writeln_withoutText() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     int offset = 52;
     int length = 12;
@@ -212,7 +212,7 @@
     expect(edit.replacement == '\n' || edit.replacement == '\r\n', isTrue);
   }
 
-  test_writeln_withText() async {
+  Future<void> test_writeln_withText() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     int offset = 52;
     int length = 12;
@@ -248,7 +248,7 @@
 class FileEditBuilderImplTest {
   String path = '/test.dart';
 
-  test_addDeletion() async {
+  Future<void> test_addDeletion() async {
     int offset = 23;
     int length = 7;
     ChangeBuilderImpl builder = ChangeBuilderImpl();
@@ -262,7 +262,7 @@
     expect(edits[0].replacement, isEmpty);
   }
 
-  test_addInsertion() async {
+  Future<void> test_addInsertion() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(10, (EditBuilder builder) {
@@ -271,7 +271,7 @@
     });
   }
 
-  test_addLinkedPosition() async {
+  Future<void> test_addLinkedPosition() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     String groupName = 'a';
     await builder.addFileEdit(path, (FileEditBuilder builder) {
@@ -287,7 +287,7 @@
     expect(group.length, 6);
   }
 
-  test_addReplacement() async {
+  Future<void> test_addReplacement() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addReplacement(SourceRange(4, 5), (EditBuilder builder) {
@@ -296,7 +296,7 @@
     });
   }
 
-  test_addSimpleInsertion() async {
+  Future<void> test_addSimpleInsertion() async {
     int offset = 23;
     String text = 'xyz';
     ChangeBuilderImpl builder = ChangeBuilderImpl();
@@ -310,7 +310,7 @@
     expect(edits[0].replacement, text);
   }
 
-  test_addSimpleReplacement() async {
+  Future<void> test_addSimpleReplacement() async {
     int offset = 23;
     int length = 7;
     String text = 'xyz';
@@ -325,7 +325,7 @@
     expect(edits[0].replacement, text);
   }
 
-  test_createEditBuilder() async {
+  Future<void> test_createEditBuilder() async {
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       int offset = 4;
@@ -345,7 +345,7 @@
 class LinkedEditBuilderImplTest {
   String path = '/test.dart';
 
-  test_addSuggestion() async {
+  Future<void> test_addSuggestion() async {
     String groupName = 'a';
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
@@ -361,7 +361,7 @@
     expect(group.suggestions, hasLength(1));
   }
 
-  test_addSuggestion_zeroLength() async {
+  Future<void> test_addSuggestion_zeroLength() async {
     String groupName = 'a';
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
@@ -375,7 +375,7 @@
     expect(builder.sourceChange.linkedEditGroups, isEmpty);
   }
 
-  test_addSuggestions() async {
+  Future<void> test_addSuggestions() async {
     String groupName = 'a';
     ChangeBuilderImpl builder = ChangeBuilderImpl();
     await builder.addFileEdit(path, (FileEditBuilder builder) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 009d89d..b24a559 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -22,7 +22,7 @@
 import '../../../support/abstract_context.dart';
 import 'dart/dart_change_builder_mixin.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(DartChangeBuilderImplTest);
     defineReflectiveTests(DartEditBuilderImplTest);
@@ -36,7 +36,7 @@
 @reflectiveTest
 class DartChangeBuilderImplTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_createFileEditBuilder() async {
+  Future<void> test_createFileEditBuilder() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'library test;');
     DartChangeBuilderImpl builder = newBuilder();
@@ -51,7 +51,7 @@
 @reflectiveTest
 class DartEditBuilderImplTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_writeClassDeclaration_interfaces() async {
+  Future<void> test_writeClassDeclaration_interfaces() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {}');
     DartType typeA = await _getType(path, 'A');
@@ -68,7 +68,7 @@
         edit.replacement, equalsIgnoringWhitespace('class C implements A { }'));
   }
 
-  test_writeClassDeclaration_isAbstract() async {
+  Future<void> test_writeClassDeclaration_isAbstract() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '');
 
@@ -83,7 +83,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('abstract class C { }'));
   }
 
-  test_writeClassDeclaration_memberWriter() async {
+  Future<void> test_writeClassDeclaration_memberWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '');
 
@@ -100,7 +100,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('class C { /**/}'));
   }
 
-  test_writeClassDeclaration_mixins_noSuperclass() async {
+  Future<void> test_writeClassDeclaration_mixins_noSuperclass() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {}');
     DartType typeA = await _getType(path, 'A');
@@ -117,7 +117,7 @@
         equalsIgnoringWhitespace('class C extends Object with A { }'));
   }
 
-  test_writeClassDeclaration_mixins_superclass() async {
+  Future<void> test_writeClassDeclaration_mixins_superclass() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {} class B {}');
     DartType typeA = await _getType(path, 'A');
@@ -135,7 +135,7 @@
         equalsIgnoringWhitespace('class C extends A with B { }'));
   }
 
-  test_writeClassDeclaration_nameGroupName() async {
+  Future<void> test_writeClassDeclaration_nameGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '');
 
@@ -157,7 +157,7 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeClassDeclaration_superclass() async {
+  Future<void> test_writeClassDeclaration_superclass() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class B {}');
     DartType typeB = await _getType(path, 'B');
@@ -180,7 +180,7 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeConstructorDeclaration_bodyWriter() async {
+  Future<void> test_writeConstructorDeclaration_bodyWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class C {}');
 
@@ -196,7 +196,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A() { print(42); }'));
   }
 
-  test_writeConstructorDeclaration_fieldNames() async {
+  Future<void> test_writeConstructorDeclaration_fieldNames() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, r'''
 class C {
@@ -215,7 +215,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A(this.a, this.bb);'));
   }
 
-  test_writeConstructorDeclaration_initializerWriter() async {
+  Future<void> test_writeConstructorDeclaration_initializerWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class C {}');
 
@@ -231,7 +231,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A() : super();'));
   }
 
-  test_writeConstructorDeclaration_parameterWriter() async {
+  Future<void> test_writeConstructorDeclaration_parameterWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class C {}');
 
@@ -247,7 +247,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A(int a, {this.b});'));
   }
 
-  test_writeFieldDeclaration_initializerWriter() async {
+  Future<void> test_writeFieldDeclaration_initializerWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -265,7 +265,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var f = e;'));
   }
 
-  test_writeFieldDeclaration_isConst() async {
+  Future<void> test_writeFieldDeclaration_isConst() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -280,7 +280,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const f;'));
   }
 
-  test_writeFieldDeclaration_isConst_isFinal() async {
+  Future<void> test_writeFieldDeclaration_isConst_isFinal() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -296,7 +296,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const f;'));
   }
 
-  test_writeFieldDeclaration_isConst_type() async {
+  Future<void> test_writeFieldDeclaration_isConst_type() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -313,7 +313,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const A f;'));
   }
 
-  test_writeFieldDeclaration_isFinal() async {
+  Future<void> test_writeFieldDeclaration_isFinal() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -328,7 +328,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('final f;'));
   }
 
-  test_writeFieldDeclaration_isFinal_type() async {
+  Future<void> test_writeFieldDeclaration_isFinal_type() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -345,7 +345,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('final A f;'));
   }
 
-  test_writeFieldDeclaration_isStatic() async {
+  Future<void> test_writeFieldDeclaration_isStatic() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -360,7 +360,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('static var f;'));
   }
 
-  test_writeFieldDeclaration_nameGroupName() async {
+  Future<void> test_writeFieldDeclaration_nameGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -385,7 +385,7 @@
     expect(position.offset, equals(13));
   }
 
-  test_writeFieldDeclaration_type_typeGroupName() async {
+  Future<void> test_writeFieldDeclaration_type_typeGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B {}';
     addSource(path, content);
@@ -411,7 +411,8 @@
     expect(position.offset, equals(20));
   }
 
-  test_writeFunctionDeclaration_noReturnType_noParams_body() async {
+  Future<void>
+      test_writeFunctionDeclaration_noReturnType_noParams_body() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '';
     addSource(path, content);
@@ -429,7 +430,8 @@
     expect(edit.replacement, equalsIgnoringWhitespace('fib() { ... }'));
   }
 
-  test_writeFunctionDeclaration_noReturnType_noParams_noBody() async {
+  Future<void>
+      test_writeFunctionDeclaration_noReturnType_noParams_noBody() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '';
     addSource(path, content);
@@ -452,7 +454,8 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeFunctionDeclaration_noReturnType_params_noBody() async {
+  Future<void>
+      test_writeFunctionDeclaration_noReturnType_params_noBody() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '';
     addSource(path, content);
@@ -470,7 +473,8 @@
     expect(edit.replacement, equalsIgnoringWhitespace('fib(p, q, r) {}'));
   }
 
-  test_writeFunctionDeclaration_returnType_noParams_noBody() async {
+  Future<void>
+      test_writeFunctionDeclaration_returnType_noParams_noBody() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -495,7 +499,7 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeGetterDeclaration_bodyWriter() async {
+  Future<void> test_writeGetterDeclaration_bodyWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -513,7 +517,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('get g {}'));
   }
 
-  test_writeGetterDeclaration_isStatic() async {
+  Future<void> test_writeGetterDeclaration_isStatic() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -529,7 +533,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('static get g => null;'));
   }
 
-  test_writeGetterDeclaration_nameGroupName() async {
+  Future<void> test_writeGetterDeclaration_nameGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -554,7 +558,7 @@
     expect(position.offset, equals(13));
   }
 
-  test_writeGetterDeclaration_returnType() async {
+  Future<void> test_writeGetterDeclaration_returnType() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B {}';
     addSource(path, content);
@@ -580,7 +584,7 @@
     expect(position.offset, equals(20));
   }
 
-  test_writeLocalVariableDeclaration_noType_initializer() async {
+  Future<void> test_writeLocalVariableDeclaration_noType_initializer() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -602,7 +606,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var foo = null;'));
   }
 
-  test_writeLocalVariableDeclaration_noType_noInitializer() async {
+  Future<void> test_writeLocalVariableDeclaration_noType_noInitializer() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -629,7 +633,8 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeLocalVariableDeclaration_noType_noInitializer_const() async {
+  Future<void>
+      test_writeLocalVariableDeclaration_noType_noInitializer_const() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -649,7 +654,8 @@
     expect(edit.replacement, equalsIgnoringWhitespace('const foo;'));
   }
 
-  test_writeLocalVariableDeclaration_noType_noInitializer_final() async {
+  Future<void>
+      test_writeLocalVariableDeclaration_noType_noInitializer_final() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -669,7 +675,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('final foo;'));
   }
 
-  test_writeLocalVariableDeclaration_type_initializer() async {
+  Future<void> test_writeLocalVariableDeclaration_type_initializer() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -700,7 +706,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo = null;'));
   }
 
-  test_writeLocalVariableDeclaration_type_noInitializer() async {
+  Future<void> test_writeLocalVariableDeclaration_type_noInitializer() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -736,7 +742,8 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeLocalVariableDeclaration_type_noInitializer_final() async {
+  Future<void>
+      test_writeLocalVariableDeclaration_type_noInitializer_final() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 void f() {
@@ -773,7 +780,7 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeMixinDeclaration_interfaces() async {
+  Future<void> test_writeMixinDeclaration_interfaces() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {}');
     DartType typeA = await _getType(path, 'A');
@@ -790,7 +797,8 @@
         edit.replacement, equalsIgnoringWhitespace('mixin M implements A { }'));
   }
 
-  test_writeMixinDeclaration_interfacesAndSuperclassConstraints() async {
+  Future<void>
+      test_writeMixinDeclaration_interfacesAndSuperclassConstraints() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {} class B {}');
     DartType typeA = await _getType(path, 'A');
@@ -808,7 +816,7 @@
         equalsIgnoringWhitespace('mixin M on B implements A { }'));
   }
 
-  test_writeMixinDeclaration_memberWriter() async {
+  Future<void> test_writeMixinDeclaration_memberWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '');
 
@@ -825,7 +833,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('mixin M { /**/}'));
   }
 
-  test_writeMixinDeclaration_nameGroupName() async {
+  Future<void> test_writeMixinDeclaration_nameGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '');
 
@@ -847,7 +855,7 @@
     expect(group.positions, hasLength(1));
   }
 
-  test_writeMixinDeclaration_superclassConstraints() async {
+  Future<void> test_writeMixinDeclaration_superclassConstraints() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {}');
     DartType typeA = await _getType(path, 'A');
@@ -863,7 +871,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('mixin M on A { }'));
   }
 
-  test_writeParameter() async {
+  Future<void> test_writeParameter() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -878,7 +886,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('a'));
   }
 
-  test_writeParameter_type() async {
+  Future<void> test_writeParameter_type() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -894,7 +902,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A a'));
   }
 
-  test_writeParameterMatchingArgument() async {
+  Future<void> test_writeParameterMatchingArgument() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = r'''
 f() {}
@@ -923,7 +931,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A a'));
   }
 
-  test_writeParameters_named() async {
+  Future<void> test_writeParameters_named() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'f(int a, {bool b = false, String c}) {}';
     addSource(path, content);
@@ -945,7 +953,7 @@
         equalsIgnoringWhitespace('(int a, {bool b = false, String c})'));
   }
 
-  test_writeParameters_positional() async {
+  Future<void> test_writeParameters_positional() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'f(int a, [bool b = false, String c]) {}';
     addSource(path, content);
@@ -966,7 +974,7 @@
         equalsIgnoringWhitespace('(int a, [bool b = false, String c])'));
   }
 
-  test_writeParameters_required() async {
+  Future<void> test_writeParameters_required() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'f(int i, String s) {}';
     addSource(path, content);
@@ -986,7 +994,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('(int i, String s)'));
   }
 
-  test_writeParametersMatchingArguments_named() async {
+  Future<void> test_writeParametersMatchingArguments_named() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 f(int i, String s) {
@@ -1011,7 +1019,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('String s, {int index}'));
   }
 
-  test_writeParametersMatchingArguments_required() async {
+  Future<void> test_writeParametersMatchingArguments_required() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = '''
 f(int i, String s) {
@@ -1036,7 +1044,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('String s, int i'));
   }
 
-  test_writeReference_method() async {
+  Future<void> test_writeReference_method() async {
     String aPath = convertPath('/a.dart');
     addSource(aPath, r'''
 class A {
@@ -1063,7 +1071,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('foo'));
   }
 
-  test_writeReference_topLevel_hasImport_noPrefix() async {
+  Future<void> test_writeReference_topLevel_hasImport_noPrefix() async {
     String aPath = convertPath('/home/test/lib/a.dart');
     addSource(aPath, 'const a = 42;');
 
@@ -1085,7 +1093,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('a'));
   }
 
-  test_writeReference_topLevel_hasImport_prefix() async {
+  Future<void> test_writeReference_topLevel_hasImport_prefix() async {
     String aPath = convertPath('/home/test/lib/a.dart');
     addSource(aPath, 'const a = 42;');
 
@@ -1107,7 +1115,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('p.a'));
   }
 
-  test_writeReference_topLevel_noImport() async {
+  Future<void> test_writeReference_topLevel_noImport() async {
     String aPath = convertPath('/home/test/bin/a.dart');
     addSource(aPath, 'const a = 42;');
 
@@ -1129,7 +1137,7 @@
     expect(edits[1].replacement, equalsIgnoringWhitespace('a'));
   }
 
-  test_writeSetterDeclaration_bodyWriter() async {
+  Future<void> test_writeSetterDeclaration_bodyWriter() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1147,7 +1155,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('set s(s) {/* TODO */}'));
   }
 
-  test_writeSetterDeclaration_isStatic() async {
+  Future<void> test_writeSetterDeclaration_isStatic() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1163,7 +1171,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('static set s(s) {}'));
   }
 
-  test_writeSetterDeclaration_nameGroupName() async {
+  Future<void> test_writeSetterDeclaration_nameGroupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1188,7 +1196,7 @@
     expect(position.offset, equals(13));
   }
 
-  test_writeSetterDeclaration_parameterType() async {
+  Future<void> test_writeSetterDeclaration_parameterType() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B {}';
     addSource(path, content);
@@ -1214,7 +1222,7 @@
     expect(position.offset, equals(26));
   }
 
-  test_writeType_dynamic() async {
+  Future<void> test_writeType_dynamic() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1231,31 +1239,31 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
-  test_writeType_function() async {
+  Future<void> test_writeType_function() async {
     await _assertWriteType('int Function(double a, String b)');
   }
 
-  test_writeType_function_generic() async {
+  Future<void> test_writeType_function_generic() async {
     await _assertWriteType('T Function<T, U>(T a, U b)');
   }
 
-  test_writeType_function_noReturnType() async {
+  Future<void> test_writeType_function_noReturnType() async {
     await _assertWriteType('Function()');
   }
 
-  test_writeType_function_parameters_named() async {
+  Future<void> test_writeType_function_parameters_named() async {
     await _assertWriteType('int Function(int a, {int b, int c})');
   }
 
-  test_writeType_function_parameters_noName() async {
+  Future<void> test_writeType_function_parameters_noName() async {
     await _assertWriteType('int Function(double, String)');
   }
 
-  test_writeType_function_parameters_positional() async {
+  Future<void> test_writeType_function_parameters_positional() async {
     await _assertWriteType('int Function(int a, [int b, int c])');
   }
 
-  test_writeType_genericType() async {
+  Future<void> test_writeType_genericType() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B<E> {}';
     addSource(path, content);
@@ -1272,7 +1280,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('B<A>'));
   }
 
-  test_writeType_groupName() async {
+  Future<void> test_writeType_groupName() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B extends A {} class C extends B {}';
     addSource(path, content);
@@ -1294,7 +1302,7 @@
     expect(group, isNotNull);
   }
 
-  test_writeType_groupName_addSupertypeProposals() async {
+  Future<void> test_writeType_groupName_addSupertypeProposals() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B extends A {} class C extends B {}';
     addSource(path, content);
@@ -1327,7 +1335,7 @@
     expect(values, contains('C'));
   }
 
-  test_writeType_groupName_invalidType() async {
+  Future<void> test_writeType_groupName_invalidType() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A<T> {}';
     addSource(path, content);
@@ -1348,15 +1356,15 @@
     expect(builder.sourceChange.linkedEditGroups, isEmpty);
   }
 
-  test_writeType_interface_typeArguments() async {
+  Future<void> test_writeType_interface_typeArguments() async {
     await _assertWriteType('Map<int, List<String>>');
   }
 
-  test_writeType_interface_typeArguments_allDynamic() async {
+  Future<void> test_writeType_interface_typeArguments_allDynamic() async {
     await _assertWriteType('Map');
   }
 
-  test_writeType_null() async {
+  Future<void> test_writeType_null() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1371,7 +1379,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace(''));
   }
 
-  test_writeType_prefixGenerator() async {
+  Future<void> test_writeType_prefixGenerator() async {
     String aPath = convertPath('/home/test/lib/a.dart');
     String bPath = convertPath('/home/test/lib/b.dart');
 
@@ -1430,7 +1438,7 @@
             '_prefix0.A1 a1; _prefix0.A2 a2; _prefix1.B b;'));
   }
 
-  test_writeType_required_dynamic() async {
+  Future<void> test_writeType_required_dynamic() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1448,7 +1456,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var'));
   }
 
-  test_writeType_required_notNull() async {
+  Future<void> test_writeType_required_notNull() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1464,7 +1472,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A'));
   }
 
-  test_writeType_required_null() async {
+  Future<void> test_writeType_required_null() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1479,7 +1487,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('var'));
   }
 
-  test_writeType_simpleType() async {
+  Future<void> test_writeType_simpleType() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1495,16 +1503,16 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A'));
   }
 
-  test_writeType_typedef_typeArguments() async {
+  Future<void> test_writeType_typedef_typeArguments() async {
     await _assertWriteType('F<int, String>',
         declarations: 'typedef void F<T, U>(T t, U u);');
   }
 
-  test_writeType_void() async {
+  Future<void> test_writeType_void() async {
     await _assertWriteType('void Function()');
   }
 
-  test_writeTypes_empty() async {
+  Future<void> test_writeTypes_empty() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1519,7 +1527,7 @@
     expect(edit.replacement, isEmpty);
   }
 
-  test_writeTypes_noPrefix() async {
+  Future<void> test_writeTypes_noPrefix() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B {}';
     addSource(path, content);
@@ -1536,7 +1544,7 @@
     expect(edit.replacement, equalsIgnoringWhitespace('A, B'));
   }
 
-  test_writeTypes_null() async {
+  Future<void> test_writeTypes_null() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
     addSource(path, content);
@@ -1551,7 +1559,7 @@
     expect(edit.replacement, isEmpty);
   }
 
-  test_writeTypes_prefix() async {
+  Future<void> test_writeTypes_prefix() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {} class B {}';
     addSource(path, content);
@@ -1613,7 +1621,7 @@
 @reflectiveTest
 class DartFileEditBuilderImplTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_convertFunctionFromSyncToAsync_closure() async {
+  Future<void> test_convertFunctionFromSyncToAsync_closure() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '''var f = () {}''');
 
@@ -1631,7 +1639,7 @@
     expect(edits[0].replacement, equalsIgnoringWhitespace('async'));
   }
 
-  test_convertFunctionFromSyncToAsync_topLevelFunction() async {
+  Future<void> test_convertFunctionFromSyncToAsync_topLevelFunction() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'String f() {}');
 
@@ -1650,7 +1658,7 @@
     expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>'));
   }
 
-  test_createEditBuilder() async {
+  Future<void> test_createEditBuilder() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'library test;');
     DartChangeBuilderImpl builder = newBuilder();
@@ -1667,7 +1675,7 @@
     });
   }
 
-  test_format_hasEdits() async {
+  Future<void> test_format_hasEdits() async {
     var initialCode = r'''
 void functionBefore() {
   1 +  2;
@@ -1719,7 +1727,7 @@
 ''');
   }
 
-  test_format_noEdits() async {
+  Future<void> test_format_noEdits() async {
     var initialCode = r'''
 void functionBefore() {
   1 +  2;
@@ -1762,7 +1770,7 @@
 ''');
   }
 
-  test_replaceTypeWithFuture() async {
+  Future<void> test_replaceTypeWithFuture() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'String f() {}');
 
@@ -1783,7 +1791,7 @@
 
 @reflectiveTest
 class DartLinkedEditBuilderImplTest extends AbstractContextTest {
-  test_addSuperTypesAsSuggestions() async {
+  Future<void> test_addSuperTypesAsSuggestions() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, '''
 class A {}
@@ -1809,7 +1817,7 @@
 @reflectiveTest
 class ImportLibraryTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_dart_beforeDart() async {
+  Future<void> test_dart_beforeDart() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:aaa';
@@ -1824,7 +1832,7 @@
     );
   }
 
-  test_dart_beforeDart_first() async {
+  Future<void> test_dart_beforeDart_first() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:bbb';
@@ -1837,7 +1845,7 @@
     );
   }
 
-  test_dart_beforePackage() async {
+  Future<void> test_dart_beforePackage() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:foo/foo.dart';
@@ -1851,7 +1859,7 @@
     );
   }
 
-  test_multiple_dart_then_package() async {
+  Future<void> test_multiple_dart_then_package() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:aaa';
@@ -1873,7 +1881,7 @@
     );
   }
 
-  test_multiple_package_then_dart() async {
+  Future<void> test_multiple_package_then_dart() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:aaa';
@@ -1895,7 +1903,7 @@
     );
   }
 
-  test_noDirectives_docComment() async {
+  Future<void> test_noDirectives_docComment() async {
     await _assertImportLibrary(
       initialCode: '''
 /// Documentation comment.
@@ -1913,7 +1921,7 @@
     );
   }
 
-  test_noDirectives_hashBang() async {
+  Future<void> test_noDirectives_hashBang() async {
     await _assertImportLibrary(
       initialCode: '''
 #!/bin/dart
@@ -1931,7 +1939,7 @@
     );
   }
 
-  test_noDirectives_lineComment() async {
+  Future<void> test_noDirectives_lineComment() async {
     await _assertImportLibrary(
       initialCode: '''
 // Not documentation comment.
@@ -1951,7 +1959,7 @@
     );
   }
 
-  test_noImports_afterLibrary_hasDeclaration() async {
+  Future<void> test_noImports_afterLibrary_hasDeclaration() async {
     await _assertImportLibrary(
       initialCode: '''
 library test;
@@ -1969,7 +1977,7 @@
     );
   }
 
-  test_noImports_afterLibrary_hasPart() async {
+  Future<void> test_noImports_afterLibrary_hasPart() async {
     await _assertImportLibrary(
       initialCode: '''
 library test;
@@ -1988,7 +1996,7 @@
     );
   }
 
-  test_noImports_beforePart() async {
+  Future<void> test_noImports_beforePart() async {
     await _assertImportLibrary(
       initialCode: '''
 part 'a.dart';
@@ -2003,7 +2011,7 @@
     );
   }
 
-  test_package_afterDart() async {
+  Future<void> test_package_afterDart() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:async';
@@ -2017,7 +2025,7 @@
     );
   }
 
-  test_package_afterPackage() async {
+  Future<void> test_package_afterPackage() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:aaa/a1.dart';
@@ -2034,7 +2042,7 @@
     );
   }
 
-  test_package_afterPackage_leadingComment() async {
+  Future<void> test_package_afterPackage_leadingComment() async {
     await _assertImportLibrary(
       initialCode: '''
 // comment
@@ -2053,7 +2061,7 @@
     );
   }
 
-  test_package_afterPackage_trailingComment() async {
+  Future<void> test_package_afterPackage_trailingComment() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:aaa/a1.dart'; // comment
@@ -2070,7 +2078,7 @@
     );
   }
 
-  test_package_beforePackage() async {
+  Future<void> test_package_beforePackage() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:aaa/a1.dart';
@@ -2089,7 +2097,7 @@
     );
   }
 
-  test_package_beforePackage_first() async {
+  Future<void> test_package_beforePackage_first() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:aaa/a2.dart';
@@ -2106,7 +2114,7 @@
     );
   }
 
-  test_package_beforePackage_leadingComments() async {
+  Future<void> test_package_beforePackage_leadingComments() async {
     await _assertImportLibrary(
       initialCode: '''
 // comment a2
@@ -2125,7 +2133,7 @@
     );
   }
 
-  test_package_beforePackage_trailingComments() async {
+  Future<void> test_package_beforePackage_trailingComments() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:aaa/a2.dart'; // comment a2
@@ -2142,7 +2150,7 @@
     );
   }
 
-  test_package_beforeRelative() async {
+  Future<void> test_package_beforeRelative() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'foo.dart';
@@ -2156,7 +2164,7 @@
     );
   }
 
-  test_relative_afterDart() async {
+  Future<void> test_relative_afterDart() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:async';
@@ -2170,7 +2178,7 @@
     );
   }
 
-  test_relative_afterPackage() async {
+  Future<void> test_relative_afterPackage() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'package:foo/foo.dart';
@@ -2184,7 +2192,7 @@
     );
   }
 
-  test_relative_beforeRelative() async {
+  Future<void> test_relative_beforeRelative() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:async';
@@ -2207,7 +2215,7 @@
     );
   }
 
-  test_relative_beforeRelative_first() async {
+  Future<void> test_relative_beforeRelative_first() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:async';
@@ -2228,7 +2236,7 @@
     );
   }
 
-  test_relative_last() async {
+  Future<void> test_relative_last() async {
     await _assertImportLibrary(
       initialCode: '''
 import 'dart:async';
@@ -2273,7 +2281,7 @@
 @reflectiveTest
 class WriteOverrideTest extends AbstractContextTest
     with DartChangeBuilderMixin {
-  test_getter_abstract() async {
+  Future<void> test_getter_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2293,7 +2301,7 @@
     );
   }
 
-  test_getter_concrete() async {
+  Future<void> test_getter_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2314,7 +2322,7 @@
     );
   }
 
-  test_method_abstract() async {
+  Future<void> test_method_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2336,7 +2344,7 @@
     );
   }
 
-  test_method_concrete() async {
+  Future<void> test_method_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2359,7 +2367,7 @@
     );
   }
 
-  test_method_functionTypeAlias_abstract() async {
+  Future<void> test_method_functionTypeAlias_abstract() async {
     await _assertWriteOverride(
       content: '''
 typedef int F(int left, int right);
@@ -2380,7 +2388,7 @@
     );
   }
 
-  test_method_functionTypeAlias_concrete() async {
+  Future<void> test_method_functionTypeAlias_concrete() async {
     await _assertWriteOverride(
       content: '''
 typedef int F(int left, int right);
@@ -2404,7 +2412,7 @@
     );
   }
 
-  test_method_functionTypedParameter_abstract() async {
+  Future<void> test_method_functionTypedParameter_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2426,7 +2434,7 @@
     );
   }
 
-  test_method_functionTypedParameter_concrete() async {
+  Future<void> test_method_functionTypedParameter_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2449,7 +2457,7 @@
     );
   }
 
-  test_method_generic_noBounds_abstract() async {
+  Future<void> test_method_generic_noBounds_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2471,7 +2479,7 @@
     );
   }
 
-  test_method_generic_noBounds_concrete() async {
+  Future<void> test_method_generic_noBounds_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2494,7 +2502,7 @@
     );
   }
 
-  test_method_generic_withBounds_abstract() async {
+  Future<void> test_method_generic_withBounds_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A<K1, V1> {
@@ -2516,7 +2524,7 @@
     );
   }
 
-  test_method_generic_withBounds_concrete() async {
+  Future<void> test_method_generic_withBounds_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A<K1, V1> {
@@ -2541,7 +2549,7 @@
     );
   }
 
-  test_method_genericFunctionTypedParameter_abstract() async {
+  Future<void> test_method_genericFunctionTypedParameter_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2563,7 +2571,7 @@
     );
   }
 
-  test_method_genericFunctionTypedParameter_concrete() async {
+  Future<void> test_method_genericFunctionTypedParameter_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2586,7 +2594,7 @@
     );
   }
 
-  test_method_nullAsTypeArgument_abstract() async {
+  Future<void> test_method_nullAsTypeArgument_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2608,7 +2616,7 @@
     );
   }
 
-  test_method_nullAsTypeArgument_concrete() async {
+  Future<void> test_method_nullAsTypeArgument_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2631,7 +2639,7 @@
     );
   }
 
-  test_method_returnVoid_abstract() async {
+  Future<void> test_method_returnVoid_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2652,7 +2660,7 @@
     );
   }
 
-  test_method_voidAsTypeArgument_abstract() async {
+  Future<void> test_method_voidAsTypeArgument_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2674,7 +2682,7 @@
     );
   }
 
-  test_method_voidAsTypeArgument_concrete() async {
+  Future<void> test_method_voidAsTypeArgument_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2697,7 +2705,7 @@
     );
   }
 
-  test_mixin_method_of_interface() async {
+  Future<void> test_mixin_method_of_interface() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2720,7 +2728,7 @@
     );
   }
 
-  test_mixin_method_of_superclassConstraint() async {
+  Future<void> test_mixin_method_of_superclassConstraint() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2745,7 +2753,7 @@
     );
   }
 
-  test_setter_abstract() async {
+  Future<void> test_setter_abstract() async {
     await _assertWriteOverride(
       content: '''
 abstract class A {
@@ -2766,7 +2774,7 @@
     );
   }
 
-  test_setter_concrete() async {
+  Future<void> test_setter_concrete() async {
     await _assertWriteOverride(
       content: '''
 class A {
@@ -2796,7 +2804,7 @@
   /// (modulo white space). Assert that the generated display text matches the
   /// given [displayText]. If a [selection] is provided, assert that the
   /// generated selection range matches it.
-  _assertWriteOverride({
+  Future<void> _assertWriteOverride({
     String content,
     String nameToOverride,
     String expected,
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
index fbf1131..3e3a002 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -12,7 +12,7 @@
 import '../../../../support/abstract_context.dart';
 import 'dart_change_builder_mixin.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ImportLibraryElementTest);
     defineReflectiveTests(ImportLibraryElement_existingImport_Test);
@@ -22,7 +22,7 @@
 
 @reflectiveTest
 class ImportLibraryElement_existingImport_Test extends _Base {
-  test_dartCore_implicit() async {
+  Future<void> test_dartCore_implicit() async {
     await _assertImportLibraryElement(
       initialCode: r'''
 import 'dart:math';
@@ -32,7 +32,7 @@
     );
   }
 
-  test_dartCore_withPrefix() async {
+  Future<void> test_dartCore_withPrefix() async {
     await _assertImportLibraryElement(
       initialCode: r'''
 import 'dart:core' as my_core;
@@ -44,7 +44,7 @@
     );
   }
 
-  test_withoutPrefix() async {
+  Future<void> test_withoutPrefix() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
 
     await _assertImportLibraryElement(
@@ -56,7 +56,7 @@
     );
   }
 
-  test_withoutPrefix_exported() async {
+  Future<void> test_withoutPrefix_exported() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'a.dart';
@@ -70,7 +70,7 @@
     );
   }
 
-  test_withoutPrefix_referencedNames_sameElements() async {
+  Future<void> test_withoutPrefix_referencedNames_sameElements() async {
     newFile('/home/test/lib/a.dart', content: r'''
 class A {}
 ''');
@@ -91,7 +91,7 @@
     );
   }
 
-  test_withoutPrefix_twoImports_sameElement() async {
+  Future<void> test_withoutPrefix_twoImports_sameElement() async {
     newFile('/home/test/lib/a.dart', content: 'class C {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'package:test/a.dart';
@@ -116,7 +116,7 @@
     );
   }
 
-  test_withPrefix() async {
+  Future<void> test_withPrefix() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
 
     await _assertImportLibraryElement(
@@ -129,7 +129,7 @@
     );
   }
 
-  test_withPrefix_twoImports_sameElement() async {
+  Future<void> test_withPrefix_twoImports_sameElement() async {
     newFile('/home/test/lib/a.dart', content: 'class C {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'package:test/a.dart';
@@ -159,7 +159,7 @@
 
 @reflectiveTest
 class ImportLibraryElement_newImport_withoutPrefix_Test extends _Base {
-  test_constructorName_name() async {
+  Future<void> test_constructorName_name() async {
     newFile('/home/test/lib/a.dart', content: r'''
 int foo;
 ''');
@@ -189,7 +189,7 @@
     );
   }
 
-  test_exported() async {
+  Future<void> test_exported() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'a.dart';
@@ -204,7 +204,7 @@
     );
   }
 
-  test_exported_differentUri() async {
+  Future<void> test_exported_differentUri() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'a.dart';
@@ -222,7 +222,7 @@
     );
   }
 
-  test_methodInvocation_name() async {
+  Future<void> test_methodInvocation_name() async {
     newFile('/home/test/lib/a.dart', content: r'''
 int foo;
 ''');
@@ -252,7 +252,7 @@
     );
   }
 
-  test_noConflict_otherImport_hide() async {
+  Future<void> test_noConflict_otherImport_hide() async {
     newFile('/home/test/lib/a.dart', content: r'''
 class A {}
 class B {}
@@ -271,7 +271,7 @@
     );
   }
 
-  test_noConflict_otherImport_show() async {
+  Future<void> test_noConflict_otherImport_show() async {
     newFile('/home/test/lib/a.dart', content: r'''
 class A {}
 class B {}
@@ -290,7 +290,7 @@
     );
   }
 
-  test_noShadow_syntacticScope_localVariable() async {
+  Future<void> test_noShadow_syntacticScope_localVariable() async {
     newFile('/home/test/lib/a.dart', content: r'''
 var foo = 0;
 ''');
@@ -322,7 +322,7 @@
     );
   }
 
-  test_noShadow_syntacticScope_typeParameter() async {
+  Future<void> test_noShadow_syntacticScope_typeParameter() async {
     newFile('/home/test/lib/a.dart', content: r'''
 class A {}
 ''');
@@ -344,7 +344,7 @@
     );
   }
 
-  test_prefixedIdentifier_identifier() async {
+  Future<void> test_prefixedIdentifier_identifier() async {
     newFile('/home/test/lib/a.dart', content: r'''
 int foo;
 ''');
@@ -374,7 +374,7 @@
     );
   }
 
-  test_thisName_notShadowed_localVariable_otherFunction() async {
+  Future<void> test_thisName_notShadowed_localVariable_otherFunction() async {
     newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
     await _assertImportLibraryElement(
       initialCode: r'''
@@ -402,7 +402,7 @@
     );
   }
 
-  test_unrelated() async {
+  Future<void> test_unrelated() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: 'class B {}');
     await _assertImportLibraryElement(
@@ -421,7 +421,7 @@
 
 @reflectiveTest
 class ImportLibraryElementTest extends _Base {
-  test_thisLibrary() async {
+  Future<void> test_thisLibrary() async {
     await _assertImportLibraryElement(
       initialCode: r'''
 class A {}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
index 06a0484..d11503b 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
@@ -6,8 +6,7 @@
 
 import 'import_library_element_test.dart' as import_library_element;
 
-/// Utility for manually running all tests.
-main() {
+void main() {
   defineReflectiveSuite(() {
     import_library_element.main();
   });
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
index 2e5d995..59d3e82 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
@@ -8,8 +8,7 @@
 import 'change_builder_dart_test.dart' as change_builder_dart_test;
 import 'dart/test_all.dart' as dart_all;
 
-/// Utility for manually running all tests.
-main() {
+void main() {
   defineReflectiveSuite(() {
     change_builder_core_test.main();
     change_builder_dart_test.main();
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index cf6fd01..2a780d3 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -15,7 +15,7 @@
 
 import '../../../support/abstract_context.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgumentListCompletionTargetTest);
     defineReflectiveTests(CompletionTargetTest);
@@ -24,7 +24,7 @@
 
 @reflectiveTest
 class ArgumentListCompletionTargetTest extends _Base {
-  test_Annotation_named() async {
+  Future<void> test_Annotation_named() async {
     await createTarget('''
 class Foo {
   const Foo({int a, String b});
@@ -42,7 +42,7 @@
     );
   }
 
-  test_Annotation_positional() async {
+  Future<void> test_Annotation_positional() async {
     await createTarget('''
 class Foo {
   const Foo(int a);
@@ -60,7 +60,7 @@
     );
   }
 
-  test_InstanceCreationExpression_explicitNew_unresolved() async {
+  Future<void> test_InstanceCreationExpression_explicitNew_unresolved() async {
     await createTarget('''
 main() {
   new Foo(^)
@@ -69,7 +69,8 @@
     assertTarget(')', '()', argIndex: 0);
   }
 
-  test_InstanceCreationExpression_generic_explicitTypeArgument() async {
+  Future<void>
+      test_InstanceCreationExpression_generic_explicitTypeArgument() async {
     await createTarget('''
 class Foo<T> {
   Foo(T a, T b);
@@ -88,7 +89,8 @@
     );
   }
 
-  test_InstanceCreationExpression_generic_inferredTypeArgument() async {
+  Future<void>
+      test_InstanceCreationExpression_generic_inferredTypeArgument() async {
     await createTarget('''
 class Foo<T> {
   Foo(T a, T b);
@@ -107,7 +109,7 @@
     );
   }
 
-  test_InstanceCreationExpression_named() async {
+  Future<void> test_InstanceCreationExpression_named() async {
     await createTarget('''
 class Foo {
   Foo({int a, String b, double c});
@@ -127,7 +129,7 @@
     );
   }
 
-  test_InstanceCreationExpression_named_unresolved() async {
+  Future<void> test_InstanceCreationExpression_named_unresolved() async {
     await createTarget('''
 class Foo {
   Foo({int a});
@@ -145,7 +147,7 @@
     );
   }
 
-  test_InstanceCreationExpression_namedConstructor() async {
+  Future<void> test_InstanceCreationExpression_namedConstructor() async {
     await createTarget('''
 class Foo {
   Foo.named(int a, String b, double c);
@@ -164,7 +166,7 @@
     );
   }
 
-  test_InstanceCreationExpression_positional() async {
+  Future<void> test_InstanceCreationExpression_positional() async {
     await createTarget('''
 class Foo {
   Foo(int a);
@@ -183,7 +185,7 @@
     );
   }
 
-  test_InstanceCreationExpression_positional_isFunctional() async {
+  Future<void> test_InstanceCreationExpression_positional_isFunctional() async {
     await createTarget('''
 class Foo {
   Foo(int Function(String) f);
@@ -203,7 +205,7 @@
     );
   }
 
-  test_InstanceCreationExpression_positional_noParameter0() async {
+  Future<void> test_InstanceCreationExpression_positional_noParameter0() async {
     await createTarget('''
 class Foo {}
 
@@ -219,7 +221,7 @@
     );
   }
 
-  test_InstanceCreationExpression_positional_noParameter1() async {
+  Future<void> test_InstanceCreationExpression_positional_noParameter1() async {
     await createTarget('''
 class Foo {}
 
@@ -235,7 +237,7 @@
     );
   }
 
-  test_MethodInvocation_named() async {
+  Future<void> test_MethodInvocation_named() async {
     await createTarget('''
 int foo({int a, String b, double c}) {}
 
@@ -252,7 +254,7 @@
     );
   }
 
-  test_MethodInvocation_named_isFunctional() async {
+  Future<void> test_MethodInvocation_named_isFunctional() async {
     await createTarget('''
 int foo({int Function(String) f}) {}
 
@@ -270,7 +272,7 @@
     );
   }
 
-  test_MethodInvocation_named_unresolved() async {
+  Future<void> test_MethodInvocation_named_unresolved() async {
     await createTarget('''
 int foo({int a}) {}
 
@@ -286,7 +288,7 @@
     );
   }
 
-  test_MethodInvocation_positional2() async {
+  Future<void> test_MethodInvocation_positional2() async {
     await createTarget('''
 int foo(int a, String b) {}
 
@@ -303,7 +305,7 @@
     );
   }
 
-  test_MethodInvocation_positional_isFunctional() async {
+  Future<void> test_MethodInvocation_positional_isFunctional() async {
     await createTarget('''
 int foo(int Function(String) f) {}
 
@@ -321,7 +323,7 @@
     );
   }
 
-  test_MethodInvocation_positional_isFunctional2() async {
+  Future<void> test_MethodInvocation_positional_isFunctional2() async {
     await createTarget('''
 class C {
   int foo(int Function(String) f) {}
@@ -341,7 +343,7 @@
     );
   }
 
-  test_MethodInvocation_positional_withPrefix() async {
+  Future<void> test_MethodInvocation_positional_withPrefix() async {
     await createTarget('''
 int foo(int a, String b) {}
 
@@ -358,7 +360,7 @@
     );
   }
 
-  test_MethodInvocation_positional_withPrefix2() async {
+  Future<void> test_MethodInvocation_positional_withPrefix2() async {
     await createTarget('''
 int foo(int a, String b) {}
 
@@ -375,7 +377,7 @@
     );
   }
 
-  test_MethodInvocation_positional_withSuffix() async {
+  Future<void> test_MethodInvocation_positional_withSuffix() async {
     await createTarget('''
 int foo(int a, String b) {}
 
@@ -392,7 +394,7 @@
     );
   }
 
-  test_MethodInvocation_unresolved() async {
+  Future<void> test_MethodInvocation_unresolved() async {
     await createTarget('''
 main() {
   foo(^)
@@ -401,7 +403,7 @@
     assertTarget(')', '()', argIndex: 0);
   }
 
-  test_not_ListLiteral() async {
+  Future<void> test_not_ListLiteral() async {
     await createTarget('''
 main() {
   print([^]);
@@ -415,84 +417,84 @@
 
 @reflectiveTest
 class CompletionTargetTest extends _Base {
-  test_AsExpression_identifier() async {
+  Future<void> test_AsExpression_identifier() async {
     // SimpleIdentifier  TypeName  AsExpression
     await createTarget(
         'class A {var b; X _c; foo() {var a; (a^ as String).foo();}');
     assertTarget('a as String', '(a as String)');
   }
 
-  test_AsExpression_keyword() async {
+  Future<void> test_AsExpression_keyword() async {
     // SimpleIdentifier  TypeName  AsExpression
     await createTarget(
         'class A {var b; X _c; foo() {var a; (a ^as String).foo();}');
     assertTarget('as', 'a as String');
   }
 
-  test_AsExpression_keyword2() async {
+  Future<void> test_AsExpression_keyword2() async {
     // SimpleIdentifier  TypeName  AsExpression
     await createTarget(
         'class A {var b; X _c; foo() {var a; (a a^s String).foo();}');
     assertTarget('as', 'a as String');
   }
 
-  test_AsExpression_keyword3() async {
+  Future<void> test_AsExpression_keyword3() async {
     // SimpleIdentifier  TypeName  AsExpression
     await createTarget(
         'class A {var b; X _c; foo() {var a; (a as^ String).foo();}');
     assertTarget('as', 'a as String');
   }
 
-  test_AsExpression_type() async {
+  Future<void> test_AsExpression_type() async {
     // SimpleIdentifier  TypeName  AsExpression
     await createTarget(
         'class A {var b; X _c; foo() {var a; (a as ^String).foo();}');
     assertTarget('String', 'a as String');
   }
 
-  test_Block() async {
+  Future<void> test_Block() async {
     // Block
     await createTarget('main() {^}');
     assertTarget('}', '{}');
   }
 
-  test_Block_keyword() async {
+  Future<void> test_Block_keyword() async {
     await createTarget(
         'class C { static C get instance => null; } main() {C.in^}');
     assertTarget('in', 'C.in');
   }
 
-  test_Block_keyword2() async {
+  Future<void> test_Block_keyword2() async {
     await createTarget(
         'class C { static C get instance => null; } main() {C.i^n}');
     assertTarget('in', 'C.in');
   }
 
-  test_FormalParameter_partialType() async {
+  Future<void> test_FormalParameter_partialType() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
     await createTarget('foo(b.^ f) { }');
     assertTarget('f', 'b.f');
   }
 
-  test_FormalParameter_partialType2() async {
+  Future<void> test_FormalParameter_partialType2() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
     await createTarget('foo(b.z^ f) { }');
     assertTarget('z', 'b.z');
   }
 
-  test_FormalParameter_partialType3() async {
+  Future<void> test_FormalParameter_partialType3() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
     await createTarget('foo(b.^) { }');
     assertTarget('', 'b.');
   }
 
-  test_FormalParameterList() async {
+  Future<void> test_FormalParameterList() async {
     // Token  FormalParameterList  FunctionExpression
     await createTarget('foo(^) { }');
     assertTarget(')', '()');
   }
 
-  test_FunctionDeclaration_inLineComment() async {
+  Future<void> test_FunctionDeclaration_inLineComment() async {
     // Comment  CompilationUnit
     await createTarget('''
       // normal comment ^
@@ -500,7 +502,7 @@
     assertTarget('// normal comment ', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inLineComment2() async {
+  Future<void> test_FunctionDeclaration_inLineComment2() async {
     // Comment  CompilationUnit
     await createTarget('''
       // normal ^comment
@@ -508,7 +510,7 @@
     assertTarget('// normal comment', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inLineComment3() async {
+  Future<void> test_FunctionDeclaration_inLineComment3() async {
     // Comment  CompilationUnit
     await createTarget('''
       // normal comment ^
@@ -517,7 +519,7 @@
     assertTarget('// normal comment ', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inLineComment4() async {
+  Future<void> test_FunctionDeclaration_inLineComment4() async {
     // Comment  CompilationUnit
     await createTarget('''
       // normal comment
@@ -526,7 +528,7 @@
     assertTarget('// normal comment 2', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inLineDocComment() async {
+  Future<void> test_FunctionDeclaration_inLineDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
     await createTarget('''
       /// some dartdoc ^
@@ -536,7 +538,7 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_inLineDocComment2() async {
+  Future<void> test_FunctionDeclaration_inLineDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
     await createTarget('''
       /// some ^dartdoc
@@ -546,19 +548,19 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_inStarComment() async {
+  Future<void> test_FunctionDeclaration_inStarComment() async {
     // Comment  CompilationUnit
     await createTarget('/* ^ */ zoo(z) {} String name;');
     assertTarget('/*  */', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inStarComment2() async {
+  Future<void> test_FunctionDeclaration_inStarComment2() async {
     // Comment  CompilationUnit
     await createTarget('/*  *^/ zoo(z) {} String name;');
     assertTarget('/*  */', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_inStarDocComment() async {
+  Future<void> test_FunctionDeclaration_inStarDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
     await createTarget('/** ^ */ zoo(z) { } String name;');
     assertTarget('/**  */', '');
@@ -566,7 +568,7 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_inStarDocComment2() async {
+  Future<void> test_FunctionDeclaration_inStarDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
     await createTarget('/**  *^/ zoo(z) { } String name;');
     assertTarget('/**  */', '');
@@ -574,13 +576,13 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_returnType() async {
+  Future<void> test_FunctionDeclaration_returnType() async {
     // CompilationUnit
     await createTarget('^ zoo(z) { } String name;');
     assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_returnType_afterLineComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineComment() async {
     // FunctionDeclaration  CompilationUnit
     await createTarget('''
       // normal comment
@@ -588,7 +590,7 @@
     assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_returnType_afterLineComment2() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineComment2() async {
     // FunctionDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     await createTarget('''
@@ -597,7 +599,7 @@
     assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_returnType_afterLineDocComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineDocComment() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     await createTarget('''
       /// some dartdoc
@@ -605,7 +607,8 @@
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_returnType_afterLineDocComment2() async {
+  Future<void>
+      test_FunctionDeclaration_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     await createTarget('''
 /// some dartdoc
@@ -613,31 +616,32 @@
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_returnType_afterStarComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarComment() async {
     // CompilationUnit
     await createTarget('/* */ ^ zoo(z) { } String name;');
     assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_returnType_afterStarComment2() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarComment2() async {
     // CompilationUnit
     await createTarget('/* */^ zoo(z) { } String name;');
     assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
-  test_FunctionDeclaration_returnType_afterStarDocComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarDocComment() async {
     // FunctionDeclaration  CompilationUnit
     await createTarget('/** */ ^ zoo(z) { } String name;');
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_FunctionDeclaration_returnType_afterStarDocComment2() async {
+  Future<void>
+      test_FunctionDeclaration_returnType_afterStarDocComment2() async {
     // FunctionDeclaration  CompilationUnit
     await createTarget('/** */^ zoo(z) { } String name;');
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_IfStatement_droppedToken() async {
+  Future<void> test_IfStatement_droppedToken() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('main() { if (v i^) }');
     if (usingFastaParser) {
@@ -647,32 +651,32 @@
     }
   }
 
-  test_InstanceCreationExpression_identifier() async {
+  Future<void> test_InstanceCreationExpression_identifier() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     await createTarget('class C {foo(){var f; {var x;} new ^C();}}');
     assertTarget('C', 'new C()');
   }
 
-  test_InstanceCreationExpression_keyword() async {
+  Future<void> test_InstanceCreationExpression_keyword() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     await createTarget('class C {foo(){var f; {var x;} new^ }}');
     assertTarget('new ();', '{var f; {var x;} new ();}');
   }
 
-  test_InstanceCreationExpression_keyword2() async {
+  Future<void> test_InstanceCreationExpression_keyword2() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     await createTarget('class C {foo(){var f; {var x;} new^ C();}}');
     assertTarget('new C();', '{var f; {var x;} new C();}');
   }
 
-  test_MapLiteral_empty() async {
+  Future<void> test_MapLiteral_empty() async {
     // MapLiteral  VariableDeclaration
     await createTarget('foo = {^');
     // fasta scanner inserts synthetic closing '}'
     assertTarget('}', '{}');
   }
 
-  test_MapLiteral_expression() async {
+  Future<void> test_MapLiteral_expression() async {
     super.setUp();
     final experimentStatus =
         (driver.analysisOptions as analyzer.AnalysisOptionsImpl)
@@ -691,13 +695,13 @@
     }
   }
 
-  test_MapLiteralEntry() async {
+  Future<void> test_MapLiteralEntry() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
     await createTarget('foo = {7:T^};');
     assertTarget('T', '7 : T');
   }
 
-  test_MethodDeclaration_inLineComment() async {
+  Future<void> test_MethodDeclaration_inLineComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -706,7 +710,7 @@
     assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inLineComment2() async {
+  Future<void> test_MethodDeclaration_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -715,7 +719,7 @@
     assertTarget('// normal comment', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inLineComment3() async {
+  Future<void> test_MethodDeclaration_inLineComment3() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -725,7 +729,7 @@
     assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inLineComment4() async {
+  Future<void> test_MethodDeclaration_inLineComment4() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -735,7 +739,7 @@
     assertTarget('// normal comment 2', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inLineDocComment() async {
+  Future<void> test_MethodDeclaration_inLineDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -746,7 +750,7 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_inLineDocComment2() async {
+  Future<void> test_MethodDeclaration_inLineDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -757,19 +761,19 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_inStarComment() async {
+  Future<void> test_MethodDeclaration_inStarComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/* ^ */ zoo(z) {} String name;}');
     assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inStarComment2() async {
+  Future<void> test_MethodDeclaration_inStarComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/*  *^/ zoo(z) {} String name;}');
     assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_inStarDocComment() async {
+  Future<void> test_MethodDeclaration_inStarDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/** ^ */ zoo(z) { } String name; }');
     assertTarget('/**  */', '');
@@ -777,7 +781,7 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_inStarDocComment2() async {
+  Future<void> test_MethodDeclaration_inStarDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/**  *^/ zoo(z) { } String name; }');
     assertTarget('/**  */', '');
@@ -785,13 +789,13 @@
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_returnType() async {
+  Future<void> test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
     await createTarget('class C2 {^ zoo(z) { } String name; }');
     assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_returnType_afterLineComment() async {
+  Future<void> test_MethodDeclaration_returnType_afterLineComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -800,7 +804,7 @@
     assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_returnType_afterLineComment2() async {
+  Future<void> test_MethodDeclaration_returnType_afterLineComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     await createTarget('''
@@ -810,7 +814,7 @@
     assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment() async {
+  Future<void> test_MethodDeclaration_returnType_afterLineDocComment() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('''
       class C2 {
@@ -819,7 +823,7 @@
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_returnType_afterLineDocComment2() async {
+  Future<void> test_MethodDeclaration_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('''
 class C2 {
@@ -828,73 +832,73 @@
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_returnType_afterStarComment() async {
+  Future<void> test_MethodDeclaration_returnType_afterStarComment() async {
     // ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/* */ ^ zoo(z) { } String name; }');
     assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_returnType_afterStarComment2() async {
+  Future<void> test_MethodDeclaration_returnType_afterStarComment2() async {
     // ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/* */^ zoo(z) { } String name; }');
     assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment() async {
+  Future<void> test_MethodDeclaration_returnType_afterStarDocComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/** */ ^ zoo(z) { } String name; }');
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_MethodDeclaration_returnType_afterStarDocComment2() async {
+  Future<void> test_MethodDeclaration_returnType_afterStarDocComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     await createTarget('class C2 {/** */^ zoo(z) { } String name; }');
     assertTarget('zoo', 'zoo(z) {}');
   }
 
-  test_SwitchStatement_c() async {
+  Future<void> test_SwitchStatement_c() async {
     // Token('c') SwitchStatement
     await createTarget('main() { switch(x) {c^} }');
     assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
-  test_SwitchStatement_c2() async {
+  Future<void> test_SwitchStatement_c2() async {
     // Token('c') SwitchStatement
     await createTarget('main() { switch(x) { c^ } }');
     assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
-  test_SwitchStatement_empty() async {
+  Future<void> test_SwitchStatement_empty() async {
     // SwitchStatement
     await createTarget('main() { switch(x) {^} }');
     assertTarget('}', 'switch (x) {}');
   }
 
-  test_SwitchStatement_empty2() async {
+  Future<void> test_SwitchStatement_empty2() async {
     // SwitchStatement
     await createTarget('main() { switch(x) { ^ } }');
     assertTarget('}', 'switch (x) {}');
   }
 
-  test_TypeArgumentList() async {
+  Future<void> test_TypeArgumentList() async {
     // TypeName  TypeArgumentList  TypeName
     await createTarget('main() { C<^> c; }');
     assertTarget('', '<>');
   }
 
-  test_TypeArgumentList2() async {
+  Future<void> test_TypeArgumentList2() async {
     // TypeName  TypeArgumentList  TypeName
     await createTarget('main() { C<C^> c; }');
     assertTarget('C', '<C>');
   }
 
-  test_VariableDeclaration_lhs_identifier_after() async {
+  Future<void> test_VariableDeclaration_lhs_identifier_after() async {
     // VariableDeclaration  VariableDeclarationList
     await createTarget('main() {int b^ = 1;}');
     assertTarget('b = 1', 'int b = 1');
   }
 
-  test_VariableDeclaration_lhs_identifier_before() async {
+  Future<void> test_VariableDeclaration_lhs_identifier_before() async {
     // VariableDeclaration  VariableDeclarationList
     await createTarget('main() {int ^b = 1;}');
     assertTarget('b = 1', 'int b = 1');
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index def2a2d..b975c97 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -14,7 +14,7 @@
 
 import '../../../support/abstract_context.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(OpTypeTest);
     defineReflectiveTests(OpTypeDart1OnlyTest);
@@ -26,7 +26,7 @@
 // TODO: determine if tests here need to be fixed for Dart2.
 class OpTypeDart1OnlyTest extends OpTypeTestCommon {
   @failingTest
-  test_Annotation() async {
+  Future<void> test_Annotation() async {
     // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
     addTestSource('class C { @A^ }');
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
@@ -43,7 +43,7 @@
     throw 'Remove this exception once fasta parser is the default';
   }
 
-  test_ArgumentList() async {
+  Future<void> test_ArgumentList() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('void main() {expect(^)}');
     // If "expect()" were resolved, then either namedArgs would be true
@@ -56,7 +56,7 @@
         functionBody: true);
   }
 
-  test_ArgumentList_namedParam() async {
+  Future<void> test_ArgumentList_namedParam() async {
     // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
     // ExpressionStatement
     addTestSource('void main() {expect(foo: ^)}');
@@ -67,7 +67,7 @@
         functionBody: true);
   }
 
-  test_ArgumentList_prefixedIdentifier() async {
+  Future<void> test_ArgumentList_prefixedIdentifier() async {
     // SimpleIdentifier  PrefixedIdentifier  ArgumentList
     addTestSource('void main() {expect(aa.^)}');
     await assertOpType(
@@ -78,7 +78,7 @@
         functionBody: true);
   }
 
-  test_ArgumentList_resolved() async {
+  Future<void> test_ArgumentList_resolved() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('void main() {int.parse(^)}');
     await assertOpType(
@@ -88,7 +88,7 @@
         functionBody: true);
   }
 
-  test_AsIdentifier() async {
+  Future<void> test_AsIdentifier() async {
     addTestSource('class A {var asdf; foo() {as^}');
     await assertOpType(
         constructors: true,
@@ -98,7 +98,7 @@
         methodBody: true);
   }
 
-  test_Assert() async {
+  Future<void> test_Assert() async {
     addTestSource('main() {assert(^)}');
     await assertOpType(
         constructors: true,
@@ -107,12 +107,12 @@
         functionBody: true);
   }
 
-  test_AssertInitializer() async {
+  Future<void> test_AssertInitializer() async {
     addTestSource('class C { C() : assert(^); }');
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  test_AssignmentExpression_RHS() async {
+  Future<void> test_AssignmentExpression_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('class A {} main() {int a; int b = ^}');
@@ -123,7 +123,7 @@
         functionBody: true);
   }
 
-  test_AssignmentExpression_type() async {
+  Future<void> test_AssignmentExpression_type() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -143,7 +143,7 @@
         functionBody: true);
   }
 
-  test_AssignmentExpression_type_newline() async {
+  Future<void> test_AssignmentExpression_type_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -162,7 +162,7 @@
         functionBody: true);
   }
 
-  test_AssignmentExpression_type_partial() async {
+  Future<void> test_AssignmentExpression_type_partial() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -182,7 +182,7 @@
         functionBody: true);
   }
 
-  test_AssignmentExpression_type_partial_newline() async {
+  Future<void> test_AssignmentExpression_type_partial_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -201,7 +201,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression() async {
+  Future<void> test_AwaitExpression() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
     addTestSource('main() async {A a; await ^}');
     await assertOpType(
@@ -211,7 +211,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression2() async {
+  Future<void> test_AwaitExpression2() async {
     addTestSource('main() async {A a; await c^ await}');
     await assertOpType(
         constructors: true,
@@ -220,7 +220,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression3() async {
+  Future<void> test_AwaitExpression3() async {
     addTestSource('main() async {A a; await ^ await foo;}');
     await assertOpType(
         constructors: true,
@@ -229,7 +229,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression4() async {
+  Future<void> test_AwaitExpression4() async {
     addTestSource('main() async {A a; await ^ await bar();}');
     await assertOpType(
         constructors: true,
@@ -238,7 +238,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression_assignment() async {
+  Future<void> test_AwaitExpression_assignment() async {
     addTestSource('main() async {A a; int x = await ^}');
     await assertOpType(
         constructors: true,
@@ -247,7 +247,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression_assignment2() async {
+  Future<void> test_AwaitExpression_assignment2() async {
     addTestSource('main() async {A a; int x = await ^ await foo;}');
     await assertOpType(
         constructors: true,
@@ -256,7 +256,7 @@
         functionBody: true);
   }
 
-  test_AwaitExpression_assignment3() async {
+  Future<void> test_AwaitExpression_assignment3() async {
     addTestSource('main() async {A a; int x = await v^ int y = await foo;}');
     await assertOpType(
         constructors: true,
@@ -265,7 +265,7 @@
         functionBody: true);
   }
 
-  test_BinaryExpression_LHS() async {
+  Future<void> test_BinaryExpression_LHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = ^ + 2;}');
@@ -276,7 +276,7 @@
         functionBody: true);
   }
 
-  test_BinaryExpression_RHS() async {
+  Future<void> test_BinaryExpression_RHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = 2 + ^;}');
@@ -287,7 +287,7 @@
         functionBody: true);
   }
 
-  test_BinaryExpression_RHS2() async {
+  Future<void> test_BinaryExpression_RHS2() async {
     // SimpleIdentifier  BinaryExpression
     addTestSource('main() {if (c < ^)}');
     await assertOpType(
@@ -297,7 +297,7 @@
         functionBody: true);
   }
 
-  test_Block() async {
+  Future<void> test_Block() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('''
       class X {
@@ -316,7 +316,7 @@
         methodBody: true);
   }
 
-  test_Block_catch_2a() async {
+  Future<void> test_Block_catch_2a() async {
     // '}'  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} catch () {} ^}');
     await assertOpType(
@@ -327,7 +327,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_2b() async {
+  Future<void> test_Block_catch_2b() async {
     // [ExpressionStatement 'c']  Block  BlockFunctionBody
     addTestSource('main() {try {} catch () {} c^}');
     await assertOpType(
@@ -338,7 +338,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_2c() async {
+  Future<void> test_Block_catch_2c() async {
     // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} catch () {} ^;}');
     await assertOpType(
@@ -349,7 +349,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_2d() async {
+  Future<void> test_Block_catch_2d() async {
     // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
     addTestSource('main() {try {} catch () {} ^ Foo foo;}');
     await assertOpType(
@@ -360,7 +360,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_3a() async {
+  Future<void> test_Block_catch_3a() async {
     // '}'  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} finally {} ^}');
     await assertOpType(
@@ -371,7 +371,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_3b() async {
+  Future<void> test_Block_catch_3b() async {
     // [ExpressionStatement 'c']  Block  BlockFunctionBody
     addTestSource('main() {try {} finally {} c^}');
     await assertOpType(
@@ -382,7 +382,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_3c() async {
+  Future<void> test_Block_catch_3c() async {
     // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} finally {} ^;}');
     await assertOpType(
@@ -393,7 +393,7 @@
         functionBody: true);
   }
 
-  test_Block_catch_3d() async {
+  Future<void> test_Block_catch_3d() async {
     // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
     addTestSource('main() {try {} finally {} ^ Foo foo;}');
     await assertOpType(
@@ -404,7 +404,7 @@
         functionBody: true);
   }
 
-  test_Block_empty() async {
+  Future<void> test_Block_empty() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     addTestSource('class A extends E implements I with M {a() {^}}');
     await assertOpType(
@@ -415,7 +415,7 @@
         methodBody: true);
   }
 
-  test_Block_identifier_partial() async {
+  Future<void> test_Block_identifier_partial() async {
     addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
     await assertOpType(
         constructors: true,
@@ -425,7 +425,7 @@
         methodBody: true);
   }
 
-  test_Block_in_constructor() async {
+  Future<void> test_Block_in_constructor() async {
     addTestSource('class A {A() {^}}');
     await assertOpType(
         constructors: true,
@@ -435,7 +435,7 @@
         voidReturn: true);
   }
 
-  test_Block_in_function() async {
+  Future<void> test_Block_in_function() async {
     addTestSource('foo() {^}');
     await assertOpType(
         constructors: true,
@@ -445,7 +445,7 @@
         voidReturn: true);
   }
 
-  test_Block_in_method() async {
+  Future<void> test_Block_in_method() async {
     addTestSource('class A {foo() {^}}');
     await assertOpType(
         constructors: true,
@@ -455,7 +455,7 @@
         voidReturn: true);
   }
 
-  test_Block_keyword() async {
+  Future<void> test_Block_keyword() async {
     addTestSource('class C { static C get instance => null; } main() {C.in^}');
     await assertOpType(
         constructors: true,
@@ -466,7 +466,7 @@
         functionBody: true);
   }
 
-  test_Block_static() async {
+  Future<void> test_Block_static() async {
     addTestSource('class A {static foo() {^}}');
     await assertOpType(
         constructors: true,
@@ -477,7 +477,7 @@
         voidReturn: true);
   }
 
-  test_CascadeExpression_selector1() async {
+  Future<void> test_CascadeExpression_selector1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addTestSource('''
       // looks like a cascade to the parser
@@ -492,7 +492,7 @@
         functionBody: true);
   }
 
-  test_CascadeExpression_selector2() async {
+  Future<void> test_CascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
     addTestSource('main() {A a; a..^z}');
     await assertOpType(
@@ -503,7 +503,7 @@
         functionBody: true);
   }
 
-  test_CascadeExpression_selector2_withTrailingReturn() async {
+  Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addTestSource('main() {A a; a..^ return}');
     await assertOpType(
@@ -514,7 +514,7 @@
         functionBody: true);
   }
 
-  test_CascadeExpression_target() async {
+  Future<void> test_CascadeExpression_target() async {
     // SimpleIdentifier  CascadeExpression  ExpressionStatement
     addTestSource('main() {A a; a^..b}');
     await assertOpType(
@@ -525,7 +525,7 @@
         functionBody: true);
   }
 
-  test_CatchClause_typed() async {
+  Future<void> test_CatchClause_typed() async {
     // Block  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
     await assertOpType(
@@ -536,7 +536,7 @@
         methodBody: true);
   }
 
-  test_CatchClause_untyped() async {
+  Future<void> test_CatchClause_untyped() async {
     // Block  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
     await assertOpType(
@@ -547,7 +547,7 @@
         methodBody: true);
   }
 
-  test_CommentReference() async {
+  Future<void> test_CommentReference() async {
     // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
     addTestSource('class A {/** [^] */ mth() {}');
     await assertOpType(
@@ -558,7 +558,7 @@
         kind: CompletionSuggestionKind.IDENTIFIER);
   }
 
-  test_ConditionalExpression_elseExpression() async {
+  Future<void> test_ConditionalExpression_elseExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T1 : T^}}');
     await assertOpType(
@@ -568,7 +568,7 @@
         methodBody: true);
   }
 
-  test_ConditionalExpression_elseExpression_empty() async {
+  Future<void> test_ConditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T1 : ^}}');
     await assertOpType(
@@ -578,7 +578,7 @@
         methodBody: true);
   }
 
-  test_ConditionalExpression_partial_thenExpression() async {
+  Future<void> test_ConditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T^}}');
     await assertOpType(
@@ -588,7 +588,7 @@
         methodBody: true);
   }
 
-  test_ConditionalExpression_partial_thenExpression_empty() async {
+  Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? ^}}');
     await assertOpType(
@@ -598,7 +598,7 @@
         methodBody: true);
   }
 
-  test_ConditionalExpression_thenExpression() async {
+  Future<void> test_ConditionalExpression_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addTestSource('class C {foo(){var f; {var x;} return a ? T^ : c}}');
     await assertOpType(
@@ -608,7 +608,7 @@
         methodBody: true);
   }
 
-  test_ConstructorFieldInitializer_name() async {
+  Future<void> test_ConstructorFieldInitializer_name() async {
     addTestSource(r'''
 class C {
   final int foo;
@@ -619,7 +619,7 @@
     await assertOpType();
   }
 
-  test_ConstructorFieldInitializer_value() async {
+  Future<void> test_ConstructorFieldInitializer_value() async {
     addTestSource(r'''
 class C {
   final int foo;
@@ -634,7 +634,7 @@
     );
   }
 
-  test_DefaultFormalParameter_named_expression() async {
+  Future<void> test_DefaultFormalParameter_named_expression() async {
     // DefaultFormalParameter FormalParameterList MethodDeclaration
     addTestSource('class A {a(blat: ^) { }}');
     await assertOpType(
@@ -644,7 +644,7 @@
     );
   }
 
-  test_DoStatement() async {
+  Future<void> test_DoStatement() async {
     // SimpleIdentifier  DoStatement  Block
     addTestSource('main() {do{} while(^x);}');
     await assertOpType(
@@ -654,7 +654,7 @@
         functionBody: true);
   }
 
-  test_ExpressionFunctionBody() async {
+  Future<void> test_ExpressionFunctionBody() async {
     // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
     addTestSource('m(){[1].forEach((x)=>^x);}');
     await assertOpType(
@@ -664,7 +664,7 @@
         functionBody: true);
   }
 
-  test_ExpressionStatement() async {
+  Future<void> test_ExpressionStatement() async {
     // ExpressionStatement  Block  BlockFunctionBody
     addTestSource('n(){f(3);^}');
     await assertOpType(
@@ -675,7 +675,7 @@
         functionBody: true);
   }
 
-  test_ForEachStatement() async {
+  Future<void> test_ForEachStatement() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main() {for(z in ^zs) {}}');
     await assertOpType(
@@ -685,7 +685,7 @@
         functionBody: true);
   }
 
-  test_ForEachStatement_body_typed() async {
+  Future<void> test_ForEachStatement_body_typed() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (int foo in bar) {^}}');
     await assertOpType(
@@ -696,7 +696,7 @@
         functionBody: true);
   }
 
-  test_ForEachStatement_body_untyped() async {
+  Future<void> test_ForEachStatement_body_untyped() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (foo in bar) {^}}');
     await assertOpType(
@@ -707,7 +707,7 @@
         functionBody: true);
   }
 
-  test_ForEachStatement_iterable() async {
+  Future<void> test_ForEachStatement_iterable() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (int foo in ^) {}}');
     await assertOpType(
@@ -717,7 +717,7 @@
         functionBody: true);
   }
 
-  test_ForElement_body() async {
+  Future<void> test_ForElement_body() async {
     addTestSource('main(args) {[for (var foo in [0]) ^];}');
     await assertOpType(
         constructors: true,
@@ -726,7 +726,7 @@
         functionBody: true);
   }
 
-  test_ForElement_forEachParts_iterable() async {
+  Future<void> test_ForElement_forEachParts_iterable() async {
     addTestSource('main(args) {[for (var foo in ^) foo];}');
     await assertOpType(
         constructors: true,
@@ -735,12 +735,12 @@
         functionBody: true);
   }
 
-  test_ForElement_forEachParts_type() async {
+  Future<void> test_ForElement_forEachParts_type() async {
     addTestSource('main(args) {[for (i^ foo in [0]) foo];}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_FormalParameter_partialType() async {
+  Future<void> test_FormalParameter_partialType() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.^ f) { }}');
     await assertOpType(
@@ -751,7 +751,7 @@
     );
   }
 
-  test_FormalParameter_partialType2() async {
+  Future<void> test_FormalParameter_partialType2() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.z^ f) { }}');
     await assertOpType(
@@ -762,7 +762,7 @@
     );
   }
 
-  test_FormalParameter_partialType3() async {
+  Future<void> test_FormalParameter_partialType3() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(b.^) { }}');
     await assertOpType(
@@ -773,7 +773,7 @@
     );
   }
 
-  test_ForStatement_condition() async {
+  Future<void> test_ForStatement_condition() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; i^)}');
     await assertOpType(
@@ -783,7 +783,7 @@
         functionBody: true);
   }
 
-  test_ForStatement_updaters() async {
+  Future<void> test_ForStatement_updaters() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; i^)}');
     // TODO (danrubel) may want to exclude methods/functions with void return
@@ -795,7 +795,7 @@
         functionBody: true);
   }
 
-  test_ForStatement_updaters_prefix_expression() async {
+  Future<void> test_ForStatement_updaters_prefix_expression() async {
     // SimpleIdentifier  PrefixExpression  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; ++i^)}');
     await assertOpType(
@@ -805,7 +805,7 @@
         functionBody: true);
   }
 
-  test_IfElement_condition() async {
+  Future<void> test_IfElement_condition() async {
     addTestSource('''
 main() {
   [if (^)];
@@ -818,7 +818,7 @@
         functionBody: true);
   }
 
-  test_IfElement_else() async {
+  Future<void> test_IfElement_else() async {
     addTestSource('''
 main() {
   [if (true) 0 else ^];
@@ -832,7 +832,7 @@
         voidReturn: true);
   }
 
-  test_IfElement_then() async {
+  Future<void> test_IfElement_then() async {
     addTestSource('''
 main() {
   [if (true) ^];
@@ -846,7 +846,7 @@
         voidReturn: true);
   }
 
-  test_IfStatement() async {
+  Future<void> test_IfStatement() async {
     // EmptyStatement  IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (true) ^}');
     await assertOpType(
@@ -857,7 +857,7 @@
         functionBody: true);
   }
 
-  test_IfStatement_condition() async {
+  Future<void> test_IfStatement_condition() async {
     // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (^)}');
     await assertOpType(
@@ -867,7 +867,7 @@
         functionBody: true);
   }
 
-  test_IfStatement_empty() async {
+  Future<void> test_IfStatement_empty() async {
     // SimpleIdentifier  PrefixIdentifier  IfStatement
     addTestSource('class A {foo() {A a; if (^) something}}');
     await assertOpType(
@@ -877,7 +877,7 @@
         methodBody: true);
   }
 
-  test_IfStatement_invocation() async {
+  Future<void> test_IfStatement_invocation() async {
     // SimpleIdentifier  PrefixIdentifier  IfStatement
     addTestSource('main() {var a; if (a.^) something}');
     await assertOpType(
@@ -888,7 +888,7 @@
         functionBody: true);
   }
 
-  test_IndexExpression() async {
+  Future<void> test_IndexExpression() async {
     addTestSource('class C {foo(){var f; {var x;} f[^]}}');
     await assertOpType(
         constructors: true,
@@ -897,7 +897,7 @@
         methodBody: true);
   }
 
-  test_IndexExpression2() async {
+  Future<void> test_IndexExpression2() async {
     addTestSource('class C {foo(){var f; {var x;} f[T^]}}');
     await assertOpType(
         constructors: true,
@@ -906,7 +906,7 @@
         methodBody: true);
   }
 
-  test_InstanceCreationExpression_keyword() async {
+  Future<void> test_InstanceCreationExpression_keyword() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     addTestSource('class C {foo(){var f; {var x;} new^ }}');
     await assertOpType(
@@ -917,7 +917,7 @@
         methodBody: true);
   }
 
-  test_InstanceCreationExpression_keyword2() async {
+  Future<void> test_InstanceCreationExpression_keyword2() async {
     // InstanceCreationExpression  ExpressionStatement  Block
     addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
     await assertOpType(
@@ -928,14 +928,14 @@
         methodBody: true);
   }
 
-  test_InterpolationExpression() async {
+  Future<void> test_InterpolationExpression() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addTestSource('main() {String name; print("hello \$^");}');
     await assertOpType(
         constructors: true, returnValue: true, functionBody: true);
   }
 
-  test_InterpolationExpression_block() async {
+  Future<void> test_InterpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addTestSource('main() {String name; print("hello \${n^}");}');
     await assertOpType(
@@ -945,7 +945,7 @@
         functionBody: true);
   }
 
-  test_InterpolationExpression_prefix_selector() async {
+  Future<void> test_InterpolationExpression_prefix_selector() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${name.^}");}');
     await assertOpType(
@@ -956,7 +956,7 @@
         functionBody: true);
   }
 
-  test_InterpolationExpression_prefix_target() async {
+  Future<void> test_InterpolationExpression_prefix_target() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${nam^e.length}");}');
     await assertOpType(
@@ -966,7 +966,7 @@
         functionBody: true);
   }
 
-  test_IsExpression_target() async {
+  Future<void> test_IsExpression_target() async {
     // IfStatement  Block  BlockFunctionBody
     addTestSource('main(){var a; if (^ is A)}');
     await assertOpType(
@@ -976,7 +976,7 @@
         functionBody: true);
   }
 
-  test_Literal_list() async {
+  Future<void> test_Literal_list() async {
     // ']'  ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([^]);}');
     await assertOpType(
@@ -986,7 +986,7 @@
         functionBody: true);
   }
 
-  test_Literal_list2() async {
+  Future<void> test_Literal_list2() async {
     // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([S^]);}');
     await assertOpType(
@@ -996,25 +996,25 @@
         functionBody: true);
   }
 
-  test_MapLiteralEntry() async {
+  Future<void> test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {^');
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  test_MapLiteralEntry1() async {
+  Future<void> test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {T^');
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  test_MapLiteralEntry2() async {
+  Future<void> test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
     addTestSource('foo = {7:T^};');
     await assertOpType(constructors: true, returnValue: true, typeNames: true);
   }
 
-  test_MethodInvocation_no_semicolon() async {
+  Future<void> test_MethodInvocation_no_semicolon() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
       class A implements I {
@@ -1030,7 +1030,7 @@
         methodBody: true);
   }
 
-  test_PostfixExpression() async {
+  Future<void> test_PostfixExpression() async {
     // SimpleIdentifier  PostfixExpression  ForStatement
     addTestSource('int x = 0; main() {ax+^+;}');
     await assertOpType(
@@ -1040,7 +1040,7 @@
         functionBody: true);
   }
 
-  test_PrefixedIdentifier_class_const() async {
+  Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
     addTestSource('main() {A.^}');
     await assertOpType(
@@ -1052,7 +1052,7 @@
         functionBody: true);
   }
 
-  test_PrefixedIdentifier_class_imported() async {
+  Future<void> test_PrefixedIdentifier_class_imported() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('main() {A a; a.^}');
     await assertOpType(
@@ -1064,7 +1064,7 @@
         functionBody: true);
   }
 
-  test_PrefixedIdentifier_prefix() async {
+  Future<void> test_PrefixedIdentifier_prefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('class X {foo(){A^.bar}}');
     await assertOpType(
@@ -1075,7 +1075,7 @@
         methodBody: true);
   }
 
-  test_PropertyAccess_expression() async {
+  Future<void> test_PropertyAccess_expression() async {
     // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
     addTestSource('class A {a() {"hello".to^String().length}}');
     await assertOpType(
@@ -1087,7 +1087,7 @@
         methodBody: true);
   }
 
-  test_PropertyAccess_selector() async {
+  Future<void> test_PropertyAccess_selector() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
     addTestSource('class A {a() {"hello".length.^}}');
     await assertOpType(
@@ -1099,7 +1099,7 @@
         methodBody: true);
   }
 
-  test_ReturnStatement() async {
+  Future<void> test_ReturnStatement() async {
     // ReturnStatement  Block
     addTestSource('f() { var vvv = 42; return ^ }');
     await assertOpType(
@@ -1109,7 +1109,7 @@
         functionBody: true);
   }
 
-  test_SpreadElement() async {
+  Future<void> test_SpreadElement() async {
     addTestSource(r'''
 main() {
   [...^];
@@ -1122,7 +1122,7 @@
         functionBody: true);
   }
 
-  test_SwitchCase_between() async {
+  Future<void> test_SwitchCase_between() async {
     // SwitchCase  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1: ^ case 2: return}}');
     await assertOpType(
@@ -1133,7 +1133,7 @@
         functionBody: true);
   }
 
-  test_SwitchCase_expression1() async {
+  Future<void> test_SwitchCase_expression1() async {
     // SimpleIdentifier  SwitchCase  SwitchStatement
     addTestSource('''m() {switch (x) {case ^D: return;}}''');
     await assertOpType(
@@ -1143,7 +1143,7 @@
         functionBody: true);
   }
 
-  test_SwitchCase_expression2() async {
+  Future<void> test_SwitchCase_expression2() async {
     // SimpleIdentifier  SwitchCase  SwitchStatement
     addTestSource('''m() {switch (x) {case ^}}''');
     await assertOpType(
@@ -1153,7 +1153,7 @@
         functionBody: true);
   }
 
-  test_SwitchDefault_between() async {
+  Future<void> test_SwitchDefault_between() async {
     // SwitchDefault  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1: ^ default: return;}}');
     await assertOpType(
@@ -1164,7 +1164,7 @@
         functionBody: true);
   }
 
-  test_SwitchStatement_body_end() async {
+  Future<void> test_SwitchStatement_body_end() async {
     // Token('}')  SwitchStatement  Block
     addTestSource('main() {switch(k) {case 1:^}}');
     await assertOpType(
@@ -1175,7 +1175,7 @@
         functionBody: true);
   }
 
-  test_SwitchStatement_body_end2() async {
+  Future<void> test_SwitchStatement_body_end2() async {
     addTestSource('main() {switch(k) {case 1:as^}}');
     await assertOpType(
         constructors: true,
@@ -1185,7 +1185,7 @@
         functionBody: true);
   }
 
-  test_SwitchStatement_expression1() async {
+  Future<void> test_SwitchStatement_expression1() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(^k) {case 1:{}}}');
     await assertOpType(
@@ -1195,7 +1195,7 @@
         functionBody: true);
   }
 
-  test_SwitchStatement_expression2() async {
+  Future<void> test_SwitchStatement_expression2() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(k^) {case 1:{}}}');
     await assertOpType(
@@ -1206,7 +1206,7 @@
   }
 
 //
-  test_SwitchStatement_expression_empty() async {
+  Future<void> test_SwitchStatement_expression_empty() async {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(^) {case 1:{}}}');
     await assertOpType(
@@ -1216,7 +1216,7 @@
         functionBody: true);
   }
 
-  test_ThisExpression_block() async {
+  Future<void> test_ThisExpression_block() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
       class A implements I {
@@ -1232,7 +1232,7 @@
         methodBody: true);
   }
 
-  test_ThisExpression_constructor() async {
+  Future<void> test_ThisExpression_constructor() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestSource('''
       class A implements I {
@@ -1246,7 +1246,7 @@
         constructorBody: true);
   }
 
-  test_ThrowExpression() async {
+  Future<void> test_ThrowExpression() async {
     // SimpleIdentifier  ThrowExpression  ExpressionStatement
     addTestSource('main() {throw ^;}');
     await assertOpType(
@@ -1256,7 +1256,7 @@
         functionBody: true);
   }
 
-  test_VariableDeclarationStatement_afterSemicolon() async {
+  Future<void> test_VariableDeclarationStatement_afterSemicolon() async {
     // VariableDeclarationStatement  Block  BlockFunctionBody
     addTestSource('class A {var a; x() {var b;^}}');
     await assertOpType(
@@ -1267,7 +1267,7 @@
         methodBody: true);
   }
 
-  test_VariableDeclarationStatement_RHS() async {
+  Future<void> test_VariableDeclarationStatement_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
     addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
@@ -1278,7 +1278,7 @@
         methodBody: true);
   }
 
-  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+  Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
     // VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
     addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
@@ -1289,7 +1289,7 @@
         methodBody: true);
   }
 
-  test_WhileStatement() async {
+  Future<void> test_WhileStatement() async {
     // SimpleIdentifier  WhileStatement  Block
     addTestSource('mth() { while (b^) {} }}');
     await assertOpType(
@@ -1300,7 +1300,7 @@
   }
 
   @failingTest
-  test_WithClause() async {
+  Future<void> test_WithClause() async {
     // WithClause  ClassDeclaration
     addTestSource('class x extends Object with ^\n{}');
     await assertOpType(constructors: true, typeNames: true);
@@ -1309,7 +1309,7 @@
 
 @reflectiveTest
 class OpTypeTest extends OpTypeTestCommon {
-  test_ArgumentList_constructor_named_resolved_1_0() async {
+  Future<void> test_ArgumentList_constructor_named_resolved_1_0() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
     addTestSource(
       'main() { new A.b(^); }'
@@ -1318,7 +1318,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_constructor_named_resolved_1_1() async {
+  Future<void> test_ArgumentList_constructor_named_resolved_1_1() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addTestSource(
       'main() { new A.b(o^); }'
@@ -1327,7 +1327,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_constructor_resolved_1_0() async {
+  Future<void> test_ArgumentList_constructor_resolved_1_0() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
     addTestSource(
       'main() { new A(^); }'
@@ -1336,7 +1336,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_constructor_resolved_1_1() async {
+  Future<void> test_ArgumentList_constructor_resolved_1_1() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addTestSource(
       'main() { new A(o^); }'
@@ -1345,7 +1345,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_factory_named_resolved_1_0() async {
+  Future<void> test_ArgumentList_factory_named_resolved_1_0() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
     addTestSource(
       'main() { new A.b(^); }'
@@ -1354,7 +1354,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_factory_named_resolved_1_1() async {
+  Future<void> test_ArgumentList_factory_named_resolved_1_1() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addTestSource(
       'main() { new A.b(o^); }'
@@ -1363,7 +1363,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_factory_resolved_1_0() async {
+  Future<void> test_ArgumentList_factory_resolved_1_0() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement Block
     addTestSource(
       'main() { new A(^); }'
@@ -1372,7 +1372,7 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_factory_resolved_1_1() async {
+  Future<void> test_ArgumentList_factory_resolved_1_1() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addTestSource(
       'main() { new A(o^); }'
@@ -1381,175 +1381,175 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_method_resolved_1_0() async {
+  Future<void> test_ArgumentList_method_resolved_1_0() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('main() { foo(^);} foo({one, two}) {}');
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_method_resolved_1_1() async {
+  Future<void> test_ArgumentList_method_resolved_1_1() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('main() { foo(o^);} foo({one, two}) {}');
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_ArgumentList_resolved_2_0() async {
+  Future<void> test_ArgumentList_resolved_2_0() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('void main() {int.parse("16", ^)}');
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_AsExpression() async {
+  Future<void> test_AsExpression() async {
     // SimpleIdentifier  TypeName  AsExpression
     addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
     await assertOpType(typeNames: true, methodBody: true);
   }
 
-  test_AsIdentifier2() async {
+  Future<void> test_AsIdentifier2() async {
     addTestSource('class A {var asdf; foo() {A as^}');
     await assertOpType(methodBody: true);
   }
 
-  test_AssignmentExpression_name() async {
+  Future<void> test_AssignmentExpression_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('class A {} main() {int a; int ^b = 1;}');
     await assertOpType(varNames: true, functionBody: true);
   }
 
-  test_Block_catch_1a() async {
+  Future<void> test_Block_catch_1a() async {
     // '}'  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} ^}');
     // Only return 'on', 'catch', and 'finally' keywords
     await assertOpType(functionBody: true);
   }
 
-  test_Block_catch_1b() async {
+  Future<void> test_Block_catch_1b() async {
     // [ExpressionStatement 'c']  Block  BlockFunctionBody
     addTestSource('main() {try {} c^}');
     // Only return 'on', 'catch', and 'finally' keywords
     await assertOpType(functionBody: true);
   }
 
-  test_Block_catch_1c() async {
+  Future<void> test_Block_catch_1c() async {
     // [EmptyStatement]  Block  BlockFunctionBody  FunctionExpression
     addTestSource('main() {try {} ^;}');
     // Only return 'on', 'catch', and 'finally' keywords
     await assertOpType(functionBody: true);
   }
 
-  test_Block_catch_1d() async {
+  Future<void> test_Block_catch_1d() async {
     // [VariableDeclarationStatement 'Foo foo']  Block  BlockFunctionBody
     addTestSource('main() {try {} ^ Foo foo;}');
     // Only return 'on', 'catch', and 'finally' keywords
     await assertOpType(functionBody: true);
   }
 
-  test_Block_final() async {
+  Future<void> test_Block_final() async {
     addTestSource('main() {final ^}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Block_final2() async {
+  Future<void> test_Block_final2() async {
     addTestSource('main() {final S^ v;}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Block_final3() async {
+  Future<void> test_Block_final3() async {
     addTestSource('main() {final ^ v;}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Block_final_final() async {
+  Future<void> test_Block_final_final() async {
     addTestSource('main() {final ^ final S x;}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Block_final_final2() async {
+  Future<void> test_Block_final_final2() async {
     addTestSource('main() {final S^ final S x;}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Break_after_label() async {
+  Future<void> test_Break_after_label() async {
     addTestSource('main() { foo: while (true) { break foo ^ ; } }');
     await assertOpType(/* No valid completions */ functionBody: true);
   }
 
-  test_Break_before_label() async {
+  Future<void> test_Break_before_label() async {
     addTestSource('main() { foo: while (true) { break ^ foo; } }');
     await assertOpType(statementLabel: true, functionBody: true);
   }
 
-  test_Break_no_label() async {
+  Future<void> test_Break_no_label() async {
     addTestSource('main() { foo: while (true) { break ^; } }');
     await assertOpType(statementLabel: true, functionBody: true);
   }
 
-  test_catch_4a1() async {
+  Future<void> test_catch_4a1() async {
     addTestSource('main() {try {} ^ on SomeException {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_4a2() async {
+  Future<void> test_catch_4a2() async {
     addTestSource('main() {try {} c^ on SomeException {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_4b1() async {
+  Future<void> test_catch_4b1() async {
     addTestSource('main() {try {} ^ catch (e) {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_4b2() async {
+  Future<void> test_catch_4b2() async {
     addTestSource('main() {try {} c^ catch (e) {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_4c1() async {
+  Future<void> test_catch_4c1() async {
     addTestSource('main() {try {} ^ finally {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_4c2() async {
+  Future<void> test_catch_4c2() async {
     addTestSource('main() {try {} c^ finally {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_catch_5a() async {
+  Future<void> test_catch_5a() async {
     addTestSource('main() {try {} on ^ finally {}}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_catch_5b() async {
+  Future<void> test_catch_5b() async {
     addTestSource('main() {try {} on E^ finally {}}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_CatchClause_onType() async {
+  Future<void> test_CatchClause_onType() async {
     // TypeName  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^ {}}}');
     await assertOpType(typeNames: true, methodBody: true);
   }
 
-  test_CatchClause_onType_noBrackets() async {
+  Future<void> test_CatchClause_onType_noBrackets() async {
     // TypeName  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^}}');
     await assertOpType(typeNames: true, methodBody: true);
   }
 
-  test_ClassDeclaration_body() async {
+  Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('@deprecated class A {^}');
     await assertOpType(typeNames: true);
   }
 
-  test_ClassDeclaration_body2() async {
+  Future<void> test_ClassDeclaration_body2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('@deprecated class A {^mth() {}}');
     await assertOpType(typeNames: true);
   }
 
-  test_Combinator_hide() async {
+  Future<void> test_Combinator_hide() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
     addTestSource('''
       import "/testAB.dart" hide ^;
@@ -1557,7 +1557,7 @@
     await assertOpType();
   }
 
-  test_Combinator_show() async {
+  Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
     addTestSource('''
       import "/testAB.dart" show ^;
@@ -1566,21 +1566,21 @@
     await assertOpType();
   }
 
-  test_ConstructorName() async {
+  Future<void> test_ConstructorName() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('main() {new X.^}');
     await assertOpType(constructors: true, prefixed: true, functionBody: true);
   }
 
-  test_ConstructorName_name_resolved() async {
+  Future<void> test_ConstructorName_name_resolved() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('main() {new Str^ing.fromCharCodes([]);}');
     await assertOpType(constructors: true, functionBody: true);
   }
 
-  test_ConstructorName_nameAndPrefix_resolved() async {
+  Future<void> test_ConstructorName_nameAndPrefix_resolved() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
@@ -1590,158 +1590,159 @@
     await assertOpType(constructors: true, prefixed: true, functionBody: true);
   }
 
-  test_ConstructorName_resolved() async {
+  Future<void> test_ConstructorName_resolved() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('main() {new String.fr^omCharCodes([]);}');
     await assertOpType(constructors: true, prefixed: true, functionBody: true);
   }
 
-  test_ConstructorName_unresolved() async {
+  Future<void> test_ConstructorName_unresolved() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('main() {new String.fr^omCharCodes([]);}');
     await assertOpType(constructors: true, prefixed: true, functionBody: true);
   }
 
-  test_Continue_after_label() async {
+  Future<void> test_Continue_after_label() async {
     addTestSource('main() { foo: while (true) { continue foo ^ ; } }');
     await assertOpType(/* No valid completions */ functionBody: true);
   }
 
-  test_Continue_before_label() async {
+  Future<void> test_Continue_before_label() async {
     addTestSource('main() { foo: while (true) { continue ^ foo; } }');
     await assertOpType(
         statementLabel: true, caseLabel: true, functionBody: true);
   }
 
-  test_Continue_no_label() async {
+  Future<void> test_Continue_no_label() async {
     addTestSource('main() { foo: while (true) { continue ^; } }');
     await assertOpType(
         statementLabel: true, caseLabel: true, functionBody: true);
   }
 
-  test_DoubleLiteral() async {
+  Future<void> test_DoubleLiteral() async {
     addTestSource('main() { print(1.2^); }');
     // TODO expected functionBody: true
     await assertOpType(functionBody: false);
   }
 
-  test_ExpressionStatement_name() async {
+  Future<void> test_ExpressionStatement_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class C {a() {C ^}}');
     await assertOpType(varNames: true, methodBody: true);
   }
 
-  test_ExpressionStatement_name_semicolon() async {
+  Future<void> test_ExpressionStatement_name_semicolon() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class C {a() {C ^;}}');
     await assertOpType(varNames: true, methodBody: true);
   }
 
-  test_ExpressionStatement_prefixed_name() async {
+  Future<void> test_ExpressionStatement_prefixed_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class C {a() {x.Y ^}}');
     await assertOpType(varNames: true, methodBody: true);
   }
 
-  test_ExpressionStatement_prefixed_name_semicolon() async {
+  Future<void> test_ExpressionStatement_prefixed_name_semicolon() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class C {a() {x.Y ^;}}');
     await assertOpType(varNames: true, methodBody: true);
   }
 
-  test_ExtendsClause() async {
+  Future<void> test_ExtendsClause() async {
     // ExtendsClause  ClassDeclaration
     addTestSource('class x extends ^\n{}');
     await assertOpType(typeNames: true);
   }
 
-  test_FieldDeclaration_name_typed() async {
+  Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
     addTestSource('class C {A ^}');
     await assertOpType(varNames: true);
   }
 
-  test_FieldDeclaration_name_var() async {
+  Future<void> test_FieldDeclaration_name_var() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
     addTestSource('class C {var ^}');
     await assertOpType();
   }
 
-  test_ForEachStatement_loopVariable() async {
+  Future<void> test_ForEachStatement_loopVariable() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (^ in args) {}}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_ForEachStatement_loopVariable_name() async {
+  Future<void> test_ForEachStatement_loopVariable_name() async {
     // DeclaredIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (String ^ in args) {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_ForEachStatement_loopVariable_name2() async {
+  Future<void> test_ForEachStatement_loopVariable_name2() async {
     // DeclaredIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (String f^ in args) {}}');
     await assertOpType(functionBody: true);
   }
 
-  test_ForEachStatement_loopVariable_type() async {
+  Future<void> test_ForEachStatement_loopVariable_type() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (^ foo in args) {}}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_ForEachStatement_loopVariable_type2() async {
+  Future<void> test_ForEachStatement_loopVariable_type2() async {
     // DeclaredIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (S^ foo in args) {}}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_FormalParameterList() async {
+  Future<void> test_FormalParameterList() async {
     // FormalParameterList MethodDeclaration
     addTestSource('class A {a(^) { }}');
     await assertOpType(typeNames: true);
   }
 
-  test_ForStatement_initializer() async {
+  Future<void> test_ForStatement_initializer() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {List a; for (^)}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_ForStatement_initializer_inKeyword() async {
+  Future<void> test_ForStatement_initializer_inKeyword() async {
     addTestSource('main() { for (var v i^) }');
     await assertOpType(functionBody: true);
   }
 
-  test_ForStatement_initializer_type() async {
+  Future<void> test_ForStatement_initializer_type() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {List a; for (i^ v = 0;)}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_ForStatement_initializer_variableNameEmpty_afterType() async {
+  Future<void>
+      test_ForStatement_initializer_variableNameEmpty_afterType() async {
     addTestSource('main() { for (String ^) }');
     await assertOpType(varNames: true, functionBody: true);
   }
 
-  test_FunctionDeclaration1() async {
+  Future<void> test_FunctionDeclaration1() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     addTestSource('const ^Fara();');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration2() async {
+  Future<void> test_FunctionDeclaration2() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     addTestSource('const F^ara();');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_inLineComment() async {
+  Future<void> test_FunctionDeclaration_inLineComment() async {
     // Comment  CompilationUnit
     addTestSource('''
       // normal comment ^
@@ -1749,7 +1750,7 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inLineComment2() async {
+  Future<void> test_FunctionDeclaration_inLineComment2() async {
     // Comment  CompilationUnit
     addTestSource('''
       // normal ^comment
@@ -1757,7 +1758,7 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inLineComment3() async {
+  Future<void> test_FunctionDeclaration_inLineComment3() async {
     // Comment  CompilationUnit
     addTestSource('''
       // normal comment ^
@@ -1766,7 +1767,7 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inLineComment4() async {
+  Future<void> test_FunctionDeclaration_inLineComment4() async {
     // Comment  CompilationUnit
     addTestSource('''
       // normal comment
@@ -1775,7 +1776,7 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inLineDocComment() async {
+  Future<void> test_FunctionDeclaration_inLineDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
     addTestSource('''
       /// some dartdoc ^
@@ -1783,7 +1784,7 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inLineDocComment2() async {
+  Future<void> test_FunctionDeclaration_inLineDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
     addTestSource('''
       /// some ^dartdoc
@@ -1791,37 +1792,37 @@
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inStarComment() async {
+  Future<void> test_FunctionDeclaration_inStarComment() async {
     // Comment  CompilationUnit
     addTestSource('/* ^ */ zoo(z) {} String name;');
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inStarComment2() async {
+  Future<void> test_FunctionDeclaration_inStarComment2() async {
     // Comment  CompilationUnit
     addTestSource('/*  *^/ zoo(z) {} String name;');
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inStarDocComment() async {
+  Future<void> test_FunctionDeclaration_inStarDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
     addTestSource('/** ^ */ zoo(z) { } String name; ');
     await assertOpType();
   }
 
-  test_FunctionDeclaration_inStarDocComment2() async {
+  Future<void> test_FunctionDeclaration_inStarDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
     addTestSource('/**  *^/ zoo(z) { } String name;');
     await assertOpType();
   }
 
-  test_FunctionDeclaration_returnType() async {
+  Future<void> test_FunctionDeclaration_returnType() async {
     // CompilationUnit
     addTestSource('^ zoo(z) { } String name;');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterLineComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineComment() async {
     // FunctionDeclaration  CompilationUnit
     addTestSource('''
       // normal comment
@@ -1829,7 +1830,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterLineComment2() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineComment2() async {
     // FunctionDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     addTestSource('''
@@ -1838,7 +1839,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterLineDocComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterLineDocComment() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     addTestSource('''
       /// some dartdoc
@@ -1846,7 +1847,8 @@
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterLineDocComment2() async {
+  Future<void>
+      test_FunctionDeclaration_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
     addTestSource('''
 /// some dartdoc
@@ -1854,55 +1856,56 @@
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterStarComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarComment() async {
     // CompilationUnit
     addTestSource('/* */ ^ zoo(z) { } String name;');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterStarComment2() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarComment2() async {
     // CompilationUnit
     addTestSource('/* */^ zoo(z) { } String name;');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterStarDocComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterStarDocComment() async {
     // FunctionDeclaration  CompilationUnit
     addTestSource('/** */ ^ zoo(z) { } String name;');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionDeclaration_returnType_afterStarDocComment2() async {
+  Future<void>
+      test_FunctionDeclaration_returnType_afterStarDocComment2() async {
     // FunctionDeclaration  CompilationUnit
     addTestSource('/** */^ zoo(z) { } String name;');
     await assertOpType(typeNames: true);
   }
 
-  test_FunctionExpression() async {
+  Future<void> test_FunctionExpression() async {
     // BlockFunctionBody  FunctionExpression  FunctionDeclaration
     addTestSource('main()^ { int b = 2; b++; b. }');
     await assertOpType();
   }
 
-  test_FunctionExpressionInvocation() async {
+  Future<void> test_FunctionExpressionInvocation() async {
     // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
     addTestSource('main() { ((x) => x + 7)^(2) }');
     await assertOpType(functionBody: true);
   }
 
-  test_FunctionTypeAlias() async {
+  Future<void> test_FunctionTypeAlias() async {
     // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
     addTestSource('typedef n^ ;');
     await assertOpType(typeNames: true);
   }
 
-  test_ImplementsClause() async {
+  Future<void> test_ImplementsClause() async {
     // ImplementsClause  ClassDeclaration
     addTestSource('class x implements ^\n{}');
     await assertOpType(typeNames: true);
   }
 
-  test_ImportDirective_dart() async {
+  Future<void> test_ImportDirective_dart() async {
     // SimpleStringLiteral  ImportDirective
     addTestSource('''
       import "dart^";
@@ -1910,61 +1913,61 @@
     await assertOpType();
   }
 
-  test_InstanceCreationExpression() async {
+  Future<void> test_InstanceCreationExpression() async {
     // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
     addTestSource('class C {foo(){var f; {var x;} new ^}}');
     await assertOpType(constructors: true, methodBody: true);
   }
 
-  test_InstanceCreationExpression_trailingStmt() async {
+  Future<void> test_InstanceCreationExpression_trailingStmt() async {
     // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
     addTestSource('class C {foo(){var f; {var x;} new ^ int x = 7;}}');
     await assertOpType(constructors: true, methodBody: true);
   }
 
-  test_IntegerLiteral_inArgumentList() async {
+  Future<void> test_IntegerLiteral_inArgumentList() async {
     // TODO expected functionBody: true
     addTestSource('main() { print(1^); }');
     await assertOpType(functionBody: false);
   }
 
-  test_IntegerLiteral_inListLiteral() async {
+  Future<void> test_IntegerLiteral_inListLiteral() async {
     // TODO expected functionBody: true
     addTestSource('main() { var items = [1^]; }');
     await assertOpType(functionBody: false);
   }
 
-  test_IsExpression() async {
+  Future<void> test_IsExpression() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('main() {var x; if (x is ^) { }}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_IsExpression_type_partial() async {
+  Future<void> test_IsExpression_type_partial() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('main(){var a; if (a is Obj^)}');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_Literal_string() async {
+  Future<void> test_Literal_string() async {
     // SimpleStringLiteral  ExpressionStatement  Block
     addTestSource('class A {a() {"hel^lo"}}');
     await assertOpType(methodBody: true);
   }
 
-  test_MethodDeclaration_inClass1() async {
+  Future<void> test_MethodDeclaration_inClass1() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const ^Fara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass2() async {
+  Future<void> test_MethodDeclaration_inClass2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration
     addTestSource('class Bar {const F^ara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_inLineComment() async {
+  Future<void> test_MethodDeclaration_inClass_inLineComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1973,7 +1976,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inLineComment2() async {
+  Future<void> test_MethodDeclaration_inClass_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1982,7 +1985,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inLineComment3() async {
+  Future<void> test_MethodDeclaration_inClass_inLineComment3() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -1992,7 +1995,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inLineDocComment() async {
+  Future<void> test_MethodDeclaration_inClass_inLineDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2001,7 +2004,7 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inLineDocComment2() async {
+  Future<void> test_MethodDeclaration_inClass_inLineDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2010,37 +2013,38 @@
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inStarComment() async {
+  Future<void> test_MethodDeclaration_inClass_inStarComment() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inStarComment2() async {
+  Future<void> test_MethodDeclaration_inClass_inStarComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inStarDocComment() async {
+  Future<void> test_MethodDeclaration_inClass_inStarDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_inStarDocComment2() async {
+  Future<void> test_MethodDeclaration_inClass_inStarDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
     await assertOpType();
   }
 
-  test_MethodDeclaration_inClass_returnType() async {
+  Future<void> test_MethodDeclaration_inClass_returnType() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterLineComment() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterLineComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2049,7 +2053,8 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterLineComment2() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterLineComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
     addTestSource('''
@@ -2059,7 +2064,8 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterLineDocComment() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterLineDocComment() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
       class C2 {
@@ -2068,7 +2074,8 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterLineDocComment2() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('''
 class C2 {
@@ -2077,61 +2084,65 @@
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterStarComment() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterStarComment() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterStarComment2() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterStarComment2() async {
     // ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterStarDocComment() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterStarDocComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_MethodDeclaration_inClass_returnType_afterStarDocComment2() async {
+  Future<void>
+      test_MethodDeclaration_inClass_returnType_afterStarDocComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inMixin1() async {
+  Future<void> test_methodDeclaration_inMixin1() async {
     // SimpleIdentifier  MethodDeclaration  MixinDeclaration
     addTestSource('mixin M {const ^Fara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inMixin2() async {
+  Future<void> test_methodDeclaration_inMixin2() async {
     // SimpleIdentifier  MethodDeclaration  MixinDeclaration
     addTestSource('mixin M {const F^ara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inMixin_returnType() async {
+  Future<void> test_methodDeclaration_inMixin_returnType() async {
     // MixinDeclaration  CompilationUnit
     addTestSource('mixin M {^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
   }
 
-  test_mixinDeclaration_body() async {
+  Future<void> test_mixinDeclaration_body() async {
     // MixinDeclaration  CompilationUnit
     addTestSource('mixin M {^}');
     await assertOpType(typeNames: true);
   }
 
-  test_mixinDeclaration_body2() async {
+  Future<void> test_mixinDeclaration_body2() async {
     // SimpleIdentifier  MethodDeclaration  MixinDeclaration
     addTestSource('mixin M {^mth() {}}');
     await assertOpType(typeNames: true);
   }
 
-  test_NamedExpression() async {
+  Future<void> test_NamedExpression() async {
     addTestSource('''
 main() { f(3, ^); }
 void f(int a, {int b}) {}
@@ -2139,121 +2150,121 @@
     await assertOpType(namedArgs: true, functionBody: true);
   }
 
-  test_OnClause() async {
+  Future<void> test_OnClause() async {
     // OnClause  MixinDeclaration
     addTestSource('mixin M on ^\n{}');
     await assertOpType(typeNames: true);
   }
 
-  test_PropertyAccess_noTarget() async {
+  Future<void> test_PropertyAccess_noTarget() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestSource('main() {.^}');
     await assertOpType(functionBody: true);
   }
 
-  test_PropertyAccess_noTarget2() async {
+  Future<void> test_PropertyAccess_noTarget2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpressions
     addTestSource('main() {.^.}');
     await assertOpType(functionBody: true);
   }
 
-  test_PropertyAccess_noTarget3() async {
+  Future<void> test_PropertyAccess_noTarget3() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpressions
     addTestSource('main() {..^}');
     await assertOpType(functionBody: true);
   }
 
-  test_SimpleFormalParameter_closure() async {
+  Future<void> test_SimpleFormalParameter_closure() async {
     // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
     addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_SimpleFormalParameter_name_typed() async {
+  Future<void> test_SimpleFormalParameter_name_typed() async {
     addTestSource('f(String ^, int b) {}');
     await assertOpType(typeNames: false, varNames: true);
   }
 
-  test_SimpleFormalParameter_name_typed_hasName() async {
+  Future<void> test_SimpleFormalParameter_name_typed_hasName() async {
     addTestSource('f(String n^, int b) {}');
     await assertOpType(typeNames: false, varNames: true);
   }
 
-  test_SimpleFormalParameter_name_typed_last() async {
+  Future<void> test_SimpleFormalParameter_name_typed_last() async {
     addTestSource('f(String ^) {}');
     await assertOpType(typeNames: false, varNames: true);
   }
 
-  test_SimpleFormalParameter_name_typed_last_hasName() async {
+  Future<void> test_SimpleFormalParameter_name_typed_last_hasName() async {
     addTestSource('f(String n^) {}');
     await assertOpType(typeNames: false, varNames: true);
   }
 
-  test_SimpleFormalParameter_type_named() async {
+  Future<void> test_SimpleFormalParameter_type_named() async {
     addTestSource('f(^ name) {}');
     await assertOpType(typeNames: true, varNames: false);
   }
 
-  test_SimpleFormalParameter_type_optionalNamed() async {
+  Future<void> test_SimpleFormalParameter_type_optionalNamed() async {
     // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
     addTestSource('m({Str^}) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_type_optionalPositional() async {
+  Future<void> test_SimpleFormalParameter_type_optionalPositional() async {
     // SimpleIdentifier  DefaultFormalParameter  FormalParameterList
     addTestSource('m([Str^]) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_type_withName() async {
+  Future<void> test_SimpleFormalParameter_type_withName() async {
     // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
     addTestSource('m(Str^ name) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_type_withoutName1() async {
+  Future<void> test_SimpleFormalParameter_type_withoutName1() async {
     // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
     addTestSource('m(Str^) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_type_withoutName2() async {
+  Future<void> test_SimpleFormalParameter_type_withoutName2() async {
     // FormalParameterList
     addTestSource('m(^) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_type_withoutName3() async {
+  Future<void> test_SimpleFormalParameter_type_withoutName3() async {
     // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
     addTestSource('m(int first, Str^) {}');
     await assertOpType(typeNames: true);
   }
 
-  test_SimpleFormalParameter_untyped() async {
+  Future<void> test_SimpleFormalParameter_untyped() async {
     addTestSource('main(final ^) {}');
     await assertOpType(typeNames: true, varNames: false);
   }
 
-  test_SwitchCase_before() async {
+  Future<void> test_SwitchCase_before() async {
     // SwitchCase  SwitchStatement  Block
     addTestSource('main() {switch(k) {^case 1:}}');
     await assertOpType(functionBody: true);
   }
 
-  test_SwitchDefault_before() async {
+  Future<void> test_SwitchDefault_before() async {
     // SwitchDefault  SwitchStatement  Block
     addTestSource('main() {switch(k) { ^ default: return;}}');
     await assertOpType(functionBody: true);
   }
 
-  test_SwitchStatement_body_empty() async {
+  Future<void> test_SwitchStatement_body_empty() async {
     // Token('}')  SwitchStatement  Block
     addTestSource('main() {switch(k) {^}}');
     await assertOpType(functionBody: true);
   }
 
-  test_ThisExpression_constructor_param() async {
+  Future<void> test_ThisExpression_constructor_param() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2262,7 +2273,7 @@
     await assertOpType(prefixed: true);
   }
 
-  test_ThisExpression_constructor_param2() async {
+  Future<void> test_ThisExpression_constructor_param2() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2271,7 +2282,7 @@
     await assertOpType(prefixed: true);
   }
 
-  test_ThisExpression_constructor_param3() async {
+  Future<void> test_ThisExpression_constructor_param3() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
       class A implements I {
@@ -2280,7 +2291,7 @@
     await assertOpType(prefixed: true);
   }
 
-  test_ThisExpression_constructor_param4() async {
+  Future<void> test_ThisExpression_constructor_param4() async {
     // FieldFormalParameter  FormalParameterList  ConstructorDeclaration
     addTestSource('''
       class A implements I {
@@ -2289,7 +2300,7 @@
     await assertOpType(typeNames: true);
   }
 
-  test_TopLevelVariableDeclaration_typed_name() async {
+  Future<void> test_TopLevelVariableDeclaration_typed_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     // _OpTypeAstVisitor.visitVariableDeclarationList is executed with this
@@ -2299,7 +2310,7 @@
     await assertOpType(varNames: true);
   }
 
-  test_TopLevelVariableDeclaration_typed_name_semicolon() async {
+  Future<void> test_TopLevelVariableDeclaration_typed_name_semicolon() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     // See comment in test_TopLevelVariableDeclaration_typed_name
@@ -2307,59 +2318,59 @@
     await assertOpType(varNames: true);
   }
 
-  test_TopLevelVariableDeclaration_untyped_name() async {
+  Future<void> test_TopLevelVariableDeclaration_untyped_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     addTestSource('class A {} var ^');
     await assertOpType();
   }
 
-  test_TypeArgumentList() async {
+  Future<void> test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
     addTestSource('main() { C<^> c; }');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_TypeArgumentList2() async {
+  Future<void> test_TypeArgumentList2() async {
     // TypeName  TypeArgumentList  TypeName
     addTestSource('main() { C<C^> c; }');
     await assertOpType(typeNames: true, functionBody: true);
   }
 
-  test_TypeParameter() async {
+  Future<void> test_TypeParameter() async {
     // SimpleIdentifier  TypeParameter  TypeParameterList
     addTestSource('class tezetst <String, ^List> {}');
     await assertOpType();
   }
 
-  test_TypeParameterList_empty() async {
+  Future<void> test_TypeParameterList_empty() async {
     // SimpleIdentifier  TypeParameter  TypeParameterList
     addTestSource('class tezetst <^> {}');
     await assertOpType();
   }
 
-  test_VariableDeclaration_name() async {
+  Future<void> test_VariableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {var ^}');
     await assertOpType(functionBody: true);
   }
 
-  test_VariableDeclaration_name_hasSome_parameterizedType() async {
+  Future<void> test_VariableDeclaration_name_hasSome_parameterizedType() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {List<int> m^}');
     await assertOpType(varNames: true, functionBody: true);
   }
 
-  test_VariableDeclaration_name_hasSome_simpleType() async {
+  Future<void> test_VariableDeclaration_name_hasSome_simpleType() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('main() {String m^}');
     await assertOpType(varNames: true, functionBody: true);
   }
 
-  test_VariableDeclarationList_final() async {
+  Future<void> test_VariableDeclarationList_final() async {
     // VariableDeclarationList  VariableDeclarationStatement  Block
     addTestSource('main() {final ^}');
     await assertOpType(typeNames: true, functionBody: true);
@@ -2446,31 +2457,31 @@
     super.setUp();
   }
 
-  test_extensionDeclaration_body() async {
+  Future<void> test_extensionDeclaration_body() async {
     // ExtensionDeclaration  CompilationUnit
     addTestSource('extension E on int {^}');
     await assertOpType(typeNames: true);
   }
 
-  test_extensionDeclaration_body2() async {
+  Future<void> test_extensionDeclaration_body2() async {
     // SimpleIdentifier  MethodDeclaration  ExtensionDeclaration
     addTestSource('extension E on int {^mth() {}}');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inExtension1() async {
+  Future<void> test_methodDeclaration_inExtension1() async {
     // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
     addTestSource('extension E on int {const ^Fara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inExtension2() async {
+  Future<void> test_methodDeclaration_inExtension2() async {
     // SimpleIdentifier  ExtensionDeclaration  MixinDeclaration
     addTestSource('extension E on int {const F^ara();}');
     await assertOpType(typeNames: true);
   }
 
-  test_methodDeclaration_inExtension_returnType() async {
+  Future<void> test_methodDeclaration_inExtension_returnType() async {
     // ExtensionDeclaration  CompilationUnit
     addTestSource('extension E on int {^ zoo(z) { } String name; }');
     await assertOpType(typeNames: true);
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/completion/test_all.dart
index 6935d56..525436a 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/test_all.dart
@@ -7,7 +7,7 @@
 import 'completion_target_test.dart' as completion_target_test;
 import 'optype_test.dart' as optype_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     completion_target_test.main();
     optype_test.main();
diff --git a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
index c96542a..c49d270 100644
--- a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
@@ -15,7 +15,7 @@
 class NavigationCollectorImplTest {
   NavigationCollectorImpl collector = NavigationCollectorImpl();
 
-  test_createRegions_multiple() {
+  void test_createRegions_multiple() {
     // Two files, each with two targets.
     String fileA = 'a.dart';
     int targetOffsetA1 = 1;
@@ -95,14 +95,14 @@
     ]);
   }
 
-  test_createRegions_none() {
+  void test_createRegions_none() {
     collector.createRegions();
     expect(collector.files, isEmpty);
     expect(collector.regions, isEmpty);
     expect(collector.targets, isEmpty);
   }
 
-  test_createRegions_single() {
+  void test_createRegions_single() {
     int regionOffset = 13;
     int regionLength = 7;
     ElementKind targetKind = ElementKind.CLASS;
diff --git a/pkg/analyzer_plugin/test/src/utilities/navigation/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/navigation/test_all.dart
index c48c1b6..64ba823 100644
--- a/pkg/analyzer_plugin/test/src/utilities/navigation/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/navigation/test_all.dart
@@ -6,7 +6,7 @@
 
 import 'navigation_test.dart' as navigation_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     navigation_test.main();
   }, name: 'navigation');
diff --git a/pkg/analyzer_plugin/test/src/utilities/string_utilities_test.dart b/pkg/analyzer_plugin/test/src/utilities/string_utilities_test.dart
index 456906e..cb99ba9 100644
--- a/pkg/analyzer_plugin/test/src/utilities/string_utilities_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/string_utilities_test.dart
@@ -6,7 +6,7 @@
 import 'package:test/test.dart' hide isEmpty;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(StringUtilitiesTest);
   });
diff --git a/pkg/analyzer_plugin/test/src/utilities/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/test_all.dart
index f7a8e3c..ba180de 100644
--- a/pkg/analyzer_plugin/test/src/utilities/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/test_all.dart
@@ -10,7 +10,7 @@
 import 'string_utilities_test.dart' as string_utilities;
 import 'visitors/test_all.dart' as visitors;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     change_builder.main();
     completion.main();
diff --git a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
index 2909b94..78a03aa 100644
--- a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
@@ -14,7 +14,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(LocalDeclarationVisitorTest);
   });
@@ -35,7 +35,7 @@
     return unit;
   }
 
-  test_visitForEachStatement() {
+  void test_visitForEachStatement() {
     CompilationUnit unit = parseCompilationUnit('''
 class MyClass {}
 f(List<MyClass> list) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/visitors/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/visitors/test_all.dart
index 4dad061..9de02ce 100644
--- a/pkg/analyzer_plugin/test/src/utilities/visitors/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/visitors/test_all.dart
@@ -6,8 +6,7 @@
 
 import 'local_declaration_visitor_test.dart' as local_declaration_visitor_test;
 
-/// Utility for manually running all tests.
-main() {
+void main() {
   defineReflectiveSuite(() {
     local_declaration_visitor_test.main();
   });
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index 41fd658..fc4e0bc 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -164,7 +164,7 @@
   _ElementVisitorFunctionWrapper(this.function);
 
   @override
-  visitElement(Element element) {
+  void visitElement(Element element) {
     function(element);
     super.visitElement(element);
   }
diff --git a/pkg/analyzer_plugin/test/test_all.dart b/pkg/analyzer_plugin/test/test_all.dart
index b5cdb54..4e58423 100644
--- a/pkg/analyzer_plugin/test/test_all.dart
+++ b/pkg/analyzer_plugin/test/test_all.dart
@@ -10,7 +10,7 @@
 import 'utilities/test_all.dart' as utilities;
 import 'verify_tests_test.dart' as verify_tests;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     plugin.main();
     src.main();
@@ -24,7 +24,7 @@
 
 @reflectiveTest
 class SpecTest {
-  test_specHasBeenGenerated() {
+  void test_specHasBeenGenerated() {
     check_spec.main();
   }
 }
diff --git a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
index 79ee6fe..a268944 100644
--- a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
@@ -81,7 +81,7 @@
     testFile = convertPath('/test.dart');
   }
 
-  test_convertAnalysisError_contextMessages() {
+  void test_convertAnalysisError_contextMessages() {
     analyzer.AnalysisError analyzerError =
         createError(13, contextMessage: 'here');
     analyzer.LineInfo lineInfo = analyzer.LineInfo([0, 10, 20]);
@@ -100,7 +100,7 @@
     expect(message.location.length, 7);
   }
 
-  test_convertAnalysisError_lineInfo_noSeverity() {
+  void test_convertAnalysisError_lineInfo_noSeverity() {
     analyzer.AnalysisError analyzerError = createError(13);
     analyzer.LineInfo lineInfo = analyzer.LineInfo([0, 10, 20]);
 
@@ -111,7 +111,7 @@
         startLine: 2);
   }
 
-  test_convertAnalysisError_lineInfo_severity() {
+  void test_convertAnalysisError_lineInfo_severity() {
     analyzer.AnalysisError analyzerError = createError(13);
     analyzer.LineInfo lineInfo = analyzer.LineInfo([0, 10, 20]);
     analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;
@@ -125,13 +125,13 @@
         severity: severity);
   }
 
-  test_convertAnalysisError_noLineInfo_noSeverity() {
+  void test_convertAnalysisError_noLineInfo_noSeverity() {
     analyzer.AnalysisError analyzerError = createError(11);
 
     assertError(converter.convertAnalysisError(analyzerError), analyzerError);
   }
 
-  test_convertAnalysisError_noLineInfo_severity() {
+  void test_convertAnalysisError_noLineInfo_severity() {
     analyzer.AnalysisError analyzerError = createError(11);
     analyzer.ErrorSeverity severity = analyzer.ErrorSeverity.WARNING;
 
@@ -141,7 +141,7 @@
         severity: severity);
   }
 
-  test_convertAnalysisErrors_lineInfo_noOptions() {
+  void test_convertAnalysisErrors_lineInfo_noOptions() {
     List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
       createError(13),
       createError(25)
@@ -157,7 +157,7 @@
         startColumn: 6, startLine: 3);
   }
 
-  test_convertAnalysisErrors_lineInfo_options() {
+  void test_convertAnalysisErrors_lineInfo_options() {
     List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
       createError(13),
       createError(25)
@@ -180,7 +180,7 @@
         startColumn: 6, startLine: 3, severity: severity);
   }
 
-  test_convertAnalysisErrors_noLineInfo_noOptions() {
+  void test_convertAnalysisErrors_noLineInfo_noOptions() {
     List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
       createError(11),
       createError(25)
@@ -193,7 +193,7 @@
     assertError(pluginErrors[1], analyzerErrors[1]);
   }
 
-  test_convertAnalysisErrors_noLineInfo_options() {
+  void test_convertAnalysisErrors_noLineInfo_options() {
     List<analyzer.AnalysisError> analyzerErrors = <analyzer.AnalysisError>[
       createError(13),
       createError(25)
@@ -211,7 +211,7 @@
     assertError(pluginErrors[1], analyzerErrors[1], severity: severity);
   }
 
-  test_convertElement_class() async {
+  Future<void> test_convertElement_class() async {
     analyzer.Source source = addSource(testFile, '''
 @deprecated
 abstract class _A {}
@@ -252,7 +252,7 @@
     }
   }
 
-  test_convertElement_constructor() async {
+  Future<void> test_convertElement_constructor() async {
     analyzer.Source source = addSource(testFile, '''
 class A {
   const A.myConstructor(int a, [String b]);
@@ -290,7 +290,7 @@
     expect(element.flags, 0);
   }
 
-  test_convertElement_enum() async {
+  Future<void> test_convertElement_enum() async {
     analyzer.Source source = addSource(testFile, '''
 @deprecated
 enum _E1 { one, two }
@@ -331,7 +331,7 @@
     }
   }
 
-  test_convertElement_enumConstant() async {
+  Future<void> test_convertElement_enumConstant() async {
     analyzer.Source source = addSource(testFile, '''
 @deprecated
 enum _E1 { one, two }
@@ -424,7 +424,7 @@
     }
   }
 
-  test_convertElement_field() async {
+  Future<void> test_convertElement_field() async {
     analyzer.Source source = addSource(testFile, '''
 class A {
   static const myField = 42;
@@ -450,7 +450,7 @@
         element.flags, plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
   }
 
-  test_convertElement_functionTypeAlias() async {
+  Future<void> test_convertElement_functionTypeAlias() async {
     analyzer.Source source = addSource(testFile, '''
 typedef int F<T>(String x);
 ''');
@@ -475,7 +475,7 @@
     expect(element.flags, 0);
   }
 
-  test_convertElement_genericTypeAlias_function() async {
+  Future<void> test_convertElement_genericTypeAlias_function() async {
     analyzer.Source source = addSource(testFile, '''
 typedef F<T> = int Function(String x);
 ''');
@@ -500,7 +500,7 @@
     expect(element.flags, 0);
   }
 
-  test_convertElement_getter() async {
+  Future<void> test_convertElement_getter() async {
     analyzer.Source source = addSource(testFile, '''
 class A {
   String get myGetter => 42;
@@ -526,7 +526,7 @@
     expect(element.flags, 0);
   }
 
-  test_convertElement_method() async {
+  Future<void> test_convertElement_method() async {
     analyzer.Source source = addSource(testFile, '''
 class A {
   static List<String> myMethod(int a, {String b, int c}) {
@@ -553,7 +553,7 @@
     expect(element.flags, plugin.Element.FLAG_STATIC);
   }
 
-  test_convertElement_setter() async {
+  Future<void> test_convertElement_setter() async {
     analyzer.Source source = addSource(testFile, '''
 class A {
   set mySetter(String x) {}
@@ -614,7 +614,7 @@
         plugin.ElementKind.TYPE_PARAMETER);
   }
 
-  test_convertErrorSeverity() {
+  void test_convertErrorSeverity() {
     for (analyzer.ErrorSeverity severity in analyzer.ErrorSeverity.values) {
       if (severity != analyzer.ErrorSeverity.NONE) {
         expect(converter.convertErrorSeverity(severity), isNotNull,
@@ -623,13 +623,13 @@
     }
   }
 
-  test_convertErrorType() {
+  void test_convertErrorType() {
     for (analyzer.ErrorType type in analyzer.ErrorType.values) {
       expect(converter.convertErrorType(type), isNotNull, reason: type.name);
     }
   }
 
-  test_fromElement_LABEL() async {
+  Future<void> test_fromElement_LABEL() async {
     analyzer.Source source = addSource(testFile, '''
 main() {
 myLabel:
diff --git a/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
index 0d88a14..9333c75 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
@@ -39,7 +39,7 @@
     return parser.parseExpression(scanner.tokenize());
   }
 
-  test_danglingExpressionCompletionIsValid() {
+  void test_danglingExpressionCompletionIsValid() {
     // Test that users can parse dangling expressions of dart and autocomplete
     // them without crash/with the correct offset information.
     final snippet = wrapForCompliance(parseDanglingDart('identifier'));
diff --git a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
index 723b10c..7a6c17d 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
@@ -10,7 +10,7 @@
 
 import 'completion_contributor_util.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InheritedReferenceContributorTest);
   });
@@ -27,7 +27,7 @@
   }
 
   /// Sanity check. Permutations tested in local_ref_contributor.
-  test_ArgDefaults_inherited_method_with_required_named() async {
+  Future<void> test_ArgDefaults_inherited_method_with_required_named() async {
     addMetaPackage();
     resolveSource('/home/test/lib/b.dart', '''
 import 'package:meta/meta.dart';
@@ -48,7 +48,7 @@
         defaultArgListString: 'bar, baz: null');
   }
 
-  test_AwaitExpression_inherited() async {
+  Future<void> test_AwaitExpression_inherited() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
     resolveSource('/home/test/lib/b.dart', '''
 lib libB;
@@ -74,7 +74,7 @@
     assertSuggestMethod('y', 'A', 'Future<dynamic>');
   }
 
-  test_Block_inherited_imported() async {
+  Future<void> test_Block_inherited_imported() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     resolveSource('/home/test/lib/b.dart', '''
       lib B;
@@ -101,7 +101,7 @@
     assertNotSuggested('==');
   }
 
-  test_Block_inherited_local() async {
+  Future<void> test_Block_inherited_local() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     addTestSource('''
 class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
@@ -125,7 +125,7 @@
     assertSuggestMethod('m2', 'M', 'int');
   }
 
-  test_inherited() async {
+  Future<void> test_inherited() async {
     resolveSource('/home/test/lib/b.dart', '''
 lib libB;
 class A2 {
@@ -166,7 +166,7 @@
     assertSuggestMethod('y2', 'A2', 'int');
   }
 
-  test_method_in_class() async {
+  Future<void> test_method_in_class() async {
     addTestSource('''
 class A {
   void m(x, int y) {}
@@ -177,7 +177,7 @@
     assertNotSuggested('m');
   }
 
-  test_method_parameters_mixed_required_and_named() async {
+  Future<void> test_method_parameters_mixed_required_and_named() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m(x, {int y}) {}
@@ -200,7 +200,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_mixed_required_and_named_local() async {
+  Future<void> test_method_parameters_mixed_required_and_named_local() async {
     addTestSource('''
 class A {
   void m(x, {int y}) {}
@@ -220,7 +220,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_mixed_required_and_positional() async {
+  Future<void> test_method_parameters_mixed_required_and_positional() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m(x, [int y]) {}
@@ -243,7 +243,8 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_mixed_required_and_positional_local() async {
+  Future<void>
+      test_method_parameters_mixed_required_and_positional_local() async {
     addTestSource('''
 class A {
   void m(x, [int y]) {}
@@ -263,7 +264,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_named() async {
+  Future<void> test_method_parameters_named() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m({x, int y}) {}
@@ -286,7 +287,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_named_local() async {
+  Future<void> test_method_parameters_named_local() async {
     addTestSource('''
 class A {
   void m({x, int y}) {}
@@ -306,7 +307,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_none() async {
+  Future<void> test_method_parameters_none() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m() {}
@@ -326,7 +327,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_none_local() async {
+  Future<void> test_method_parameters_none_local() async {
     addTestSource('''
 class A {
   void m() {}
@@ -343,7 +344,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_positional() async {
+  Future<void> test_method_parameters_positional() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m([x, int y]) {}
@@ -366,7 +367,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_positional_local() async {
+  Future<void> test_method_parameters_positional_local() async {
     addTestSource('''
 class A {
   void m([x, int y]) {}
@@ -386,7 +387,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_required() async {
+  Future<void> test_method_parameters_required() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m(x, int y) {}
@@ -409,7 +410,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_mixin_ordering() async {
+  Future<void> test_mixin_ordering() async {
     resolveSource('/home/test/lib/a.dart', '''
 class B {}
 class M1 {
@@ -431,7 +432,7 @@
     assertSuggestMethod('m', 'M1', 'void');
   }
 
-  test_no_parameters_field() async {
+  Future<void> test_no_parameters_field() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   int x;
@@ -448,7 +449,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_no_parameters_getter() async {
+  Future<void> test_no_parameters_getter() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   int get x => null;
@@ -465,7 +466,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_no_parameters_setter() async {
+  Future<void> test_no_parameters_setter() async {
     resolveSource('/home/test/lib/a.dart', '''
 class A {
   set x(int value) {};
@@ -482,7 +483,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_outside_class() async {
+  Future<void> test_outside_class() async {
     resolveSource('/home/test/lib/b.dart', '''
 lib libB;
 class A2 {
@@ -523,7 +524,7 @@
     assertNotSuggested('y2');
   }
 
-  test_static_field() async {
+  Future<void> test_static_field() async {
     resolveSource('/home/test/lib/b.dart', '''
 lib libB;
 class A2 {
@@ -564,7 +565,7 @@
     assertNotSuggested('y2');
   }
 
-  test_static_method() async {
+  Future<void> test_static_method() async {
     resolveSource('/home/test/lib/b.dart', '''
 lib libB;
 class A2 {
diff --git a/pkg/analyzer_plugin/test/utilities/completion/test_all.dart b/pkg/analyzer_plugin/test/utilities/completion/test_all.dart
index ebca199..5fd7132 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/test_all.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/test_all.dart
@@ -4,12 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'completion_target_test.dart' as completion_target_test;
 import 'inherited_reference_contributor_test.dart'
     as inherited_reference_contributor_test;
 import 'type_member_contributor_test.dart' as type_member_contributor_test;
-import 'completion_target_test.dart' as completion_target_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     inherited_reference_contributor_test.main();
     type_member_contributor_test.main();
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 33df41b..f931d09 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -13,7 +13,7 @@
 
 import 'completion_contributor_util.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(TypeMemberContributorTest);
   });
@@ -25,7 +25,7 @@
   /// shadows a declaration of the form [shadowee] in a base class, for the
   /// purposes of what is shown during completion. [shouldBeShadowed] indicates
   /// whether shadowing is expected.
-  Future check_shadowing(
+  Future<void> check_shadowing(
       String shadower, String shadowee, bool shouldBeShadowed) async {
     addTestSource('''
 class Base {
@@ -55,7 +55,7 @@
     return TypeMemberContributor();
   }
 
-  test_ArgDefaults_method() async {
+  Future<void> test_ArgDefaults_method() async {
     addTestSource('''
 class A {
   bool a(int b, bool c) => false;
@@ -67,7 +67,7 @@
     assertSuggestMethod('a', 'A', 'bool', defaultArgListString: 'b, c');
   }
 
-  test_ArgDefaults_method_none() async {
+  Future<void> test_ArgDefaults_method_none() async {
     addTestSource('''
 class A {
   bool a() => false;
@@ -79,7 +79,7 @@
     assertSuggestMethod('a', 'A', 'bool', defaultArgListString: null);
   }
 
-  test_ArgDefaults_method_with_optional_positional() async {
+  Future<void> test_ArgDefaults_method_with_optional_positional() async {
     addMetaPackage();
     addTestSource('''
 import 'package:meta/meta.dart';
@@ -94,7 +94,7 @@
     assertSuggestMethod('foo', 'A', 'bool', defaultArgListString: 'bar');
   }
 
-  test_ArgDefaults_method_with_required_named() async {
+  Future<void> test_ArgDefaults_method_with_required_named() async {
     addMetaPackage();
     addTestSource('''
 import 'package:meta/meta.dart';
@@ -110,7 +110,7 @@
         defaultArgListString: 'bar, baz: null');
   }
 
-  test_ArgumentList() async {
+  Future<void> test_ArgumentList() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -134,7 +134,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_imported_function() async {
+  Future<void> test_ArgumentList_imported_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -159,7 +159,8 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+  Future<void>
+      test_ArgumentList_InstanceCreationExpression_functionalArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -186,7 +187,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+  Future<void> test_ArgumentList_InstanceCreationExpression_typedefArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -214,7 +215,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_local_function() async {
+  Future<void> test_ArgumentList_local_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -239,7 +240,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_local_method() async {
+  Future<void> test_ArgumentList_local_method() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -264,7 +265,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_MethodInvocation_functionalArg() async {
+  Future<void> test_ArgumentList_MethodInvocation_functionalArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -291,7 +292,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_MethodInvocation_methodArg() async {
+  Future<void> test_ArgumentList_MethodInvocation_methodArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         library A;
@@ -316,7 +317,7 @@
     assertNotSuggested('print');
   }
 
-  test_ArgumentList_namedParam() async {
+  Future<void> test_ArgumentList_namedParam() async {
     // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
     // ExpressionStatement
     addSource('/home/test/lib/a.dart', '''
@@ -334,7 +335,7 @@
     assertNotSuggested('main');
   }
 
-  test_AsExpression() async {
+  Future<void> test_AsExpression() async {
     // SimpleIdentifier  TypeName  AsExpression
     addTestSource('''
         class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
@@ -348,7 +349,7 @@
     assertNotSuggested('==');
   }
 
-  test_AssignmentExpression_name() async {
+  Future<void> test_AssignmentExpression_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('class A {} main() {int a; int ^b = 1;}');
@@ -356,7 +357,7 @@
     assertNoSuggestions();
   }
 
-  test_AssignmentExpression_RHS() async {
+  Future<void> test_AssignmentExpression_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('class A {} main() {int a; int b = ^}');
@@ -369,7 +370,7 @@
     assertNotSuggested('Object');
   }
 
-  test_AssignmentExpression_type() async {
+  Future<void> test_AssignmentExpression_type() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -391,7 +392,7 @@
     //assertNotSuggested('identical');
   }
 
-  test_AssignmentExpression_type_newline() async {
+  Future<void> test_AssignmentExpression_type_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -412,7 +413,7 @@
     assertNotSuggested('identical');
   }
 
-  test_AssignmentExpression_type_partial() async {
+  Future<void> test_AssignmentExpression_type_partial() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -434,7 +435,7 @@
     //assertNotSuggested('identical');
   }
 
-  test_AssignmentExpression_type_partial_newline() async {
+  Future<void> test_AssignmentExpression_type_partial_newline() async {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
@@ -455,7 +456,7 @@
     assertNotSuggested('identical');
   }
 
-  test_AwaitExpression() async {
+  Future<void> test_AwaitExpression() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
     addTestSource('''
         class A {int x; int y() => 0;}
@@ -469,7 +470,7 @@
     assertNotSuggested('Object');
   }
 
-  test_BinaryExpression_LHS() async {
+  Future<void> test_BinaryExpression_LHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = ^ + 2;}');
@@ -481,7 +482,7 @@
     assertNotSuggested('b');
   }
 
-  test_BinaryExpression_RHS() async {
+  Future<void> test_BinaryExpression_RHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
     addTestSource('main() {int a = 1, b = 2 + ^;}');
@@ -494,7 +495,7 @@
     assertNotSuggested('==');
   }
 
-  test_Block() async {
+  Future<void> test_Block() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
@@ -586,7 +587,7 @@
     assertNotSuggested('parseHex');
   }
 
-  test_Block_final() async {
+  Future<void> test_Block_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
@@ -684,21 +685,21 @@
     assertNotSuggested('parseHex');
   }
 
-  test_Block_final2() async {
+  Future<void> test_Block_final2() async {
     addTestSource('main() {final S^ v;}');
     await computeSuggestions();
 
     assertNotSuggested('String');
   }
 
-  test_Block_final3() async {
+  Future<void> test_Block_final3() async {
     addTestSource('main() {final ^ v;}');
     await computeSuggestions();
 
     assertNotSuggested('String');
   }
 
-  test_Block_final_final() async {
+  Future<void> test_Block_final_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
@@ -796,7 +797,7 @@
     assertNotSuggested('parseHex');
   }
 
-  test_Block_final_var() async {
+  Future<void> test_Block_final_var() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
@@ -894,7 +895,7 @@
     assertNotSuggested('parseHex');
   }
 
-  test_Block_identifier_partial() async {
+  Future<void> test_Block_identifier_partial() async {
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
         class A {int x;}
@@ -972,7 +973,7 @@
     assertNotSuggested('HtmlElement');
   }
 
-  test_Block_inherited_imported() async {
+  Future<void> test_Block_inherited_imported() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -1003,7 +1004,7 @@
     assertNotSuggested('==');
   }
 
-  test_Block_inherited_local() async {
+  Future<void> test_Block_inherited_local() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
     addTestSource('''
         class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
@@ -1026,7 +1027,7 @@
     assertNotSuggested('m2');
   }
 
-  test_Block_local_function() async {
+  Future<void> test_Block_local_function() async {
     addSource('/testAB.dart', '''
         export "dart:math" hide max;
         class A {int x;}
@@ -1075,7 +1076,7 @@
     assertNotSuggested('parseHex');
   }
 
-  test_Block_unimported() async {
+  Future<void> test_Block_unimported() async {
     addPackageFile('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
     addSource(
         '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
@@ -1090,7 +1091,7 @@
     assertNotSuggested('Future');
   }
 
-  test_CascadeExpression_method1() async {
+  Future<void> test_CascadeExpression_method1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1114,7 +1115,7 @@
     assertNotSuggested('==');
   }
 
-  test_CascadeExpression_selector1() async {
+  Future<void> test_CascadeExpression_selector1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1138,7 +1139,7 @@
     assertNotSuggested('==');
   }
 
-  test_CascadeExpression_selector2() async {
+  Future<void> test_CascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1160,7 +1161,7 @@
     assertNotSuggested('==');
   }
 
-  test_CascadeExpression_selector2_withTrailingReturn() async {
+  Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1182,7 +1183,7 @@
     assertNotSuggested('==');
   }
 
-  test_CascadeExpression_target() async {
+  Future<void> test_CascadeExpression_target() async {
     // SimpleIdentifier  CascadeExpression  ExpressionStatement
     addTestSource('''
         class A {var b; X _c;}
@@ -1201,7 +1202,7 @@
     assertNotSuggested('==');
   }
 
-  test_CatchClause_onType() async {
+  Future<void> test_CatchClause_onType() async {
     // TypeName  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^ {}}}');
     await computeSuggestions();
@@ -1213,7 +1214,7 @@
     assertNotSuggested('x');
   }
 
-  test_CatchClause_onType_noBrackets() async {
+  Future<void> test_CatchClause_onType_noBrackets() async {
     // TypeName  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^}}');
     await computeSuggestions();
@@ -1224,7 +1225,7 @@
     assertNotSuggested('x');
   }
 
-  test_CatchClause_typed() async {
+  Future<void> test_CatchClause_typed() async {
     // Block  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
     await computeSuggestions();
@@ -1236,7 +1237,7 @@
     assertNotSuggested('x');
   }
 
-  test_CatchClause_untyped() async {
+  Future<void> test_CatchClause_untyped() async {
     // Block  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
     await computeSuggestions();
@@ -1249,7 +1250,7 @@
     assertNotSuggested('x');
   }
 
-  test_ClassDeclaration_body() async {
+  Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1268,7 +1269,7 @@
     assertNotSuggested('x');
   }
 
-  test_ClassDeclaration_body_final() async {
+  Future<void> test_ClassDeclaration_body_final() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1287,7 +1288,7 @@
     assertNotSuggested('x');
   }
 
-  test_ClassDeclaration_body_final_field() async {
+  Future<void> test_ClassDeclaration_body_final_field() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1306,7 +1307,7 @@
     assertNotSuggested('x');
   }
 
-  test_ClassDeclaration_body_final_field2() async {
+  Future<void> test_ClassDeclaration_body_final_field2() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1325,7 +1326,7 @@
     assertNotSuggested('Soo');
   }
 
-  test_ClassDeclaration_body_final_final() async {
+  Future<void> test_ClassDeclaration_body_final_final() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1344,7 +1345,7 @@
     assertNotSuggested('x');
   }
 
-  test_ClassDeclaration_body_final_var() async {
+  Future<void> test_ClassDeclaration_body_final_var() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
         class B { }''');
@@ -1363,7 +1364,7 @@
     assertNotSuggested('x');
   }
 
-  test_Combinator_hide() async {
+  Future<void> test_Combinator_hide() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
     addSource('/testAB.dart', '''
         library libAB;
@@ -1386,7 +1387,7 @@
     assertNoSuggestions();
   }
 
-  test_Combinator_show() async {
+  Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
     addSource('/testAB.dart', '''
         library libAB;
@@ -1411,7 +1412,7 @@
     assertNoSuggestions();
   }
 
-  test_ConditionalExpression_elseExpression() async {
+  Future<void> test_ConditionalExpression_elseExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1430,7 +1431,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_ConditionalExpression_elseExpression_empty() async {
+  Future<void> test_ConditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1455,7 +1456,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_ConditionalExpression_partial_thenExpression() async {
+  Future<void> test_ConditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1474,7 +1475,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_ConditionalExpression_partial_thenExpression_empty() async {
+  Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1499,7 +1500,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_ConditionalExpression_thenExpression() async {
+  Future<void> test_ConditionalExpression_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1518,7 +1519,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_ConstructorName_importedClass() async {
+  Future<void> test_ConstructorName_importedClass() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addSource('/home/test/lib/b.dart', '''
@@ -1542,7 +1543,7 @@
     assertNotSuggested('m');
   }
 
-  test_ConstructorName_importedFactory() async {
+  Future<void> test_ConstructorName_importedFactory() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addSource('/home/test/lib/b.dart', '''
@@ -1566,7 +1567,7 @@
     assertNotSuggested('m');
   }
 
-  test_ConstructorName_importedFactory2() async {
+  Future<void> test_ConstructorName_importedFactory2() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
@@ -1583,7 +1584,7 @@
     assertNotSuggested('String');
   }
 
-  test_ConstructorName_localClass() async {
+  Future<void> test_ConstructorName_localClass() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
@@ -1603,7 +1604,7 @@
     assertNotSuggested('m');
   }
 
-  test_ConstructorName_localFactory() async {
+  Future<void> test_ConstructorName_localFactory() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
@@ -1623,7 +1624,7 @@
     assertNotSuggested('m');
   }
 
-  test_DefaultFormalParameter_named_expression() async {
+  Future<void> test_DefaultFormalParameter_named_expression() async {
     // DefaultFormalParameter FormalParameterList MethodDeclaration
     addTestSource('''
         foo() { }
@@ -1640,7 +1641,7 @@
     assertNotSuggested('bar');
   }
 
-  test_enumConst() async {
+  Future<void> test_enumConst() async {
     addTestSource('enum E { one, two } main() {E.^}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1651,7 +1652,7 @@
     assertNotSuggested('values');
   }
 
-  test_enumConst2() async {
+  Future<void> test_enumConst2() async {
     addTestSource('enum E { one, two } main() {E.o^}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1662,7 +1663,7 @@
     assertNotSuggested('values');
   }
 
-  test_enumConst3() async {
+  Future<void> test_enumConst3() async {
     addTestSource('enum E { one, two } main() {E.^ int g;}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1673,7 +1674,7 @@
     assertNotSuggested('values');
   }
 
-  test_enumConst_index() async {
+  Future<void> test_enumConst_index() async {
     addTestSource('enum E { one, two } main() {E.one.^}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1683,7 +1684,7 @@
     assertNotSuggested('values');
   }
 
-  test_enumConst_index2() async {
+  Future<void> test_enumConst_index2() async {
     addTestSource('enum E { one, two } main() {E.one.i^}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1693,7 +1694,7 @@
     assertNotSuggested('values');
   }
 
-  test_enumConst_index3() async {
+  Future<void> test_enumConst_index3() async {
     addTestSource('enum E { one, two } main() {E.one.^ int g;}');
     await computeSuggestions();
     assertNotSuggested('E');
@@ -1703,7 +1704,7 @@
     assertNotSuggested('values');
   }
 
-  test_ExpressionStatement_identifier() async {
+  Future<void> test_ExpressionStatement_identifier() async {
     // SimpleIdentifier  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         _B F1() { }
@@ -1729,7 +1730,7 @@
     assertNotSuggested('_B');
   }
 
-  test_ExpressionStatement_name() async {
+  Future<void> test_ExpressionStatement_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
     addSource('/home/test/lib/a.dart', '''
         B T1;
@@ -1741,7 +1742,7 @@
     assertNoSuggestions();
   }
 
-  test_FieldDeclaration_name_typed() async {
+  Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
     addSource('/home/test/lib/a.dart', 'class A { }');
@@ -1752,7 +1753,7 @@
     assertNoSuggestions();
   }
 
-  test_FieldDeclaration_name_var() async {
+  Future<void> test_FieldDeclaration_name_var() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
     addSource('/home/test/lib/a.dart', 'class A { }');
@@ -1763,7 +1764,7 @@
     assertNoSuggestions();
   }
 
-  test_FieldFormalParameter_in_non_constructor() async {
+  Future<void> test_FieldFormalParameter_in_non_constructor() async {
     // SimpleIdentifer  FieldFormalParameter  FormalParameterList
     addTestSource('class A {B(this.^foo) {}}');
     await computeSuggestions();
@@ -1772,7 +1773,7 @@
     assertNoSuggestions();
   }
 
-  test_ForEachStatement_body_typed() async {
+  Future<void> test_ForEachStatement_body_typed() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (int foo in bar) {^}}');
     await computeSuggestions();
@@ -1783,7 +1784,7 @@
     assertNotSuggested('Object');
   }
 
-  test_ForEachStatement_body_untyped() async {
+  Future<void> test_ForEachStatement_body_untyped() async {
     // Block  ForEachStatement
     addTestSource('main(args) {for (foo in bar) {^}}');
     await computeSuggestions();
@@ -1794,7 +1795,7 @@
     assertNotSuggested('Object');
   }
 
-  test_ForEachStatement_iterable() async {
+  Future<void> test_ForEachStatement_iterable() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (int foo in ^) {}}');
     await computeSuggestions();
@@ -1804,7 +1805,7 @@
     assertNotSuggested('Object');
   }
 
-  test_ForEachStatement_loopVariable() async {
+  Future<void> test_ForEachStatement_loopVariable() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (^ in args) {}}');
     await computeSuggestions();
@@ -1814,7 +1815,7 @@
     assertNotSuggested('String');
   }
 
-  test_ForEachStatement_loopVariable_type() async {
+  Future<void> test_ForEachStatement_loopVariable_type() async {
     // SimpleIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (^ foo in args) {}}');
     await computeSuggestions();
@@ -1825,7 +1826,7 @@
     assertNotSuggested('String');
   }
 
-  test_ForEachStatement_loopVariable_type2() async {
+  Future<void> test_ForEachStatement_loopVariable_type2() async {
     // DeclaredIdentifier  ForEachStatement  Block
     addTestSource('main(args) {for (S^ foo in args) {}}');
     await computeSuggestions();
@@ -1836,7 +1837,7 @@
     assertNotSuggested('String');
   }
 
-  test_FormalParameterList() async {
+  Future<void> test_FormalParameterList() async {
     // FormalParameterList MethodDeclaration
     addTestSource('''
         foo() { }
@@ -1853,7 +1854,7 @@
     assertNotSuggested('bar');
   }
 
-  test_ForStatement_body() async {
+  Future<void> test_ForStatement_body() async {
     // Block  ForStatement
     addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
     await computeSuggestions();
@@ -1863,7 +1864,7 @@
     assertNotSuggested('Object');
   }
 
-  test_ForStatement_condition() async {
+  Future<void> test_ForStatement_condition() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; i^)}');
     await computeSuggestions();
@@ -1872,7 +1873,7 @@
     assertNotSuggested('index');
   }
 
-  test_ForStatement_initializer() async {
+  Future<void> test_ForStatement_initializer() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {List a; for (^)}');
     await computeSuggestions();
@@ -1883,7 +1884,7 @@
     assertNotSuggested('int');
   }
 
-  test_ForStatement_updaters() async {
+  Future<void> test_ForStatement_updaters() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; i^)}');
     await computeSuggestions();
@@ -1892,7 +1893,7 @@
     assertNotSuggested('index');
   }
 
-  test_ForStatement_updaters_prefix_expression() async {
+  Future<void> test_ForStatement_updaters_prefix_expression() async {
     // SimpleIdentifier  PrefixExpression  ForStatement
     addTestSource('''
         void bar() { }
@@ -1905,7 +1906,7 @@
     assertNotSuggested('bar');
   }
 
-  test_FunctionDeclaration_returnType_afterComment() async {
+  Future<void> test_FunctionDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1934,7 +1935,7 @@
     assertNotSuggested('name');
   }
 
-  test_FunctionDeclaration_returnType_afterComment2() async {
+  Future<void> test_FunctionDeclaration_returnType_afterComment2() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1963,7 +1964,7 @@
     assertNotSuggested('name');
   }
 
-  test_FunctionDeclaration_returnType_afterComment3() async {
+  Future<void> test_FunctionDeclaration_returnType_afterComment3() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -1993,7 +1994,7 @@
     assertNotSuggested('name');
   }
 
-  test_FunctionExpression_body_function() async {
+  Future<void> test_FunctionExpression_body_function() async {
     // Block  BlockFunctionBody  FunctionExpression
     addTestSource('''
         void bar() { }
@@ -2009,7 +2010,7 @@
     assertNotSuggested('Object');
   }
 
-  test_generic_field() async {
+  Future<void> test_generic_field() async {
     addTestSource('''
 class C<T> {
   T t;
@@ -2022,7 +2023,7 @@
     assertSuggestField('t', 'int');
   }
 
-  test_generic_getter() async {
+  Future<void> test_generic_getter() async {
     addTestSource('''
 class C<T> {
   T get t => null;
@@ -2035,7 +2036,7 @@
     assertSuggestGetter('t', 'int');
   }
 
-  test_generic_method() async {
+  Future<void> test_generic_method() async {
     addTestSource('''
 class C<T> {
   T m(T t) {}
@@ -2051,7 +2052,7 @@
     expect(suggestion.element.parameters, '(int t)');
   }
 
-  test_generic_setter() async {
+  Future<void> test_generic_setter() async {
     addTestSource('''
 class C<T> {
   set t(T value) {}
@@ -2068,7 +2069,7 @@
     expect(suggestion.element.parameters, '(int value)');
   }
 
-  test_genericTypeAlias_noFunctionType() async {
+  Future<void> test_genericTypeAlias_noFunctionType() async {
     addTestSource('''
 typedef F=;
 g(F.^
@@ -2076,7 +2077,7 @@
     await computeSuggestions();
   }
 
-  test_IfStatement() async {
+  Future<void> test_IfStatement() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
         class A {var b; X _c; foo() {A a; if (true) ^}}''');
@@ -2090,7 +2091,7 @@
     assertNotSuggested('==');
   }
 
-  test_IfStatement_condition() async {
+  Future<void> test_IfStatement_condition() async {
     // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
     addTestSource('''
         class A {int x; int y() => 0;}
@@ -2104,7 +2105,7 @@
     assertNotSuggested('Object');
   }
 
-  test_IfStatement_empty() async {
+  Future<void> test_IfStatement_empty() async {
     // SimpleIdentifier  IfStatement
     addTestSource('''
         class A {var b; X _c; foo() {A a; if (^) something}}''');
@@ -2118,7 +2119,7 @@
     assertNotSuggested('==');
   }
 
-  test_IfStatement_invocation() async {
+  Future<void> test_IfStatement_invocation() async {
     // SimpleIdentifier  PrefixIdentifier  IfStatement
     addTestSource('''
         main() {var a; if (a.^) something}''');
@@ -2131,7 +2132,7 @@
     assertNotSuggested('==');
   }
 
-  test_ImportDirective_dart() async {
+  Future<void> test_ImportDirective_dart() async {
     // SimpleStringLiteral  ImportDirective
     addTestSource('''
         import "dart^";
@@ -2140,7 +2141,7 @@
     assertNoSuggestions();
   }
 
-  test_IndexExpression() async {
+  Future<void> test_IndexExpression() async {
     // ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2165,7 +2166,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_IndexExpression2() async {
+  Future<void> test_IndexExpression2() async {
     // SimpleIdentifier IndexExpression ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2184,7 +2185,7 @@
     //assertSuggestImportedTopLevelVar('T1', 'int');
   }
 
-  test_InstanceCreationExpression_imported() async {
+  Future<void> test_InstanceCreationExpression_imported() async {
     // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2214,7 +2215,7 @@
     assertNotSuggested('T2');
   }
 
-  test_InstanceCreationExpression_unimported() async {
+  Future<void> test_InstanceCreationExpression_unimported() async {
     // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('class C {foo(){new F^}}');
@@ -2225,7 +2226,7 @@
     assertNotSuggested('Foo');
   }
 
-  test_InterpolationExpression() async {
+  Future<void> test_InterpolationExpression() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2254,7 +2255,7 @@
     assertNotSuggested('name');
   }
 
-  test_InterpolationExpression_block() async {
+  Future<void> test_InterpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2282,7 +2283,7 @@
     assertNotSuggested('name');
   }
 
-  test_InterpolationExpression_block2() async {
+  Future<void> test_InterpolationExpression_block2() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
     addTestSource('main() {String name; print("hello \${n^}");}');
     await computeSuggestions();
@@ -2291,7 +2292,7 @@
     //assertNotSuggested('Object');
   }
 
-  test_InterpolationExpression_prefix_selector() async {
+  Future<void> test_InterpolationExpression_prefix_selector() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${name.^}");}');
     await computeSuggestions();
@@ -2303,14 +2304,14 @@
     assertNotSuggested('==');
   }
 
-  test_InterpolationExpression_prefix_selector2() async {
+  Future<void> test_InterpolationExpression_prefix_selector2() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \$name.^");}');
     await computeSuggestions();
     assertNoSuggestions();
   }
 
-  test_InterpolationExpression_prefix_target() async {
+  Future<void> test_InterpolationExpression_prefix_target() async {
     // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
     addTestSource('main() {String name; print("hello \${nam^e.length}");}');
     await computeSuggestions();
@@ -2320,7 +2321,7 @@
     assertNotSuggested('length');
   }
 
-  test_IsExpression() async {
+  Future<void> test_IsExpression() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -2340,7 +2341,7 @@
     assertNotSuggested('foo');
   }
 
-  test_IsExpression_target() async {
+  Future<void> test_IsExpression_target() async {
     // IfStatement  Block  BlockFunctionBody
     addTestSource('''
         foo() { }
@@ -2358,7 +2359,7 @@
     assertNotSuggested('Object');
   }
 
-  test_IsExpression_type() async {
+  Future<void> test_IsExpression_type() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
@@ -2372,7 +2373,7 @@
     assertNotSuggested('Object');
   }
 
-  test_IsExpression_type_partial() async {
+  Future<void> test_IsExpression_type_partial() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
@@ -2386,14 +2387,14 @@
     assertNotSuggested('Object');
   }
 
-  test_keyword() async {
+  Future<void> test_keyword() async {
     addTestSource('class C { static C get instance => null; } main() {C.in^}');
     await computeSuggestions();
     // Suggested by StaticMemberContributor
     assertNotSuggested('instance');
   }
 
-  test_keyword2() async {
+  Future<void> test_keyword2() async {
     addSource('/home/test/lib/b.dart', '''
         lib B;
         int newT1;
@@ -2418,7 +2419,7 @@
     assertNotSuggested('newer');
   }
 
-  test_libraryPrefix() async {
+  Future<void> test_libraryPrefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('import "dart:async" as bar; foo() {bar.^}');
     await computeSuggestions();
@@ -2427,7 +2428,7 @@
     assertNotSuggested('loadLibrary');
   }
 
-  test_libraryPrefix2() async {
+  Future<void> test_libraryPrefix2() async {
     // SimpleIdentifier  MethodInvocation  ExpressionStatement
     addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
     await computeSuggestions();
@@ -2435,7 +2436,7 @@
     assertNotSuggested('Future');
   }
 
-  test_libraryPrefix3() async {
+  Future<void> test_libraryPrefix3() async {
     // SimpleIdentifier  MethodInvocation  ExpressionStatement
     addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
     await computeSuggestions();
@@ -2444,7 +2445,7 @@
     assertNotSuggested('Future.delayed');
   }
 
-  test_libraryPrefix_deferred() async {
+  Future<void> test_libraryPrefix_deferred() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
     await computeSuggestions();
@@ -2453,7 +2454,7 @@
     assertNotSuggested('loadLibrary');
   }
 
-  test_libraryPrefix_with_exports() async {
+  Future<void> test_libraryPrefix_with_exports() async {
     addSource('/home/test/lib/a.dart', 'class A { }');
     addSource('/home/test/lib/b.dart', 'export "a.dart"; class B { }');
     addTestSource('import "b.dart" as foo; main() {foo.^} class C { }');
@@ -2463,7 +2464,7 @@
     assertNotSuggested('A');
   }
 
-  test_Literal_list() async {
+  Future<void> test_Literal_list() async {
     // ']'  ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([^]);}');
     await computeSuggestions();
@@ -2471,7 +2472,7 @@
     assertNotSuggested('String');
   }
 
-  test_Literal_list2() async {
+  Future<void> test_Literal_list2() async {
     // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
     addTestSource('main() {var Some; print([S^]);}');
     await computeSuggestions();
@@ -2479,39 +2480,39 @@
     assertNotSuggested('String');
   }
 
-  test_Literal_string() async {
+  Future<void> test_Literal_string() async {
     // SimpleStringLiteral  ExpressionStatement  Block
     addTestSource('class A {a() {"hel^lo"}}');
     await computeSuggestions();
     assertNoSuggestions();
   }
 
-  test_local() async {
+  Future<void> test_local() async {
     addTestSource('foo() {String x = "bar"; x.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_local_is() async {
+  Future<void> test_local_is() async {
     addTestSource('foo() {var x; if (x is String) x.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_local_propogatedType() async {
+  Future<void> test_local_propogatedType() async {
     addTestSource('foo() {var x = "bar"; x.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_localVariableDeclarationName() async {
+  Future<void> test_localVariableDeclarationName() async {
     addTestSource('main() {String m^}');
     await computeSuggestions();
     assertNotSuggested('main');
     assertNotSuggested('min');
   }
 
-  test_MapLiteralEntry() async {
+  Future<void> test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2538,7 +2539,7 @@
     assertNotSuggested('C2');
   }
 
-  test_MapLiteralEntry1() async {
+  Future<void> test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2558,7 +2559,7 @@
     assertNotSuggested('T2');
   }
 
-  test_MapLiteralEntry2() async {
+  Future<void> test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2578,7 +2579,7 @@
     assertNotSuggested('T2');
   }
 
-  test_method_parameters_mixed_required_and_named() async {
+  Future<void> test_method_parameters_mixed_required_and_named() async {
     addTestSource('''
 class C {
   void m(x, {int y}) {}
@@ -2595,7 +2596,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_mixed_required_and_positional() async {
+  Future<void> test_method_parameters_mixed_required_and_positional() async {
     addTestSource('''
 class C {
   void m(x, [int y]) {}
@@ -2612,7 +2613,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_named() async {
+  Future<void> test_method_parameters_named() async {
     addTestSource('''
 class C {
   void m({x, int y}) {}
@@ -2629,7 +2630,7 @@
     expect(suggestion.hasNamedParameters, true);
   }
 
-  test_method_parameters_none() async {
+  Future<void> test_method_parameters_none() async {
     addTestSource('''
 class C {
   void m() {}
@@ -2643,7 +2644,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_positional() async {
+  Future<void> test_method_parameters_positional() async {
     addTestSource('''
 class C {
   void m([x, int y]) {}
@@ -2660,7 +2661,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_method_parameters_required() async {
+  Future<void> test_method_parameters_required() async {
     addTestSource('''
 class C {
   void m(x, int y) {}
@@ -2677,7 +2678,7 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
-  test_MethodDeclaration_body_getters() async {
+  Future<void> test_MethodDeclaration_body_getters() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
     await computeSuggestions();
@@ -2688,7 +2689,7 @@
     assertNotSuggested('_g');
   }
 
-  test_MethodDeclaration_body_static() async {
+  Future<void> test_MethodDeclaration_body_static() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addSource('/testC.dart', '''
         class C {
@@ -2724,7 +2725,7 @@
     assertNotSuggested('c4');
   }
 
-  test_MethodDeclaration_members() async {
+  Future<void> test_MethodDeclaration_members() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
     await computeSuggestions();
@@ -2736,7 +2737,7 @@
     assertNotSuggested('bool');
   }
 
-  test_MethodDeclaration_parameters_named() async {
+  Future<void> test_MethodDeclaration_parameters_named() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
     await computeSuggestions();
@@ -2750,7 +2751,7 @@
     assertNotSuggested('_');
   }
 
-  test_MethodDeclaration_parameters_positional() async {
+  Future<void> test_MethodDeclaration_parameters_positional() async {
     // Block  BlockFunctionBody  MethodDeclaration
     addTestSource('''
         foo() { }
@@ -2767,7 +2768,7 @@
     assertNotSuggested('String');
   }
 
-  test_MethodDeclaration_returnType() async {
+  Future<void> test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2795,7 +2796,7 @@
     assertNotSuggested('name');
   }
 
-  test_MethodDeclaration_returnType_afterComment() async {
+  Future<void> test_MethodDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2823,7 +2824,7 @@
     assertNotSuggested('name');
   }
 
-  test_MethodDeclaration_returnType_afterComment2() async {
+  Future<void> test_MethodDeclaration_returnType_afterComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2851,7 +2852,7 @@
     assertNotSuggested('name');
   }
 
-  test_MethodDeclaration_returnType_afterComment3() async {
+  Future<void> test_MethodDeclaration_returnType_afterComment3() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     addSource('/home/test/lib/a.dart', '''
         int T1;
@@ -2881,7 +2882,7 @@
     assertNotSuggested('name');
   }
 
-  test_MethodInvocation_no_semicolon() async {
+  Future<void> test_MethodInvocation_no_semicolon() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource(r'''
         main() { }
@@ -2915,7 +2916,7 @@
     assertNotSuggested('==');
   }
 
-  test_new_instance() async {
+  Future<void> test_new_instance() async {
     addTestSource('import "dart:math"; class A {x() {new Random().^}}');
     await computeSuggestions();
     assertSuggestMethod('nextBool', 'Random', 'bool');
@@ -2926,7 +2927,7 @@
     assertNotSuggested('A');
   }
 
-  test_no_parameters_field() async {
+  Future<void> test_no_parameters_field() async {
     addTestSource('''
 class C {
   int x;
@@ -2937,7 +2938,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_no_parameters_getter() async {
+  Future<void> test_no_parameters_getter() async {
     addTestSource('''
 class C {
   int get x => null;
@@ -2948,7 +2949,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_no_parameters_setter() async {
+  Future<void> test_no_parameters_setter() async {
     addTestSource('''
 class C {
   set x(int value) {};
@@ -2959,7 +2960,7 @@
     assertHasNoParameterInfo(suggestion);
   }
 
-  test_only_instance() async {
+  Future<void> test_only_instance() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestSource('''
 class C {
@@ -2976,7 +2977,7 @@
     assertNotSuggested('m2');
   }
 
-  test_only_instance2() async {
+  Future<void> test_only_instance2() async {
     // SimpleIdentifier  MethodInvocation  ExpressionStatement
     addTestSource('''
 class C {
@@ -2993,7 +2994,7 @@
     assertNotSuggested('m2');
   }
 
-  test_only_static() async {
+  Future<void> test_only_static() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('''
 class C {
@@ -3011,7 +3012,7 @@
     assertNotSuggested('m2');
   }
 
-  test_only_static2() async {
+  Future<void> test_only_static2() async {
     // SimpleIdentifier  MethodInvocation  ExpressionStatement
     addTestSource('''
 class C {
@@ -3029,26 +3030,26 @@
     assertNotSuggested('m2');
   }
 
-  test_param() async {
+  Future<void> test_param() async {
     addTestSource('foo(String x) {x.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_param_is() async {
+  Future<void> test_param_is() async {
     addTestSource('foo(x) {if (x is String) x.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_parameterName_excludeTypes() async {
+  Future<void> test_parameterName_excludeTypes() async {
     addTestSource('m(int ^) {}');
     await computeSuggestions();
     assertNotSuggested('int');
     assertNotSuggested('bool');
   }
 
-  test_partFile_TypeName() async {
+  Future<void> test_partFile_TypeName() async {
     // SimpleIdentifier  TypeName  ConstructorName
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3080,7 +3081,7 @@
     assertNotSuggested('m');
   }
 
-  test_partFile_TypeName2() async {
+  Future<void> test_partFile_TypeName2() async {
     // SimpleIdentifier  TypeName  ConstructorName
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3112,7 +3113,7 @@
     assertNotSuggested('m');
   }
 
-  test_PrefixedIdentifier_class_const() async {
+  Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3158,7 +3159,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_class_imported() async {
+  Future<void> test_PrefixedIdentifier_class_imported() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3194,7 +3195,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_class_local() async {
+  Future<void> test_PrefixedIdentifier_class_local() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('''
         main() {A a; a.^}
@@ -3227,14 +3228,14 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_getter() async {
+  Future<void> test_PrefixedIdentifier_getter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('String get g => "one"; f() {g.^}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_library() async {
+  Future<void> test_PrefixedIdentifier_library() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3260,7 +3261,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_library_typesOnly() async {
+  Future<void> test_PrefixedIdentifier_library_typesOnly() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3286,7 +3287,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_library_typesOnly2() async {
+  Future<void> test_PrefixedIdentifier_library_typesOnly2() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3312,7 +3313,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_parameter() async {
+  Future<void> test_PrefixedIdentifier_parameter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addSource('/home/test/lib/b.dart', '''
         lib B;
@@ -3330,7 +3331,7 @@
     assertNotSuggested('==');
   }
 
-  test_PrefixedIdentifier_prefix() async {
+  Future<void> test_PrefixedIdentifier_prefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addSource('/home/test/lib/a.dart', '''
         class A {static int bar = 10;}
@@ -3348,7 +3349,7 @@
     assertNotSuggested('_B');
   }
 
-  test_PrefixedIdentifier_propertyAccess() async {
+  Future<void> test_PrefixedIdentifier_propertyAccess() async {
     // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
     addTestSource('class A {String x; int get foo {x.^}');
     await computeSuggestions();
@@ -3358,7 +3359,7 @@
     assertSuggestMethod('compareTo', 'Comparable', 'int');
   }
 
-  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+  Future<void> test_PrefixedIdentifier_propertyAccess_newStmt() async {
     // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
     addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
     await computeSuggestions();
@@ -3368,14 +3369,14 @@
     assertSuggestMethod('compareTo', 'Comparable', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_const() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_const() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_const_untyped() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_const_untyped() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
     await computeSuggestions();
@@ -3383,77 +3384,77 @@
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_field() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_field() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('class A {String g; f() {g.^ int y = 0;}}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_function() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_function() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('typedef String g(); f() {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_getter() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_getter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_local_typed() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('f() {String g; g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_local_untyped() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_method() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_method() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_param() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_param() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('class A {f(String g) {g.^ int y = 0;}}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_param2() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_param2() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('f(String g) {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+  Future<void> test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('String g; f() {g.^ int y = 0;}');
     await computeSuggestions();
     assertSuggestGetter('length', 'int');
   }
 
-  test_PropertyAccess_expression() async {
+  Future<void> test_PropertyAccess_expression() async {
     // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
     addTestSource('class A {a() {"hello".to^String().length}}');
     await computeSuggestions();
@@ -3466,7 +3467,7 @@
     assertNotSuggested('==');
   }
 
-  test_PropertyAccess_noTarget() async {
+  Future<void> test_PropertyAccess_noTarget() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('class C {foo(){.^}}');
@@ -3474,7 +3475,7 @@
     assertNoSuggestions();
   }
 
-  test_PropertyAccess_noTarget2() async {
+  Future<void> test_PropertyAccess_noTarget2() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('main() {.^}');
@@ -3482,7 +3483,7 @@
     assertNoSuggestions();
   }
 
-  test_PropertyAccess_selector() async {
+  Future<void> test_PropertyAccess_selector() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
     addTestSource('class A {a() {"hello".length.^}}');
     await computeSuggestions();
@@ -3495,43 +3496,43 @@
     assertNotSuggested('==');
   }
 
-  test_shadowing_field_over_field() =>
+  Future<void> test_shadowing_field_over_field() =>
       check_shadowing('int x;', 'int x;', true);
 
-  test_shadowing_field_over_getter() =>
+  Future<void> test_shadowing_field_over_getter() =>
       check_shadowing('int x;', 'int get x => null;', true);
 
-  test_shadowing_field_over_method() =>
+  Future<void> test_shadowing_field_over_method() =>
       check_shadowing('int x;', 'void x() {}', true);
 
-  test_shadowing_field_over_setter() =>
+  Future<void> test_shadowing_field_over_setter() =>
       check_shadowing('int x;', 'set x(int value) {}', true);
 
-  test_shadowing_getter_over_field() =>
+  Future<void> test_shadowing_getter_over_field() =>
       check_shadowing('int get x => null;', 'int x;', false);
 
-  test_shadowing_getter_over_getter() =>
+  Future<void> test_shadowing_getter_over_getter() =>
       check_shadowing('int get x => null;', 'int get x => null;', true);
 
-  test_shadowing_getter_over_method() =>
+  Future<void> test_shadowing_getter_over_method() =>
       check_shadowing('int get x => null;', 'void x() {}', true);
 
-  test_shadowing_getter_over_setter() =>
+  Future<void> test_shadowing_getter_over_setter() =>
       check_shadowing('int get x => null;', 'set x(int value) {}', false);
 
-  test_shadowing_method_over_field() =>
+  Future<void> test_shadowing_method_over_field() =>
       check_shadowing('void x() {}', 'int x;', true);
 
-  test_shadowing_method_over_getter() =>
+  Future<void> test_shadowing_method_over_getter() =>
       check_shadowing('void x() {}', 'int get x => null;', true);
 
-  test_shadowing_method_over_method() =>
+  Future<void> test_shadowing_method_over_method() =>
       check_shadowing('void x() {}', 'void x() {}', true);
 
-  test_shadowing_method_over_setter() =>
+  Future<void> test_shadowing_method_over_setter() =>
       check_shadowing('void x() {}', 'set x(int value) {}', true);
 
-  test_shadowing_mixin_order() async {
+  Future<void> test_shadowing_mixin_order() async {
     addTestSource('''
 class Base {
 }
@@ -3556,7 +3557,7 @@
     assertSuggestMethod('f', 'Mixin2', 'void');
   }
 
-  test_shadowing_mixin_over_superclass() async {
+  Future<void> test_shadowing_mixin_over_superclass() async {
     addTestSource('''
 class Base {
   void f() {}
@@ -3574,19 +3575,19 @@
     assertSuggestMethod('f', 'Mixin', 'void');
   }
 
-  test_shadowing_setter_over_field() =>
+  Future<void> test_shadowing_setter_over_field() =>
       check_shadowing('set x(int value) {}', 'int x;', false);
 
-  test_shadowing_setter_over_getter() =>
+  Future<void> test_shadowing_setter_over_getter() =>
       check_shadowing('set x(int value) {}', 'int get x => null;', false);
 
-  test_shadowing_setter_over_method() =>
+  Future<void> test_shadowing_setter_over_method() =>
       check_shadowing('set x(int value) {}', 'void x() {}', true);
 
-  test_shadowing_setter_over_setter() =>
+  Future<void> test_shadowing_setter_over_setter() =>
       check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
 
-  test_shadowing_superclass_over_interface() async {
+  Future<void> test_shadowing_superclass_over_interface() async {
     addTestSource('''
 class Base {
   void f() {}
@@ -3604,7 +3605,7 @@
     assertSuggestMethod('f', 'Base', 'void');
   }
 
-  test_super() async {
+  Future<void> test_super() async {
     // SimpleIdentifier  MethodInvocation  ExpressionStatement
     addTestSource('''
 class C3 {
@@ -3644,14 +3645,14 @@
     assertNotSuggested('ms3');
   }
 
-  test_SwitchStatement_c() async {
+  Future<void> test_SwitchStatement_c() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {switch(x) {c^}}}');
     await computeSuggestions();
     assertNoSuggestions();
   }
 
-  test_SwitchStatement_case() async {
+  Future<void> test_SwitchStatement_case() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
     await computeSuggestions();
@@ -3661,14 +3662,14 @@
     assertNotSuggested('String');
   }
 
-  test_SwitchStatement_empty() async {
+  Future<void> test_SwitchStatement_empty() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {switch(x) {^}}}');
     await computeSuggestions();
     assertNoSuggestions();
   }
 
-  test_ThisExpression_block() async {
+  Future<void> test_ThisExpression_block() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
         main() { }
@@ -3703,7 +3704,7 @@
     assertNotSuggested('==');
   }
 
-  test_ThisExpression_constructor() async {
+  Future<void> test_ThisExpression_constructor() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
         main() { }
@@ -3738,7 +3739,7 @@
     assertNotSuggested('==');
   }
 
-  test_ThisExpression_constructor_param() async {
+  Future<void> test_ThisExpression_constructor_param() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
         main() { }
@@ -3775,7 +3776,7 @@
     assertNotSuggested('==');
   }
 
-  test_ThisExpression_constructor_param2() async {
+  Future<void> test_ThisExpression_constructor_param2() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
         main() { }
@@ -3811,7 +3812,7 @@
     assertNotSuggested('==');
   }
 
-  test_ThisExpression_constructor_param3() async {
+  Future<void> test_ThisExpression_constructor_param3() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
         main() { }
@@ -3847,7 +3848,7 @@
     assertNotSuggested('==');
   }
 
-  test_ThisExpression_constructor_param4() async {
+  Future<void> test_ThisExpression_constructor_param4() async {
     // SimpleIdentifier  FieldFormalParameter  FormalParameterList
     addTestSource('''
         main() { }
@@ -3883,7 +3884,7 @@
     assertNotSuggested('==');
   }
 
-  test_TopLevelVariableDeclaration_typed_name() async {
+  Future<void> test_TopLevelVariableDeclaration_typed_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     addTestSource('class A {} B ^');
@@ -3891,7 +3892,7 @@
     assertNoSuggestions();
   }
 
-  test_TopLevelVariableDeclaration_untyped_name() async {
+  Future<void> test_TopLevelVariableDeclaration_untyped_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
     addTestSource('class A {} var ^');
@@ -3899,7 +3900,7 @@
     assertNoSuggestions();
   }
 
-  test_TypeArgumentList() async {
+  Future<void> test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
     addSource('/home/test/lib/a.dart', '''
         class C1 {int x;}
@@ -3924,7 +3925,7 @@
     assertNotSuggested('F2');
   }
 
-  test_TypeArgumentList2() async {
+  Future<void> test_TypeArgumentList2() async {
     // TypeName  TypeArgumentList  TypeName
     addSource('/home/test/lib/a.dart', '''
         class C1 {int x;}
@@ -3944,7 +3945,7 @@
     assertNotSuggested('C2');
   }
 
-  test_VariableDeclaration_name() async {
+  Future<void> test_VariableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addSource('/home/test/lib/b.dart', '''
@@ -3960,7 +3961,7 @@
     assertNoSuggestions();
   }
 
-  test_VariableDeclarationList_final() async {
+  Future<void> test_VariableDeclarationList_final() async {
     // VariableDeclarationList  VariableDeclarationStatement  Block
     addTestSource('main() {final ^} class C { }');
     await computeSuggestions();
@@ -3969,7 +3970,7 @@
     assertNotSuggested('==');
   }
 
-  test_VariableDeclarationStatement_RHS() async {
+  Future<void> test_VariableDeclarationStatement_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
     addSource('/home/test/lib/b.dart', '''
@@ -3993,7 +3994,7 @@
     assertNotSuggested('e');
   }
 
-  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+  Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
     // VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
     addSource('/home/test/lib/b.dart', '''
diff --git a/pkg/analyzer_plugin/test/utilities/navigation_test.dart b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
index 2cbf5ae..f704fa7 100644
--- a/pkg/analyzer_plugin/test/utilities/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
@@ -20,7 +20,7 @@
 class NavigationGeneratorTest with ResourceProviderMixin {
   ResolvedUnitResult resolvedUnit = MockResolvedUnitResult(path: 'a.dart');
 
-  test_none() {
+  void test_none() {
     NavigationGenerator generator = NavigationGenerator([]);
     NavigationRequest request =
         DartNavigationRequestImpl(resourceProvider, 0, 100, resolvedUnit);
@@ -28,7 +28,7 @@
     expect(result.notifications, hasLength(1));
   }
 
-  test_normal() {
+  void test_normal() {
     TestContributor contributor = TestContributor();
     NavigationGenerator generator = NavigationGenerator([contributor]);
     NavigationRequest request =
@@ -41,7 +41,7 @@
   /// This tests that we get an error notification for each contributor that
   /// throws an error and that an error in one contributor doesn't prevent other
   /// contributors from being called.
-  test_withException() {
+  void test_withException() {
     TestContributor contributor1 = TestContributor();
     TestContributor contributor2 = TestContributor(throwException: true);
     TestContributor contributor3 = TestContributor();
diff --git a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
index a5e5080..71b6ab1 100644
--- a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
@@ -13,7 +13,7 @@
 
 import '../support/abstract_single_unit.dart';
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SourceRangesTest);
   });
@@ -21,13 +21,13 @@
 
 @reflectiveTest
 class SourceRangesTest extends AbstractSingleUnitTest {
-  test_elementName() async {
+  Future<void> test_elementName() async {
     await resolveTestUnit('class ABC {}');
     Element element = findElement('ABC');
     expect(range.elementName(element), SourceRange(6, 3));
   }
 
-  test_endEnd() async {
+  Future<void> test_endEnd() async {
     await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -36,7 +36,7 @@
     expect(range.endEnd(mainName, mainBody), SourceRange(4, 5));
   }
 
-  test_endLength() async {
+  Future<void> test_endLength() async {
     await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -44,7 +44,7 @@
     expect(range.endLength(mainName, 3), SourceRange(4, 3));
   }
 
-  test_endStart() async {
+  Future<void> test_endStart() async {
     await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -53,13 +53,13 @@
     expect(range.endStart(mainName, mainBody), SourceRange(4, 3));
   }
 
-  test_error() {
+  void test_error() {
     AnalysisError error =
         AnalysisError(null, 10, 5, ParserErrorCode.CONST_CLASS, []);
     expect(range.error(error), SourceRange(10, 5));
   }
 
-  test_node() async {
+  Future<void> test_node() async {
     await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -67,7 +67,7 @@
     expect(range.node(mainName), SourceRange(0, 4));
   }
 
-  test_nodes() async {
+  Future<void> test_nodes() async {
     await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -76,16 +76,16 @@
     expect(range.nodes([mainName, mainBody]), SourceRange(1, 9));
   }
 
-  test_nodes_empty() async {
+  Future<void> test_nodes_empty() async {
     await resolveTestUnit('main() {}');
     expect(range.nodes([]), SourceRange(0, 0));
   }
 
-  test_offsetBy() {
+  void test_offsetBy() {
     expect(range.offsetBy(SourceRange(7, 3), 2), SourceRange(9, 3));
   }
 
-  test_startEnd_nodeNode() async {
+  Future<void> test_startEnd_nodeNode() async {
     await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -94,7 +94,7 @@
     expect(range.startEnd(mainName, mainBody), SourceRange(1, 9));
   }
 
-  test_startLength_node() async {
+  Future<void> test_startLength_node() async {
     await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -102,11 +102,11 @@
     expect(range.startLength(mainName, 10), SourceRange(1, 10));
   }
 
-  test_startOffsetEndOffset() {
+  void test_startOffsetEndOffset() {
     expect(range.startOffsetEndOffset(6, 11), SourceRange(6, 5));
   }
 
-  test_startStart_nodeNode() async {
+  Future<void> test_startStart_nodeNode() async {
     await resolveTestUnit('main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
@@ -115,7 +115,7 @@
     expect(range.startStart(mainName, mainBody), SourceRange(0, 7));
   }
 
-  test_token() async {
+  Future<void> test_token() async {
     await resolveTestUnit(' main() {}');
     FunctionDeclaration mainFunction =
         testUnit.declarations[0] as FunctionDeclaration;
diff --git a/pkg/analyzer_plugin/test/utilities/subscriptions/subscription_manager_test.dart b/pkg/analyzer_plugin/test/utilities/subscriptions/subscription_manager_test.dart
index d5f542f..2e39e8b 100644
--- a/pkg/analyzer_plugin/test/utilities/subscriptions/subscription_manager_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/subscriptions/subscription_manager_test.dart
@@ -19,7 +19,7 @@
   String barPath = '/project/lib/bar.dart';
   String bazPath = '/project/lib/baz.dart';
 
-  test_hasSubscriptionForFile_differentSubscription() {
+  void test_hasSubscriptionForFile_differentSubscription() {
     manager.setSubscriptions({
       AnalysisService.NAVIGATION: [barPath]
     });
@@ -27,7 +27,7 @@
         isFalse);
   }
 
-  test_hasSubscriptionForFile_hasSubscription() {
+  void test_hasSubscriptionForFile_hasSubscription() {
     manager.setSubscriptions({
       AnalysisService.HIGHLIGHTS: [fooPath]
     });
@@ -35,16 +35,16 @@
         isTrue);
   }
 
-  test_hasSubscriptionForFile_noSubscription() {
+  void test_hasSubscriptionForFile_noSubscription() {
     expect(manager.hasSubscriptionForFile(fooPath, AnalysisService.HIGHLIGHTS),
         isFalse);
   }
 
-  test_servicesForFile() {
+  void test_servicesForFile() {
     expect(manager.servicesForFile('/project/lib/test.dart'), hasLength(0));
   }
 
-  test_setSubscriptions() {
+  void test_setSubscriptions() {
     //
     // Set the initial set of subscriptions.
     //
diff --git a/pkg/analyzer_plugin/test/utilities/subscriptions/test_all.dart b/pkg/analyzer_plugin/test/utilities/subscriptions/test_all.dart
index dd3a398..6a2d7c9 100644
--- a/pkg/analyzer_plugin/test/utilities/subscriptions/test_all.dart
+++ b/pkg/analyzer_plugin/test/utilities/subscriptions/test_all.dart
@@ -6,7 +6,7 @@
 
 import 'subscription_manager_test.dart' as subscription_manager_test;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     subscription_manager_test.main();
   }, name: 'subscriptions');
diff --git a/pkg/analyzer_plugin/test/utilities/test_all.dart b/pkg/analyzer_plugin/test/utilities/test_all.dart
index 398c9db..c8c48c0 100644
--- a/pkg/analyzer_plugin/test/utilities/test_all.dart
+++ b/pkg/analyzer_plugin/test/utilities/test_all.dart
@@ -10,7 +10,7 @@
 import 'range_factory_test.dart' as range_factory_test;
 import 'subscriptions/test_all.dart' as subscriptions;
 
-main() {
+void main() {
   defineReflectiveSuite(() {
     analyzer_converter_test.main();
     completion.main();
diff --git a/pkg/analyzer_plugin/test/verify_tests_test.dart b/pkg/analyzer_plugin/test/verify_tests_test.dart
index 5cabcbe..7dabc4f 100644
--- a/pkg/analyzer_plugin/test/verify_tests_test.dart
+++ b/pkg/analyzer_plugin/test/verify_tests_test.dart
@@ -14,7 +14,7 @@
 
 import 'utils/package_root.dart' as package_root;
 
-main() {
+void main() {
   PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
   String packageRoot = provider.pathContext.normalize(package_root.packageRoot);
   String analysisServerPath =
diff --git a/pkg/analyzer_plugin/tool/spec/api.dart b/pkg/analyzer_plugin/tool/spec/api.dart
index 4030771..e96e3ce 100644
--- a/pkg/analyzer_plugin/tool/spec/api.dart
+++ b/pkg/analyzer_plugin/tool/spec/api.dart
@@ -40,7 +40,7 @@
 /// Base class for visiting the API definition.
 abstract class ApiVisitor<T> {
   /// Dispatch the given [type] to the visitor.
-  T visitTypeDecl(TypeDecl type) => type.accept(this) as T;
+  T visitTypeDecl(TypeDecl type) => type.accept(this);
   T visitTypeEnum(TypeEnum typeEnum);
   T visitTypeList(TypeList typeList);
   T visitTypeMap(TypeMap typeMap);
@@ -284,7 +284,7 @@
   TypeDecl(dom.Element html, bool experimental, bool deprecated)
       : super(html, experimental, deprecated);
 
-  accept(ApiVisitor visitor);
+  T accept<T>(ApiVisitor<T> visitor);
 }
 
 /// Description of a named type definition.
@@ -308,7 +308,7 @@
       : super(html, experimental, deprecated);
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeEnum(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeEnum(this);
 }
 
 /// Description of a single allowed value for an enum.
@@ -328,7 +328,7 @@
       : super(html, experimental, false);
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeList(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeList(this);
 }
 
 /// Type of a JSON map.
@@ -346,7 +346,7 @@
       : super(html, experimental, false);
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeMap(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeMap(this);
 }
 
 /// Type of a JSON object with specified fields, some of which may be optional.
@@ -358,7 +358,7 @@
       : super(html, experimental, deprecated);
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeObject(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeObject(this);
 
   /// Return the field with the given [name], or null if there is no such field.
   TypeObjectField getField(String name) {
@@ -398,7 +398,7 @@
   }
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeReference(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeReference(this);
 }
 
 /// A collection of type definitions.
@@ -431,5 +431,5 @@
       : super(html, experimental, false);
 
   @override
-  accept(ApiVisitor visitor) => visitor.visitTypeUnion(this);
+  T accept<T>(ApiVisitor<T> visitor) => visitor.visitTypeUnion(this);
 }
diff --git a/pkg/analyzer_plugin/tool/spec/check_all_test.dart b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
index 4358bc1..f228a3a 100644
--- a/pkg/analyzer_plugin/tool/spec/check_all_test.dart
+++ b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
@@ -11,7 +11,7 @@
 
 /// Check that all targets have been code generated. If they haven't tell the
 /// user to run generate_all.dart.
-main() async {
+Future<void> main() async {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
   List<String> components = split(script);
   int index = components.indexOf('analyzer_plugin');
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
index ff717bd..7b76e20 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
@@ -662,7 +662,7 @@
       if (type == null) {
         writeln('return ${className.hashCode};');
       } else {
-        writeln('int hash = 0;');
+        writeln('var hash = 0;');
         for (TypeObjectField field in type.fields) {
           String valueToCombine;
           if (field.value != null) {
@@ -830,7 +830,7 @@
     writeln('@override');
     writeln('Map<String, dynamic> toJson() {');
     indent(() {
-      writeln('Map<String, dynamic> result = {};');
+      writeln('var result = <String, dynamic>{};');
       for (TypeObjectField field in type.fields) {
         String fieldNameString = literalString(field.name);
         if (field.value != null) {
@@ -1094,7 +1094,7 @@
   }
 
   @override
-  visitApi() {
+  void visitApi() {
     outputHeader(year: '2017');
     writeln();
     emitImports();
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
index 272cf3e..710dc62 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
@@ -81,7 +81,7 @@
   }
 
   @override
-  visitApi() {
+  void visitApi() {
     outputHeader(year: '2017');
     writeln();
     writeln('/// Convenience methods for running integration tests.');
@@ -141,7 +141,7 @@
   }
 
   @override
-  visitNotification(Notification notification) {
+  void visitNotification(Notification notification) {
     String streamName =
         camelJoin(['on', notification.domainName, notification.event]);
     String className = camelJoin(
@@ -181,7 +181,7 @@
   }
 
   @override
-  visitRequest(Request request) {
+  void visitRequest(Request request) {
     String methodName = camelJoin(['send', request.domainName, request.method]);
     List<String> args = <String>[];
     List<String> optionalArgs = <String>[];
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
index 154c7ab..ccae715 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
@@ -86,7 +86,7 @@
   }
 
   @override
-  visitApi() {
+  void visitApi() {
     outputHeader(year: '2017');
     writeln();
     writeln('/// Matchers for data types defined in the analysis server API.');
@@ -103,7 +103,7 @@
   }
 
   @override
-  visitTypeEnum(TypeEnum typeEnum) {
+  void visitTypeEnum(TypeEnum typeEnum) {
     writeln("MatchesEnum('$context', [");
     indent(() {
       bool commaNeeded = false;
@@ -120,14 +120,14 @@
   }
 
   @override
-  visitTypeList(TypeList typeList) {
+  void visitTypeList(TypeList typeList) {
     write('isListOf(');
     visitTypeDecl(typeList.itemType);
     write(')');
   }
 
   @override
-  visitTypeMap(TypeMap typeMap) {
+  void visitTypeMap(TypeMap typeMap) {
     write('isMapOf(');
     visitTypeDecl(typeMap.keyType);
     write(', ');
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
index 0169912..b41db53 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
@@ -46,7 +46,7 @@
   }
 
   @override
-  visitApi() {
+  void visitApi() {
     outputHeader(year: '2017');
     writeln();
     generateConstants();
diff --git a/pkg/analyzer_plugin/tool/spec/generate_all.dart b/pkg/analyzer_plugin/tool/spec/generate_all.dart
index 8f9d7da..68452ca 100644
--- a/pkg/analyzer_plugin/tool/spec/generate_all.dart
+++ b/pkg/analyzer_plugin/tool/spec/generate_all.dart
@@ -15,7 +15,7 @@
 import 'to_html.dart' as to_html;
 
 /// Generate all targets.
-main() async {
+Future<void> main() async {
   String script = Platform.script.toFilePath(windows: Platform.isWindows);
   String pkgPath = normalize(join(dirname(script), '..', '..'));
   await GeneratedContent.generateAll(pkgPath, allTargets);
diff --git a/pkg/analyzer_plugin/tool/spec/implied_types.dart b/pkg/analyzer_plugin/tool/spec/implied_types.dart
index 80ff4d4..caa1ad5 100644
--- a/pkg/analyzer_plugin/tool/spec/implied_types.dart
+++ b/pkg/analyzer_plugin/tool/spec/implied_types.dart
@@ -53,13 +53,13 @@
   }
 
   @override
-  visitNotification(Notification notification) {
+  void visitNotification(Notification notification) {
     storeType(notification.longEvent, 'params', notification.params,
         'notificationParams', notification);
   }
 
   @override
-  visitRefactoring(Refactoring refactoring) {
+  void visitRefactoring(Refactoring refactoring) {
     String camelKind = camelJoin(refactoring.kind.toLowerCase().split('_'));
     storeType(camelKind, 'feedback', refactoring.feedback,
         'refactoringFeedback', refactoring);
@@ -68,7 +68,7 @@
   }
 
   @override
-  visitRequest(Request request) {
+  void visitRequest(Request request) {
     storeType(
         request.longMethod, 'params', request.params, 'requestParams', request);
     storeType(
@@ -76,7 +76,7 @@
   }
 
   @override
-  visitTypeDefinition(TypeDefinition typeDefinition) {
+  void visitTypeDefinition(TypeDefinition typeDefinition) {
     storeType(typeDefinition.name, null, typeDefinition.type, 'typeDefinition',
         typeDefinition);
   }
diff --git a/pkg/analyzer_plugin/tool/spec/to_html.dart b/pkg/analyzer_plugin/tool/spec/to_html.dart
index 92ffeb3..1983af6 100644
--- a/pkg/analyzer_plugin/tool/spec/to_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/to_html.dart
@@ -536,7 +536,7 @@
   }
 
   @override
-  visitRefactoring(Refactoring refactoring) {
+  void visitRefactoring(Refactoring refactoring) {
     dt('refactoring', () {
       write(refactoring.kind);
     });
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 6412b51..79fd852 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -390,7 +390,9 @@
     if (_closedWorld.nativeData.isNativeMember(_analyzedMember)) {
       // Native methods do not have a body, and we currently just say
       // they return dynamic and may contain all side-effects.
-      _sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+      NativeBehavior nativeBehavior =
+          _closedWorld.nativeData.getNativeMethodBehavior(_analyzedMember);
+      _sideEffectsBuilder.add(nativeBehavior.sideEffects);
       return _types.dynamicType;
     }
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index ae6c452..fa98ea5 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -605,7 +605,6 @@
   DartTypes get _dartTypes => _closedWorld.dartTypes;
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
-  NativeData get _nativeData => _closedWorld.nativeData;
   RuntimeTypesNeed get _rtiNeed => _closedWorld.rtiNeed;
 
   js.Name _call0Name, _call1Name, _call2Name;
@@ -1973,6 +1972,7 @@
     if (!_options.useNewRti) return js.Block.empty();
 
     List<js.Statement> statements = [];
+
     bool addJsObjectRedirections = false;
     ClassEntity jsObjectClass = _commonElements.jsJavaScriptObjectClass;
     InterfaceType jsObjectType = _elementEnvironment.getThisType(jsObjectClass);
@@ -1993,7 +1993,7 @@
         erasedTypes[element] = targetType.typeArguments.length;
       }
 
-      bool isInterop = _nativeData.isJsInteropClass(element);
+      bool isInterop = _classHierarchy.isSubclassOf(element, jsObjectClass);
 
       Iterable<TypeCheck> checks = cls.classChecksNewRti?.checks ?? [];
       Iterable<InterfaceType> supertypes = isInterop
@@ -2026,9 +2026,9 @@
 
     if (addJsObjectRedirections) {
       _classHierarchy
-          .strictSubtypesOf(jsObjectClass)
-          .forEach((ClassEntity subtype) {
-        ruleset.addRedirection(subtype, jsObjectClass);
+          .strictSubclassesOf(jsObjectClass)
+          .forEach((ClassEntity subclass) {
+        ruleset.addRedirection(subclass, jsObjectClass);
       });
     }
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index fa7c20d9..5158656 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -49,7 +49,6 @@
 import '../../js_backend/js_backend.dart'
     show Namer, ConstantEmitter, StringBackedName;
 import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
-import '../../js_backend/native_data.dart' show NativeData;
 import '../../js_backend/runtime_types.dart';
 import '../../js_backend/runtime_types_codegen.dart';
 import '../../js_backend/runtime_types_new.dart'
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index 6308055..4382db5 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -327,6 +327,7 @@
       newBehavior.throwBehavior = behavior.throwBehavior;
       newBehavior.isAllocation = behavior.isAllocation;
       newBehavior.useGvn = behavior.useGvn;
+      newBehavior.sideEffects.add(behavior.sideEffects);
       return newBehavior;
     }
 
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 0e2aa4b..4329315 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -762,8 +762,8 @@
   /// Returns a list of type constraints from the annotations of
   /// [annotationClass].
   /// Returns `null` if no constraints.
-  List _collect(Iterable<String> annotations, TypeLookup lookupType) {
-    var types = null;
+  List<dynamic> _collect(Iterable<String> annotations, TypeLookup lookupType) {
+    List<dynamic> types = null;
     for (String specString in annotations) {
       for (final typeString in specString.split('|')) {
         var type = NativeBehavior._parseType(typeString, lookupType);
@@ -835,6 +835,14 @@
     }
   }
 
+  void _handleSideEffects() {
+    // TODO(sra): We can probably assume DOM getters are idempotent.
+    // TODO(sra): Add an annotation that includes other attributes, for example,
+    // a @Behavior() annotation that supports the same language as JS().
+    _behavior.sideEffects.setDependsOnSomething();
+    _behavior.sideEffects.setAllSideEffects();
+  }
+
   NativeBehavior buildFieldLoadBehavior(
       DartType type,
       Iterable<String> createsAnnotations,
@@ -851,6 +859,7 @@
     _capture(type, isJsInterop);
     _overrideWithAnnotations(
         createsAnnotations, returnsAnnotations, lookupType);
+    _handleSideEffects();
     return _behavior;
   }
 
@@ -859,6 +868,7 @@
     _escape(type, false);
     // We don't override the default behaviour - the annotations apply to
     // loading the field.
+    _handleSideEffects();
     return _behavior;
   }
 
@@ -896,6 +906,8 @@
     }
 
     _overrideWithAnnotations(createAnnotations, returnsAnnotations, lookupType);
+    _handleSideEffects();
+
     return _behavior;
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 3f860c2..a1b208c 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -272,16 +272,17 @@
               interceptedClasses.contains(_commonElements.jsIntClass))) {
         Set<ClassEntity> required;
         for (HInstruction user in node.usedBy) {
-          if (user is! HInvoke) continue;
-          Set<ClassEntity> intercepted = _interceptorData
-              .getInterceptedClassesOn(user.selector.name, _closedWorld);
-          if (intercepted.contains(_commonElements.jsIntClass)) {
-            required ??= {};
-            required.add(_commonElements.jsIntClass);
-          }
-          if (intercepted.contains(_commonElements.jsDoubleClass)) {
-            required ??= {};
-            required.add(_commonElements.jsDoubleClass);
+          if (user is HInvokeDynamic) {
+            Set<ClassEntity> intercepted = _interceptorData
+                .getInterceptedClassesOn(user.selector.name, _closedWorld);
+            if (intercepted.contains(_commonElements.jsIntClass)) {
+              required ??= {};
+              required.add(_commonElements.jsIntClass);
+            }
+            if (intercepted.contains(_commonElements.jsDoubleClass)) {
+              required ??= {};
+              required.add(_commonElements.jsDoubleClass);
+            }
           }
         }
         // Don't modify the result of
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index b0d2411..d5da5f8 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -9,7 +9,6 @@
 import '../elements/names.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
-import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../world.dart' show JClosedWorld;
 import 'logging.dart';
@@ -45,11 +44,12 @@
     instruction.setUseGvn();
   }
 
-  Selector renameToOptimizedSelector(
-      String name, Selector selector, JCommonElements commonElements) {
-    if (selector.name == name) return selector;
-    return new Selector.call(new Name(name, commonElements.interceptorsLibrary),
-        new CallStructure(selector.argumentCount));
+  void redirectSelector(
+      HInvokeDynamic instruction, String name, JCommonElements commonElements) {
+    Selector selector = instruction.selector;
+    if (selector.name == name) return;
+    instruction.selector = Selector.call(
+        Name(name, commonElements.interceptorsLibrary), selector.callStructure);
   }
 
   constant_system.Operation operation() => null;
@@ -786,8 +786,7 @@
         }
         // We can call _tdivFast because the rhs is a 32bit integer
         // and not 0, nor -1.
-        instruction.selector = renameToOptimizedSelector(
-            '_tdivFast', instruction.selector, commonElements);
+        redirectSelector(instruction, '_tdivFast', commonElements);
         if (log != null) {
           registerOptimization(log, instruction, null);
         }
@@ -892,8 +891,7 @@
       // can be GVN'ed.
       clearAllSideEffects(instruction);
       if (isPositive(right, closedWorld)) {
-        instruction.selector = renameToOptimizedSelector(
-            '_shlPositive', instruction.selector, commonElements);
+        redirectSelector(instruction, '_shlPositive', commonElements);
       }
       if (log != null) {
         registerOptimization(log, instruction, null);
@@ -956,21 +954,18 @@
       // can be GVN'ed.
       clearAllSideEffects(instruction);
       if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) {
-        instruction.selector = renameToOptimizedSelector(
-            '_shrBothPositive', instruction.selector, commonElements);
+        redirectSelector(instruction, '_shrBothPositive', commonElements);
         if (log != null) {
           registerOptimization(log, instruction, null);
         }
       } else if (isPositive(left, closedWorld) &&
           right.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
-        instruction.selector = renameToOptimizedSelector(
-            '_shrReceiverPositive', instruction.selector, commonElements);
+        redirectSelector(instruction, '_shrReceiverPositive', commonElements);
         if (log != null) {
           registerOptimization(log, instruction, null);
         }
       } else if (isPositive(right, closedWorld)) {
-        instruction.selector = renameToOptimizedSelector(
-            '_shrOtherPositive', instruction.selector, commonElements);
+        redirectSelector(instruction, '_shrOtherPositive', commonElements);
         if (log != null) {
           registerOptimization(log, instruction, null);
         }
@@ -1337,8 +1332,7 @@
       if (instruction.inputs.last
           .isPositiveInteger(closedWorld.abstractValueDomain)
           .isDefinitelyTrue) {
-        instruction.selector = renameToOptimizedSelector(
-            '_codeUnitAt', instruction.selector, commonElements);
+        redirectSelector(instruction, '_codeUnitAt', commonElements);
       }
       log?.registerCodeUnitAt(instruction);
     }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index cba623c..3cad724 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1243,7 +1243,6 @@
   /// Type of the instruction.
   AbstractValue instructionType;
 
-  Selector get selector => null;
   HInstruction getDartReceiver(JClosedWorld closedWorld) => null;
   bool onlyThrowsNSM() => false;
 
@@ -1760,15 +1759,22 @@
 
 abstract class HInvokeDynamic extends HInvoke {
   final InvokeDynamicSpecializer specializer;
-  @override
-  Selector selector;
+
+  Selector _selector;
   AbstractValue _receiverType;
   final AbstractValue _originalReceiverType;
+
+  // Cached target when non-nullable receiver type and selector determine a
+  // single target. This is in effect a direct call (except for a possible
+  // `null` receiver). The element should only be set if the inputs are correct
+  // for a direct call. These constraints exclude caching a target when the call
+  // needs defaulted arguments, is `noSuchMethod` (legacy), or is a call-through
+  // stub.
   MemberEntity element;
 
   HInvokeDynamic(Selector selector, this._receiverType, this.element,
       List<HInstruction> inputs, bool isIntercepted, AbstractValue resultType)
-      : this.selector = selector,
+      : this._selector = selector,
         this._originalReceiverType = _receiverType,
         specializer = isIntercepted
             ? InvokeDynamicSpecializer.lookupSpecializer(selector)
@@ -1779,6 +1785,13 @@
     isInterceptedCall = isIntercepted;
   }
 
+  Selector get selector => _selector;
+
+  set selector(Selector selector) {
+    _selector = selector;
+    element = null; // Cached element would no longer match new selector.
+  }
+
   AbstractValue get receiverType => _receiverType;
 
   void updateReceiverType(
@@ -1978,7 +1991,6 @@
   /// The class where the call to super is being done.
   final ClassEntity caller;
   final bool isSetter;
-  @override
   final Selector selector;
 
   HInvokeSuper(
@@ -2387,7 +2399,6 @@
 }
 
 abstract class HInvokeBinary extends HInstruction {
-  @override
   final Selector selector;
   HInvokeBinary(
       HInstruction left, HInstruction right, this.selector, AbstractValue type)
@@ -2628,7 +2639,6 @@
 }
 
 abstract class HInvokeUnary extends HInstruction {
-  @override
   final Selector selector;
   HInvokeUnary(HInstruction input, this.selector, type)
       : super(<HInstruction>[input], type) {
@@ -3341,7 +3351,6 @@
 /// The primitive array indexing operation. Note that this instruction
 /// does not throw because we generate the checks explicitly.
 class HIndex extends HInstruction {
-  @override
   final Selector selector;
   HIndex(HInstruction receiver, HInstruction index, this.selector,
       AbstractValue type)
@@ -3384,7 +3393,6 @@
 /// The primitive array assignment operation. Note that this instruction
 /// does not throw because we generate the checks explicitly.
 class HIndexAssign extends HInstruction {
-  @override
   final Selector selector;
   HIndexAssign(AbstractValueDomain domain, HInstruction receiver,
       HInstruction index, HInstruction value, this.selector)
@@ -3810,7 +3818,6 @@
 /// field getter or setter when the receiver might be null. In these cases, the
 /// [selector] and [field] members are assigned.
 class HNullCheck extends HCheck {
-  @override
   Selector selector;
   FieldEntity field;
 
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index d12781c..e19991a 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -123,7 +123,9 @@
   @override
   bool operator ==(other) {
     if (identical(this, other)) return true;
-    return selector == other.selector && receiver == other.receiver;
+    return other is SelectorMask &&
+        selector == other.selector &&
+        receiver == other.receiver;
   }
 
   @override
diff --git a/pkg/dart2js_tools/bin/deobfuscate.dart b/pkg/dart2js_tools/bin/deobfuscate.dart
index df2729f..d6ba837 100644
--- a/pkg/dart2js_tools/bin/deobfuscate.dart
+++ b/pkg/dart2js_tools/bin/deobfuscate.dart
@@ -48,7 +48,7 @@
   try {
     String obfuscatedTrace = new File(args[0]).readAsStringSync();
     String error = extractErrorMessage(obfuscatedTrace);
-    var provider = new CachingFileProvider();
+    var provider = new CachingFileProvider(logger: Logger());
     StackDeobfuscationResult result =
         deobfuscateStack(obfuscatedTrace, provider);
     Frame firstFrame = result.original.frames.first;
diff --git a/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart b/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart
new file mode 100644
index 0000000..29a209e
--- /dev/null
+++ b/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart
@@ -0,0 +1,61 @@
+import 'dart:math' show max;
+import 'package:stack_trace/stack_trace.dart';
+import 'package:dart2js_tools/src/trace.dart';
+import 'package:dart2js_tools/src/name_decoder.dart';
+import 'package:dart2js_tools/src/util.dart';
+import 'package:dart2js_tools/src/trace_decoder.dart';
+
+/// Deobuscates the given [obfuscatedTrace].
+///
+/// This method assumes a stack trace contains URIs normalized to be file URIs.
+/// If for example you obtain a stack from a browser, you may need to preprocess
+/// the stack to map the URI of the JavaScript files to URIs in the local file
+/// system.
+///
+/// For example, a valid input to this method would be:
+///
+///   Error: no such method
+///     at aB.a20 (/usr/local/foo/main.dart.js:71969:32)
+///     at aNk.goV (/usr/local/foo/main.dart.js:72040:52)
+///     at aNk.gfK (/usr/local/foo/main.dart.js:72038:27)
+///     at FE.gtn (/usr/local/foo/main.dart.js:72640:24)
+///     at aBZ.ghN (/usr/local/foo/main.dart.js:72642:24)
+///     at inheritance (/usr/local/foo/main.dart.js:105334:0)
+///     at FE (/usr/local/foo/main.dart.js:5037:18)
+///
+/// Internally this method will read those JavaScript files, search for the
+///  `//# sourceMappingURL=` line at the end, and load the corresponding
+/// source-map file.
+String deobfuscateStackTrace(String obfuscatedTrace) {
+  String error = extractErrorMessage(obfuscatedTrace);
+  var provider = CachingFileProvider();
+  StackDeobfuscationResult result = deobfuscateStack(obfuscatedTrace, provider);
+  Frame firstFrame = result.original.frames.first;
+  String translatedError = (firstFrame.uri.scheme == 'error'
+          ? null
+          : translate(error, provider.mappingFor(firstFrame.uri))) ??
+      '<no error message found>';
+
+  var sb = StringBuffer();
+  sb.writeln(translatedError);
+  maxMemberLengthHelper(int m, Frame f) => max(f.member.length, m);
+  int longest = result.deobfuscated.frames.fold(0, maxMemberLengthHelper);
+  longest = result.original.frames.fold(longest, maxMemberLengthHelper);
+  for (var originalFrame in result.original.frames) {
+    var deobfuscatedFrames = result.frameMap[originalFrame];
+    if (deobfuscatedFrames == null) {
+      var name = originalFrame.member;
+      sb.writeln('    at ${name.padRight(longest)} ${originalFrame.location}');
+    } else {
+      for (var frame in deobfuscatedFrames) {
+        var name = frame.member;
+        // TODO(sigmund): eventually when ddc stops shipping source-maps to the
+        // client, we can start encoding the function name and remove this
+        // workaround.
+        if (name == '<unknown>') name = originalFrame.member;
+        sb.writeln('    at ${name.padRight(longest)} ${frame.location}');
+      }
+    }
+  }
+  return '$sb';
+}
diff --git a/pkg/dart2js_tools/lib/src/dart2js_mapping.dart b/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
index 2ba789c..1bb8cf3 100644
--- a/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
+++ b/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
@@ -31,13 +31,15 @@
     return _frameIndex;
   }
 
-  Dart2jsMapping(this.sourceMap, Map json) {
+  Dart2jsMapping(this.sourceMap, Map json, {Logger logger}) {
     var extensions = json['x_org_dartlang_dart2js'];
     if (extensions == null) return;
     var minifiedNames = extensions['minified_names'];
     if (minifiedNames != null) {
-      _extractMinifedNames(minifiedNames['global'], sourceMap, globalNames);
-      _extractMinifedNames(minifiedNames['instance'], sourceMap, instanceNames);
+      _extractMinifedNames(
+          minifiedNames['global'], sourceMap, globalNames, logger);
+      _extractMinifedNames(
+          minifiedNames['instance'], sourceMap, instanceNames, logger);
     }
     String jsonFrames = extensions['frames'];
     if (jsonFrames != null) {
@@ -74,10 +76,10 @@
 }
 
 const _marker = "\n//# sourceMappingURL=";
-Dart2jsMapping parseMappingFor(Uri uri) {
+Dart2jsMapping parseMappingFor(Uri uri, {Logger logger}) {
   var file = new File.fromUri(uri);
   if (!file.existsSync()) {
-    warn('Error: no such file: $uri');
+    logger?.log('Error: no such file: $uri');
     return null;
   }
   var contents = file.readAsStringSync();
@@ -86,7 +88,7 @@
   if (urlIndex != -1) {
     sourcemapPath = contents.substring(urlIndex + _marker.length).trim();
   } else {
-    warn('Error: source-map url marker not found in $uri\n'
+    logger?.log('Error: source-map url marker not found in $uri\n'
         '       trying $uri.map');
     sourcemapPath = '${uri.pathSegments.last}.map';
   }
@@ -94,11 +96,11 @@
   assert(!sourcemapPath.contains('\n'));
   var sourcemapFile = new File.fromUri(uri.resolve(sourcemapPath));
   if (!sourcemapFile.existsSync()) {
-    warn('Error: no such file: $sourcemapFile');
+    logger?.log('Error: no such file: $sourcemapFile');
     return null;
   }
   var json = jsonDecode(sourcemapFile.readAsStringSync());
-  return new Dart2jsMapping(parseJson(json), json);
+  return new Dart2jsMapping(parseJson(json), json, logger: logger);
 }
 
 class _FrameDecoder implements Iterator<String> {
@@ -149,10 +151,10 @@
 }
 
 _extractMinifedNames(String encodedInput, SingleMapping sourceMap,
-    Map<String, String> minifiedNames) {
+    Map<String, String> minifiedNames, Logger logger) {
   List<String> input = encodedInput.split(',');
   if (input.length % 2 != 0) {
-    warn("expected an even number of entries");
+    logger?.log("Error: expected an even number of entries");
   }
   for (int i = 0; i < input.length; i += 2) {
     String minifiedName = input[i];
diff --git a/pkg/dart2js_tools/lib/src/trace.dart b/pkg/dart2js_tools/lib/src/trace.dart
index ad12d8f..846af16 100644
--- a/pkg/dart2js_tools/lib/src/trace.dart
+++ b/pkg/dart2js_tools/lib/src/trace.dart
@@ -31,7 +31,7 @@
   ///     at <fileName>:<lineNo>
   ///     at <fileName>
   ///
-  factory StackTraceLine.fromText(String text) {
+  factory StackTraceLine.fromText(String text, {Logger logger}) {
     text = text.trim();
     assert(text.startsWith('at '));
     text = text.substring('at '.length);
@@ -43,7 +43,7 @@
         methodName = text.substring(0, nameEnd).trim();
         text = text.substring(nameEnd + 1, endParen).trim();
       } else {
-        warn('Missing left-paren in: $text');
+        logger?.log('Missing left-paren in: $text');
       }
     }
     int lineNo;
@@ -123,13 +123,13 @@
   }
 }
 
-List<StackTraceLine> parseStackTrace(String trace) {
+List<StackTraceLine> parseStackTrace(String trace, {Logger logger}) {
   List<String> lines = trace.split(new RegExp(r'(\r|\n|\r\n)'));
   List<StackTraceLine> jsStackTrace = <StackTraceLine>[];
   for (String line in lines) {
     line = line.trim();
     if (line.startsWith('at ')) {
-      jsStackTrace.add(new StackTraceLine.fromText(line));
+      jsStackTrace.add(new StackTraceLine.fromText(line, logger: logger));
     }
   }
   return jsStackTrace;
diff --git a/pkg/dart2js_tools/lib/src/trace_decoder.dart b/pkg/dart2js_tools/lib/src/trace_decoder.dart
index cae4c22..7ac12aa 100644
--- a/pkg/dart2js_tools/lib/src/trace_decoder.dart
+++ b/pkg/dart2js_tools/lib/src/trace_decoder.dart
@@ -42,7 +42,7 @@
     }
 
     // If there's no column, try using the first column of the line.
-    var column = frame.column ?? 0;
+    var column = frame.column ?? 1;
 
     Dart2jsMapping mapping = provider.mappingFor(frame.uri);
     if (mapping == null) continue;
diff --git a/pkg/dart2js_tools/lib/src/util.dart b/pkg/dart2js_tools/lib/src/util.dart
index a68cf6e..433ac5a 100644
--- a/pkg/dart2js_tools/lib/src/util.dart
+++ b/pkg/dart2js_tools/lib/src/util.dart
@@ -12,6 +12,9 @@
   final Map<Uri, String> _sources = {};
   final Map<Uri, SourceFile> _files = {};
   final Map<Uri, Dart2jsMapping> _mappings = {};
+  final Logger logger;
+
+  CachingFileProvider({this.logger});
 
   String sourcesFor(Uri uri) =>
       _sources[uri] ??= new File.fromUri(uri).readAsStringSync();
@@ -19,7 +22,8 @@
   SourceFile fileFor(Uri uri) =>
       _files[uri] ??= new SourceFile.fromString(sourcesFor(uri));
 
-  Dart2jsMapping mappingFor(Uri uri) => _mappings[uri] ??= parseMappingFor(uri);
+  Dart2jsMapping mappingFor(Uri uri) =>
+      _mappings[uri] ??= parseMappingFor(uri, logger: logger);
 }
 
 /// A provider that converts `http:` URLs to a `file:` URI assuming that all
@@ -43,10 +47,13 @@
   Dart2jsMapping mappingFor(Uri uri) => super.mappingFor(_localize(uri));
 }
 
-warn(String message) {
-  if (_seenMessages.add(message)) {
-    print(message);
+class Logger {
+  Set<String> _seenMessages = new Set<String>();
+  log(String message) {
+    if (_seenMessages.add(message)) {
+      print(message);
+    }
   }
 }
 
-Set<String> _seenMessages = new Set<String>();
+var logger = Logger();
diff --git a/pkg/dart2js_tools/pubspec.yaml b/pkg/dart2js_tools/pubspec.yaml
index 87290a6..294d05f 100644
--- a/pkg/dart2js_tools/pubspec.yaml
+++ b/pkg/dart2js_tools/pubspec.yaml
@@ -7,4 +7,4 @@
   source_maps: ^0.10.7
   stack_trace: ^1.9.3
 environment:
-  sdk: '>=2.0.0 <3.0.0'
+  sdk: '>=2.3.0 <3.0.0'
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index 826290e1..754b221 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -28,6 +28,7 @@
     Kind kind,
     String sourceFile,
     String outputFile,
+    String debugFile,
     String packages,
     List<String> defines,
     bool enableAsserts,
@@ -68,7 +69,7 @@
       print('Generating AOT snapshot.');
     }
     final snapshotResult = await generateAotSnapshot(
-        genSnapshot, kernelFile, snapshotFile, enableAsserts);
+        genSnapshot, kernelFile, snapshotFile, debugFile, enableAsserts);
     if (snapshotResult.exitCode != 0) {
       stderr.writeln(snapshotResult.stdout);
       stderr.writeln(snapshotResult.stderr);
@@ -139,6 +140,9 @@
 Get package locations from the specified file instead of .packages. <path> can be relative or absolute.
 E.g.: dart2native --packages=/tmp/pkgs main.dart
 ''')
+    ..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
+Remove debugging information from the output and save it separately to the specified file. <path> can be relative or absolute.
+''')
     ..addFlag('verbose',
         abbr: 'v', negatable: false, help: 'Show verbose output.');
 
@@ -176,6 +180,9 @@
               Kind.aot: '${sourceWithoutDart}.aot',
               Kind.exe: '${sourceWithoutDart}.exe',
             }[kind]));
+  final debugPath = parsedArgs['save-debugging-info'] != null
+      ? path.canonicalize(path.normalize(parsedArgs['save-debugging-info']))
+      : null;
 
   if (!FileSystemEntity.isFileSync(sourcePath)) {
     stderr.writeln(
@@ -189,6 +196,7 @@
         kind,
         sourcePath,
         outputPath,
+        debugPath,
         parsedArgs['packages'],
         parsedArgs['define'],
         parsedArgs['enable-asserts'],
diff --git a/pkg/dart2native/lib/dart2native.dart b/pkg/dart2native/lib/dart2native.dart
index 7806861..26e146a 100644
--- a/pkg/dart2native/lib/dart2native.dart
+++ b/pkg/dart2native/lib/dart2native.dart
@@ -60,10 +60,13 @@
 }
 
 Future generateAotSnapshot(String genSnapshot, String kernelFile,
-    String snapshotFile, bool enableAsserts) {
+    String snapshotFile, String debugFile, bool enableAsserts) {
   return Process.run(genSnapshot, [
     '--snapshot-kind=app-aot-elf',
     '--elf=${snapshotFile}',
+    if (debugFile != null) '--save-debugging-info=$debugFile',
+    if (debugFile != null) '--dwarf-stack-traces',
+    if (debugFile != null) '--strip',
     if (enableAsserts) '--enable-asserts',
     kernelFile
   ]);
diff --git a/pkg/dartdev/test/command_test.dart b/pkg/dartdev/test/command_test.dart
deleted file mode 100644
index d49fec4..0000000
--- a/pkg/dartdev/test/command_test.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-// TODO(jwren) move the following test utilities to a separate file
-
-// Files that end in _test.dart must have a main method to satisfy the dart2js
-// bots
-void main() {
-  test('empty test for dart2js', () {
-    assert(true == true);
-  });
-}
-
-TestProject project({String mainSrc}) => TestProject(mainSrc: mainSrc);
-
-class TestProject {
-  Directory dir;
-
-  static String get defaultProjectName => 'dartdev_temp';
-
-  String get name => defaultProjectName;
-
-  TestProject({String mainSrc}) {
-    dir = Directory.systemTemp.createTempSync('dartdev');
-    if (mainSrc != null) {
-      file('lib/main.dart', mainSrc);
-    }
-    file('pubspec.yaml', 'name: $name\ndev_dependencies:\n  test: any\n');
-  }
-
-  void file(String name, String contents) {
-    var file = File(path.join(dir.path, name));
-    file.parent.createSync();
-    file.writeAsStringSync(contents);
-  }
-
-  void dispose() {
-    dir.deleteSync(recursive: true);
-  }
-
-  ProcessResult run(String command, [List<String> args]) {
-    var arguments = [
-      path.absolute(path.join(Directory.current.path, 'bin', 'dartdev.dart')),
-      command
-    ];
-    if (args != null && args.isNotEmpty) {
-      arguments.addAll(args);
-    }
-    return Process.runSync(
-      Platform.resolvedExecutable,
-      arguments,
-      workingDirectory: dir.path,
-    );
-  }
-
-  File findFile(String name) {
-    var file = File(path.join(dir.path, name));
-    return file.existsSync() ? file : null;
-  }
-}
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
new file mode 100644
index 0000000..1e6cadd
--- /dev/null
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, 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:dartdev/dartdev.dart';
+import 'package:test/test.dart';
+
+import '../utils.dart';
+
+void main() {
+  group('flag', help);
+}
+
+void help() {
+  TestProject p;
+  tearDown(() => p?.dispose());
+  test('--help', () {
+    p = project();
+
+    var result = p.runSync('--help');
+
+    expect(result.exitCode, 0);
+    expect(result.stdout, contains(DartdevRunner.dartdevDescription));
+    expect(result.stdout, contains('Usage: dartdev <command> [arguments]'));
+    expect(result.stdout, contains('Global options:'));
+    expect(result.stdout, contains('Available commands:'));
+  });
+}
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
new file mode 100644
index 0000000..ce18d50
--- /dev/null
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, 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:test/test.dart';
+
+import '../utils.dart';
+
+void main() {
+  group('format', format);
+}
+
+void format() {
+  TestProject p;
+
+  tearDown(() => p?.dispose());
+
+  test('--help', () {
+    p = project();
+    var result = p.runSync('format', ['--help']);
+    expect(result.exitCode, 0);
+    expect(result.stdout, contains('Format one or more Dart files.'));
+    expect(result.stdout, contains('Usage: dartdev format [arguments]'));
+    expect(
+        result.stdout, contains('Run "dartdev help" to see global options.'));
+  });
+}
diff --git a/pkg/dartdev/test/test_all.dart b/pkg/dartdev/test/test_all.dart
new file mode 100644
index 0000000..9cef9d3
--- /dev/null
+++ b/pkg/dartdev/test/test_all.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, 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:test/test.dart';
+
+import 'commands/flag_test.dart' as flag;
+import 'commands/format_test.dart' as format;
+import 'utils_test.dart' as utils;
+
+main() {
+  group('dartdev', () {
+    flag.main();
+    format.main();
+    utils.main();
+  });
+}
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
new file mode 100644
index 0000000..ac4189a
--- /dev/null
+++ b/pkg/dartdev/test/utils.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+TestProject project({String mainSrc}) => TestProject(mainSrc: mainSrc);
+
+class TestProject {
+  Directory dir;
+
+  static String get defaultProjectName => 'dartdev_temp';
+
+  String get name => defaultProjectName;
+
+  TestProject({String mainSrc}) {
+    dir = Directory.systemTemp.createTempSync('dartdev');
+    if (mainSrc != null) {
+      file('lib/main.dart', mainSrc);
+    }
+    file('pubspec.yaml', 'name: $name\ndev_dependencies:\n  test: any\n');
+  }
+
+  void file(String name, String contents) {
+    var file = File(path.join(dir.path, name));
+    file.parent.createSync();
+    file.writeAsStringSync(contents);
+  }
+
+  void dispose() {
+    dir.deleteSync(recursive: true);
+  }
+
+  ProcessResult runSync(String command, [List<String> args]) {
+    var arguments = [
+      absolutePathToDartdevFile,
+      command,
+    ];
+
+    if (args != null && args.isNotEmpty) {
+      arguments.addAll(args);
+    }
+
+    return Process.runSync(
+      Platform.resolvedExecutable,
+      arguments,
+      workingDirectory: dir.path,
+    );
+  }
+
+  /// The path relative from `Directory.current.path` to `dartdev.dart` is
+  /// different when executing these tests locally versus on the Dart
+  /// buildbots, this if-else captures this change and branches for each case.
+  String get absolutePathToDartdevFile {
+    var dartdevFilePathOnBots = path.absolute(path.join(
+        Directory.current.path, 'pkg', 'dartdev', 'bin', 'dartdev.dart'));
+    if (File(dartdevFilePathOnBots).existsSync()) {
+      return dartdevFilePathOnBots;
+    } else {
+      return path
+          .absolute(path.join(Directory.current.path, 'bin', 'dartdev.dart'));
+    }
+  }
+
+  File findFile(String name) {
+    var file = File(path.join(dir.path, name));
+    return file.existsSync() ? file : null;
+  }
+}
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index 04e102a..334a785 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -80,10 +80,6 @@
       _unsupportedOption(includeFixOption);
       return false;
     }
-    if (options.requiredFixes) {
-      _unsupportedOption(requiredOption);
-      return false;
-    }
     if (options.showHelp) {
       return false;
     }
@@ -116,7 +112,6 @@
     Options options, {
     Progress progress,
   }) async {
-    logger.trace('Requesting fixes');
     Future isAnalysisComplete = handler.analysisComplete();
 
     final params = EditDartfixParams(options.targets);
@@ -126,9 +121,6 @@
     if (options.includeFixes.isNotEmpty) {
       params.includedFixes = options.includeFixes;
     }
-    if (options.requiredFixes) {
-      params.includeRequiredFixes = true;
-    }
     if (options.pedanticFixes) {
       params.includePedanticFixes = true;
     }
@@ -221,16 +213,9 @@
 
     logger.stdout('''
 
-The following fixes are automatically applied unless at least one --$includeFixOption option is specified
-(and --$requiredOption is not specified). They may be individually disabled using --$excludeFixOption.''');
+These fixes can be enabled using --$includeFixOption:''');
 
-    fixes.where((fix) => fix.isRequired).forEach(showFix);
-
-    logger.stdout('''
-
-These fixes are NOT automatically applied, but may be enabled using --$includeFixOption:''');
-
-    fixes.where((fix) => !fix.isRequired).toList()
+    fixes
       ..sort(compareFixes)
       ..forEach(showFix);
 
@@ -280,6 +265,11 @@
       context.exit(0);
     }
 
+    if (options.includeFixes.isEmpty && !options.pedanticFixes) {
+      logger.stdout('No fixes specified.');
+      context.exit(1);
+    }
+
     Future serverStopped;
     try {
       await startServerAnalysis(options);
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index 38b9e46..24a5d37 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -17,30 +17,19 @@
 const pedanticOption = 'pedantic';
 const previewDirOption = 'preview-dir';
 const previewPortOption = 'preview-port';
-const requiredOption = 'required';
 const sdkOption = 'sdk';
 
 const _binaryName = 'dartfix';
 const _colorOption = 'color';
-const _helpOption = 'help';
-
-// options only supported by server 1.22.2 and greater
-const _previewOption = 'preview';
-const _serverSnapshot = 'server';
-const _verboseOption = 'verbose';
-
-// options not supported yet by any server
 const _dependencies = 'migrate-dependencies';
 
-/// Command line options for `dartfix upgrade`.
-class UpgradeOptions {
-  final bool dependencies;
-  final bool preview;
+// options only supported by server 1.22.2 and greater
+const _helpOption = 'help';
+const _previewOption = 'preview';
+const _serverSnapshot = 'server';
 
-  UpgradeOptions._fromCommand(ArgResults results)
-      : dependencies = results[_dependencies] as bool,
-        preview = results[_previewOption] as bool;
-}
+// options not supported yet by any server
+const _verboseOption = 'verbose';
 
 /// Command line options for `dartfix`.
 class Options {
@@ -53,7 +42,6 @@
   final String serverSnapshot;
 
   final bool pedanticFixes;
-  final bool requiredFixes;
   final List<String> includeFixes;
   final List<String> excludeFixes;
 
@@ -69,7 +57,6 @@
         excludeFixes = (results[excludeFixOption] as List ?? []).cast<String>(),
         overwrite = results[overwriteOption] as bool,
         pedanticFixes = results[pedanticOption] as bool,
-        requiredFixes = results[requiredOption] as bool,
         sdkPath = results[sdkOption] as String ?? _getSdkPath(),
         serverSnapshot = results[_serverSnapshot] as String,
         showHelp = results[_helpOption] as bool || results.arguments.isEmpty,
@@ -97,8 +84,6 @@
           help: 'Exclude a specific fix.', valueHelp: 'name-of-fix')
       ..addFlag(pedanticOption,
           help: 'Apply pedantic fixes.', defaultsTo: false, negatable: false)
-      ..addFlag(requiredOption,
-          help: 'Apply required fixes.', defaultsTo: false, negatable: false)
       ..addSeparator('Modifying files:')
       ..addFlag(overwriteOption,
           abbr: 'w',
@@ -211,10 +196,6 @@
               logger.stderr('Cannot use pedanticFixes when using upgrade.');
               context.exit(22);
             }
-            if (results.wasParsed(requiredOption) && options.requiredFixes) {
-              logger.stderr('Cannot use requiredFixes when using upgrade.');
-              context.exit(22);
-            }
             // TODO(jcollins-g): prevent non-nullable outside of upgrade
             // command.
             options.includeFixes.add('non-nullable');
@@ -284,3 +265,13 @@
         : '');
   }
 }
+
+/// Command line options for `dartfix upgrade`.
+class UpgradeOptions {
+  final bool dependencies;
+  final bool preview;
+
+  UpgradeOptions._fromCommand(ArgResults results)
+      : dependencies = results[_dependencies] as bool,
+        preview = results[_previewOption] as bool;
+}
diff --git a/pkg/dartfix/test/src/driver_exclude_test.dart b/pkg/dartfix/test/src/driver_exclude_test.dart
index dbae703..3236efa 100644
--- a/pkg/dartfix/test/src/driver_exclude_test.dart
+++ b/pkg/dartfix/test/src/driver_exclude_test.dart
@@ -9,8 +9,6 @@
 
 import 'test_context.dart';
 
-const _debug = true;
-
 void main() {
   File exampleFile;
   Directory exampleDir;
@@ -27,8 +25,10 @@
     try {
       await driver.start([
         if (_debug) '-v',
+        '--fix',
+        'convert_class_to_mixin',
         '--excludeFix',
-        'use-mixin',
+        'convert_class_to_mixin',
         exampleDir.path,
       ], testContext: testContext, testLogger: testLogger);
     } finally {
@@ -44,3 +44,5 @@
     expect(suggestions, hasLength(0));
   }, timeout: const Timeout(Duration(minutes: 3)));
 }
+
+const _debug = true;
diff --git a/pkg/dartfix/test/src/driver_help_test.dart b/pkg/dartfix/test/src/driver_help_test.dart
index fa0326d..d8a6330 100644
--- a/pkg/dartfix/test/src/driver_help_test.dart
+++ b/pkg/dartfix/test/src/driver_help_test.dart
@@ -28,7 +28,6 @@
     expect(errText, isEmpty);
     expect(outText, contains('--$excludeFixOption'));
     expect(outText, isNot(contains('Use --help to display the fixes')));
-    expect(outText, contains('use-mixin'));
   });
 
   test('help implicit', () async {
@@ -52,6 +51,5 @@
     expect(errText, isEmpty);
     expect(outText, contains('--$excludeFixOption'));
     expect(outText, isNot(contains('Use --help to display the fixes')));
-    expect(outText, contains('use-mixin'));
   });
 }
diff --git a/pkg/dartfix/test/src/driver_include_test.dart b/pkg/dartfix/test/src/driver_include_test.dart
index d2297aa..7079d5d 100644
--- a/pkg/dartfix/test/src/driver_include_test.dart
+++ b/pkg/dartfix/test/src/driver_include_test.dart
@@ -9,8 +9,6 @@
 
 import 'test_context.dart';
 
-const _debug = true;
-
 void main() {
   File exampleFile;
   Directory exampleDir;
@@ -28,7 +26,7 @@
       await driver.start([
         if (_debug) '-v',
         '--fix',
-        'double-to-int',
+        'prefer_int_literals',
         exampleDir.path,
       ], testContext: testContext, testLogger: testLogger);
     } finally {
@@ -45,3 +43,5 @@
     expectHasSuggestion(suggestions, 'Convert to an int literal');
   }, timeout: const Timeout(Duration(minutes: 3)));
 }
+
+const _debug = true;
diff --git a/pkg/dartfix/test/src/driver_prefer_is_empty_test.dart b/pkg/dartfix/test/src/driver_prefer_is_empty_test.dart
index 7f88324..db8b4ad 100644
--- a/pkg/dartfix/test/src/driver_prefer_is_empty_test.dart
+++ b/pkg/dartfix/test/src/driver_prefer_is_empty_test.dart
@@ -6,8 +6,8 @@
 
 void main() {
   defineDriverTests(
-    name: 'prefer-is-empty',
-    options: ['--fix', 'prefer-is-empty'],
+    name: 'prefer_is_empty',
+    options: ['--fix', 'prefer_is_empty'],
     expectedSuggestions: ["Replace with 'isEmpty'"],
   );
 }
diff --git a/pkg/dartfix/test/src/driver_required_test.dart b/pkg/dartfix/test/src/driver_required_test.dart
deleted file mode 100644
index 2d4e115..0000000
--- a/pkg/dartfix/test/src/driver_required_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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 'driver_test.dart' show defineDriverTests;
-
-void main() {
-  defineDriverTests(
-    name: 'required',
-    options: ['--required'],
-    expectedSuggestions: ['Convert MyMixin to a mixin'],
-  );
-}
diff --git a/pkg/dartfix/test/src/driver_test.dart b/pkg/dartfix/test/src/driver_test.dart
index b8e6f8d..667b723 100644
--- a/pkg/dartfix/test/src/driver_test.dart
+++ b/pkg/dartfix/test/src/driver_test.dart
@@ -10,6 +10,22 @@
 
 import 'test_context.dart';
 
+void main() {
+  defineDriverTests(
+    name: 'default',
+    options: [
+      '--fix',
+      'prefer_int_literals',
+      '--fix',
+      'convert_class_to_mixin'
+    ],
+    expectedSuggestions: [
+      'Convert MyMixin to a mixin',
+      'Convert to an int literal',
+    ],
+  );
+}
+
 void defineDriverTests({
   String name,
   List<String> options,
@@ -17,7 +33,7 @@
   bool debug = false,
   bool updateExample = false,
 }) {
-  var fixFileName = 'example_${name.replaceAll('-', '_')}.dart';
+  var fixFileName = 'example_$name.dart';
 
   File exampleFile;
   File exampleFixedFile;
@@ -95,17 +111,6 @@
   });
 }
 
-void main() {
-  defineDriverTests(
-    name: 'default',
-    options: ['--fix', 'double-to-int', '--fix', 'use-mixin'],
-    expectedSuggestions: [
-      'Convert MyMixin to a mixin',
-      'Convert to an int literal',
-    ],
-  );
-}
-
 String replaceLeadingComment(String source) => source.replaceAll(
     '''
 // This file contains code that is modified by running dartfix.
diff --git a/pkg/dartfix/test/src/options_test.dart b/pkg/dartfix/test/src/options_test.dart
index d04faa5..ff91250 100644
--- a/pkg/dartfix/test/src/options_test.dart
+++ b/pkg/dartfix/test/src/options_test.dart
@@ -55,7 +55,6 @@
     }
     expect(options.force, force);
     expect(options.pedanticFixes, pedanticFixes);
-    expect(options.requiredFixes, requiredFixes);
     expect(options.overwrite, overwrite);
     expect(options.serverSnapshot, serverSnapshot);
     expect(options.showHelp, showHelp);
@@ -124,10 +123,6 @@
     parse(['--pedantic', 'foo'], pedanticFixes: true);
   });
 
-  test('required fixes', () {
-    parse(['--required', 'foo'], requiredFixes: true);
-  });
-
   test('server snapshot', () {
     parse(['--server', 'some/path', 'foo'], serverSnapshot: 'some/path');
   });
diff --git a/pkg/dartfix/test/test_all.dart b/pkg/dartfix/test/test_all.dart
index f03ce9c..54dc9ce 100644
--- a/pkg/dartfix/test/test_all.dart
+++ b/pkg/dartfix/test/test_all.dart
@@ -11,7 +11,6 @@
 import 'src/driver_include_test.dart' as driver_include;
 import 'src/driver_pedantic_test.dart' as driver_pedantic;
 import 'src/driver_prefer_is_empty_test.dart' as driver_prefer_is_empty;
-import 'src/driver_required_test.dart' as driver_required;
 import 'src/driver_test.dart' as driver;
 import 'src/options_test.dart' as options_test;
 
@@ -23,7 +22,6 @@
   group('driver', driver_include.main);
   group('driver', driver_pedantic.main);
   group('driver', driver_prefer_is_empty.main);
-  group('driver', driver_required.main);
   group('driver', driver.main);
   group('options', options_test.main);
 }
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 01db3fc..ed8ddc4 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -19,4 +19,6 @@
     - prefer_conditional_assignment
     - prefer_null_aware_operators
     - prefer_single_quotes
+    # Not enforced by pedantic at any version
+    - directives_ordering
     - prefer_typing_uninitialized_variables
diff --git a/pkg/dev_compiler/lib/dev_compiler.dart b/pkg/dev_compiler/lib/dev_compiler.dart
index e0f2bba..ff98a4d 100644
--- a/pkg/dev_compiler/lib/dev_compiler.dart
+++ b/pkg/dev_compiler/lib/dev_compiler.dart
@@ -4,8 +4,8 @@
 
 // The dev_compiler does not have a publishable public API, instead this is
 // intended for other consumers within the Dart SDK.
-export 'src/kernel/target.dart' show DevCompilerTarget;
-export 'src/kernel/compiler.dart' show ProgramCompiler;
-export 'src/kernel/command.dart' show jsProgramToCode;
-export 'src/compiler/shared_command.dart' show SharedCompilerOptions;
 export 'src/compiler/module_builder.dart' show ModuleFormat;
+export 'src/compiler/shared_command.dart' show SharedCompilerOptions;
+export 'src/kernel/command.dart' show jsProgramToCode;
+export 'src/kernel/compiler.dart' show ProgramCompiler;
+export 'src/kernel/target.dart' show DevCompilerTarget;
diff --git a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
index c0ad7a8..2799afd 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
@@ -4,8 +4,8 @@
 
 // TODO(jmesserly): import from its own package
 import '../js_ast/js_ast.dart';
-import 'shared_compiler.dart' show YieldFinder;
 import 'js_names.dart' show TemporaryId;
+import 'shared_compiler.dart' show YieldFinder;
 
 /// A synthetic `let*` node, similar to that found in Scheme.
 ///
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index c6f12d2..d668402 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -4,12 +4,14 @@
 
 import 'dart:async';
 import 'dart:io';
+
 import 'package:args/args.dart';
 import 'package:front_end/src/api_unstable/ddc.dart'
     show InitializedCompilerState, parseExperimentalArguments;
 import 'package:path/path.dart' as p;
-import 'module_builder.dart';
+
 import '../kernel/command.dart' as kernel_compiler;
+import 'module_builder.dart';
 
 // TODO(nshahan) Merge all of this file the locations where they are used in
 // the kernel (only) version of DDC.
@@ -343,16 +345,6 @@
         var shortPath = uri.path
             .replaceAll('/sdk/', '/dart-sdk/')
             .replaceAll('/sdk_nnbd/', '/dart-sdk/');
-        // A multi-root uri starting with a path under `/lib` indicates that
-        // the multi-root is at the root of a package (typically, the
-        // application root package). These should be converted into a
-        // `/packages` path, we do that by stripping the `/lib` prefix and
-        // relying on the `multiRootOutputPath` to be set to the proper
-        // packages dir (so /packages/<package>).
-        if (shortPath.startsWith('/lib') &&
-            multiRootOutputPath.startsWith('/packages')) {
-          shortPath = shortPath.substring(4);
-        }
         var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath";
         multiRootPath = p.url.relative(multiRootPath, from: sourceMapDir);
         return multiRootPath;
@@ -360,6 +352,8 @@
       return sourcePath;
     }
 
+    if (uri.scheme == 'http') return sourcePath;
+
     // Convert to a local file path if it's not.
     sourcePath = sourcePathToUri(p.absolute(p.fromUri(uri))).path;
 
diff --git a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
index bf84e7a..6140225 100644
--- a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
@@ -2,6 +2,8 @@
 // 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_for_file: directives_ordering
+
 library js_ast;
 
 import 'precedence.dart';
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 80014d1..654d5a8 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -10,12 +10,12 @@
 import 'package:build_integration/file_system/multi_root.dart';
 import 'package:cli_util/cli_util.dart' show getSdkPath;
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
+import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart' hide MapEntry;
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/text/ast_to_text.dart' as kernel show Printer;
-import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
 import 'package:path/path.dart' as p;
 import 'package:source_maps/source_maps.dart' show SourceMapBuilder;
 
@@ -26,7 +26,6 @@
 import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
-
 import 'compiler.dart';
 import 'target.dart';
 
@@ -389,10 +388,22 @@
     outFiles.add(File(outPaths.first + '.txt').writeAsString(sb.toString()));
   }
 
-  var compiler = ProgramCompiler(component, result.classHierarchy, options);
+  final importToSummary = Map<Library, Component>.identity();
+  final summaryToModule = Map<Component, String>.identity();
+  for (var i = 0; i < result.inputSummaries.length; i++) {
+    var summary = result.inputSummaries[i];
+    var moduleImport = summaryModules[inputSummaries[i]];
+    for (var l in summary.libraries) {
+      assert(!importToSummary.containsKey(l));
+      importToSummary[l] = summary;
+      summaryToModule[summary] = moduleImport;
+    }
+  }
 
-  var jsModule = compiler.emitModule(
-      compiledLibraries, result.inputSummaries, inputSummaries, summaryModules);
+  var compiler = ProgramCompiler(component, result.classHierarchy, options,
+      importToSummary, summaryToModule);
+
+  var jsModule = compiler.emitModule(compiledLibraries);
 
   // Also the old Analyzer backend had some code to make debugging better when
   // --single-out-file is used, but that option does not appear to be used by
@@ -488,9 +499,10 @@
   var multiRootOutputPath = argResults['multi-root-output-path'] as String;
   var options = SharedCompilerOptions.fromArguments(argResults);
 
-  var compiler =
-      ProgramCompiler(component, hierarchy, options, coreTypes: coreTypes);
-  var jsModule = compiler.emitModule(component, const [], const [], const {});
+  var compiler = ProgramCompiler(
+      component, hierarchy, options, const {}, const {},
+      coreTypes: coreTypes);
+  var jsModule = compiler.emitModule(component);
   var outFiles = <Future>[];
 
   // Also the old Analyzer backend had some code to make debugging better when
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index d012d6b..c4205b1 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -42,10 +42,14 @@
 
   /// Maps a library URI import, that is not in [_libraries], to the
   /// corresponding Kernel summary module we imported it with.
-  final _importToSummary = Map<Library, Component>.identity();
+  ///
+  /// An entry must exist for every reachable component.
+  final Map<Library, Component> _importToSummary;
 
   /// Maps a Kernel summary to the JS import name for the module.
-  final _summaryToModule = Map<Component, String>.identity();
+  ///
+  /// An entry must exist for every reachable component.
+  final Map<Component, String> _summaryToModule;
 
   /// The variable for the current catch clause
   VariableDeclaration _rethrowParameter;
@@ -218,8 +222,12 @@
 
   final NullableInference _nullableInference;
 
-  factory ProgramCompiler(Component component, ClassHierarchy hierarchy,
+  factory ProgramCompiler(
+      Component component,
+      ClassHierarchy hierarchy,
       SharedCompilerOptions options,
+      Map<Library, Component> importToSummary,
+      Map<Component, String> summaryToModule,
       {CoreTypes coreTypes}) {
     coreTypes ??= CoreTypes(component);
     var types = TypeEnvironment(coreTypes, hierarchy);
@@ -229,16 +237,19 @@
     var jsTypeRep = JSTypeRep(types, hierarchy);
     var staticTypeContext = StatefulStaticTypeContext.stacked(types);
     return ProgramCompiler._(
-        coreTypes,
-        coreTypes.index,
-        nativeTypes,
-        constants,
-        types,
-        hierarchy,
-        jsTypeRep,
-        NullableInference(jsTypeRep, staticTypeContext),
-        staticTypeContext,
-        options);
+      coreTypes,
+      coreTypes.index,
+      nativeTypes,
+      constants,
+      types,
+      hierarchy,
+      jsTypeRep,
+      NullableInference(jsTypeRep, staticTypeContext),
+      staticTypeContext,
+      options,
+      importToSummary,
+      summaryToModule,
+    );
   }
 
   ProgramCompiler._(
@@ -251,7 +262,9 @@
       this._typeRep,
       this._nullableInference,
       this._staticTypeContext,
-      this._options)
+      this._options,
+      this._importToSummary,
+      this._summaryToModule)
       : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
         _asyncStreamIteratorClass =
             sdk.getClass('dart:async', 'StreamIterator'),
@@ -288,23 +301,12 @@
   InterfaceType get internalSymbolType =>
       _coreTypes.legacyRawType(_coreTypes.internalSymbolClass);
 
-  js_ast.Program emitModule(Component component, List<Component> summaries,
-      List<Uri> summaryUris, Map<Uri, String> moduleImportForSummary) {
+  js_ast.Program emitModule(Component component) {
     if (moduleItems.isNotEmpty) {
       throw StateError('Can only call emitModule once.');
     }
     _component = component;
 
-    for (var i = 0; i < summaries.length; i++) {
-      var summary = summaries[i];
-      var moduleImport = moduleImportForSummary[summaryUris[i]];
-      for (var l in summary.libraries) {
-        assert(!_importToSummary.containsKey(l));
-        _importToSummary[l] = summary;
-        _summaryToModule[summary] = moduleImport;
-      }
-    }
-
     var libraries = component.libraries;
 
     // Initialize our library variables.
@@ -1015,12 +1017,11 @@
       //   method that adds these type tests (similar to addTypeTests()) because
       //   in the bootstrap ordering the Future class hasn't been defined yet.
       if (_options.enableNullSafety) {
-        // TODO(nshahan) Update FutureOr type tests for NNBD
         var typeParam =
-            TypeParameterType(c.typeParameters[0], Nullability.legacy);
+            TypeParameterType(c.typeParameters[0], Nullability.undetermined);
         var typeT = visitTypeParameterType(typeParam);
         var futureOfT = visitInterfaceType(InterfaceType(
-            _coreTypes.futureClass, Nullability.legacy, [typeParam]));
+            _coreTypes.futureClass, currentLibrary.nonNullable, [typeParam]));
         body.add(js.statement('''
             #.is = function is_FutureOr(o) {
               return #.is(o) || #.is(o);
@@ -1028,14 +1029,14 @@
             ''', [className, typeT, futureOfT]));
         body.add(js.statement('''
             #.as = function as_FutureOr(o) {
-              if (o == null || #.is(o) || #.is(o)) return o;
-              #.castError(o, this, false);
+              if (#.is(o) || #.is(o)) return o;
+              return #.as(o, this, false);
             }
             ''', [className, typeT, futureOfT, runtimeModule]));
         body.add(js.statement('''
             #._check = function check_FutureOr(o) {
-              if (o == null || #.is(o) || #.is(o)) return o;
-              #.castError(o, this, true);
+              if (#.is(o) || #.is(o)) return o;
+              return #.as(o, this, true);
             }
             ''', [className, typeT, futureOfT, runtimeModule]));
         return null;
@@ -2591,11 +2592,12 @@
   js_ast.Expression visitVoidType(VoidType type) => runtimeCall('void');
 
   @override
-  js_ast.Expression visitBottomType(BottomType type) => runtimeCall('bottom');
+  js_ast.Expression visitBottomType(BottomType type) =>
+      _emitNullabilityWrapper(runtimeCall('bottom'), type.nullability);
 
   @override
-  js_ast.Expression visitNeverType(NeverType type) => runtimeCall('Never');
-
+  js_ast.Expression visitNeverType(NeverType type) =>
+      _emitNullabilityWrapper(runtimeCall('Never'), type.nullability);
   @override
   js_ast.Expression visitInterfaceType(InterfaceType type) =>
       _emitInterfaceType(type);
@@ -2653,29 +2655,43 @@
     }
 
     typeRep ??= _emitTopLevelNameNoInterop(type.classNode);
-    if (!emitNullability ||
-        !_options.enableNullSafety ||
-        type == _coreTypes.nullType) {
-      // Avoid emitting the null safety wrapper types when:
-      // * The non-nullable experiment is not enabled.
-      // * This specific InterfaceType is known to be from a context where
-      //   the nullability is meaningless (ie. class A extends B) where B is the
-      //   InterfaceType.
-      // * The InterfaceType is the Null type.
-      // * Emitting non-null constructor calls.
-      return typeRep;
-    }
 
-    switch (type.nullability) {
+    // Avoid emitting the null safety wrapper types when:
+    // * This specific InterfaceType is known to be from a context where
+    //   the nullability is meaningless:
+    //   * `class A extends B {...}` where B is the InterfaceType.
+    //   * Emitting non-null constructor calls.
+    // * The InterfaceType is the Null type.
+    if (!emitNullability || type == _coreTypes.nullType) return typeRep;
+
+    if (type.nullability == Nullability.undetermined) {
+      throw UnsupportedError('Undetermined Nullability');
+    }
+    return _emitNullabilityWrapper(typeRep, type.nullability);
+  }
+
+  /// Wraps [typeRep] in the appropriate wrapper for the given [nullability].
+  ///
+  /// NOTE: This is currently a no-op if the null safety experiment is not
+  /// enabled.
+  ///
+  /// Non-nullable and undetermined nullability will not cause any wrappers to
+  /// be emitted.
+  js_ast.Expression _emitNullabilityWrapper(
+      js_ast.Expression typeRep, Nullability nullability) {
+    // TODO(nshahan) Cleanup this check once it is safe to always emit the
+    // legacy wrapper.
+    if (!_options.enableNullSafety) return typeRep;
+
+    switch (nullability) {
       case Nullability.legacy:
         return runtimeCall('legacy(#)', [typeRep]);
-      case Nullability.nonNullable:
-        // No wrapper for types that are non-nullable.
-        return typeRep;
       case Nullability.nullable:
         return runtimeCall('nullable(#)', [typeRep]);
       default:
-        throw UnsupportedError('Undetermined Nullability');
+        // Do not wrap types that are known to be non-nullable or those that do
+        // not yet have the nullability determined.
+        return typeRep;
     }
   }
 
@@ -2874,20 +2890,9 @@
   js_ast.Expression _emitTypeParameterType(TypeParameterType type,
       {bool emitNullability = true}) {
     var typeParam = _emitTypeParameter(type.parameter);
+    if (!emitNullability) return typeParam;
 
-    // Nullability rules should be synced with _emitInterfaceType.
-    if (!emitNullability || !_options.enableNullSafety) {
-      return typeParam;
-    }
-
-    switch (type.nullability) {
-      case Nullability.legacy:
-        return runtimeCall('legacy(#)', [typeParam]);
-      case Nullability.nullable:
-        return runtimeCall('nullable(#)', [typeParam]);
-      default:
-        return typeParam;
-    }
+    return _emitNullabilityWrapper(typeParam, type.nullability);
   }
 
   js_ast.Identifier _emitTypeParameter(TypeParameter t) =>
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index e1e67a1..949004d 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -4,12 +4,14 @@
 
 import 'dart:collection';
 import 'dart:core' hide MapEntry;
-import 'package:kernel/kernel.dart';
-import 'package:kernel/core_types.dart';
+
 import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/transformations/track_widget_constructor_locations.dart';
+
 import 'constants.dart' show DevCompilerConstantsBackend;
 import 'kernel_helpers.dart';
 
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 85e018a..9abb66c 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -211,8 +211,8 @@
   String requirePath;
   String ddcSdk;
   var archDir = nnbd ? 'ReleaseX64NNBD' : 'ReleaseX64';
-  var sdkRoot = p.dirname(p.dirname(ddcPath));
   if (debug) {
+    var sdkRoot = p.dirname(p.dirname(ddcPath));
     var buildDir = p.join(sdkRoot, Platform.isMacOS ? 'xcodebuild' : 'out');
     dartSdk = p.join(buildDir, archDir, 'dart-sdk');
   }
@@ -262,15 +262,12 @@
   require.config({
     paths: {
         'dart_sdk': '$sdkJsPath/dart_sdk',
-        'browser-source-map-support':
-          '$sdkRoot/third_party/node-source-map-support/browser-source-map-support'
     },
     waitSeconds: 15
   });
-  require(['dart_sdk', 'browser-source-map-support', '$basename'],
-        function(sdk, sm, app) {
+  require(['dart_sdk', '$basename'],
+        function(sdk, app) {
     'use strict';
-    sm.install();
     if ($nnbd) {
       sdk.dart.strictSubtypeChecks($isNnbdStrong);
     }
@@ -292,8 +289,7 @@
       ]);
       if (await process.exitCode != 0) exit(await process.exitCode);
     } else if (node) {
-      var nodePath =
-          '$sdkJsPath:$sdkRoot/third_party/node-source-map-support:$libRoot';
+      var nodePath = '$sdkJsPath:$libRoot';
       var runjs = '''
 let source_maps;
 try {
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 85d3b98..9481d7d 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -93,9 +93,12 @@
   File(librarySpecPath)
       .copySync(p.join(p.dirname(outputDir), p.basename(librarySpecPath)));
 
-  var jsModule = ProgramCompiler(component, compilerResult.classHierarchy,
-          SharedCompilerOptions(moduleName: 'dart_sdk'))
-      .emitModule(component, [], [], {});
+  var jsModule = ProgramCompiler(
+      component,
+      compilerResult.classHierarchy,
+      SharedCompilerOptions(moduleName: 'dart_sdk'),
+      const {},
+      const {}).emitModule(component);
   var moduleFormats = {
     'amd': ModuleFormat.amd,
     'common': ModuleFormat.common,
diff --git a/pkg/dev_compiler/tool/vm_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/vm_nnbd_sdk_error_golden.txt
new file mode 100644
index 0000000..45beed5
--- /dev/null
+++ b/pkg/dev_compiler/tool/vm_nnbd_sdk_error_golden.txt
@@ -0,0 +1,2 @@
+ERROR|STATIC_WARNING|NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER|lib/core/core.dart|3894|7|16|Missing concrete implementations of 'getter Error._stackTrace' and 'setter Error._stackTrace'.
+ERROR|STATIC_WARNING|NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER|lib/core/core.dart|3902|7|18|Missing concrete implementations of 'getter Error._stackTrace' and 'setter Error._stackTrace'.
diff --git a/pkg/dev_compiler/web/stack_trace_mapper.dart b/pkg/dev_compiler/web/stack_trace_mapper.dart
index e4557c3..fa74c34 100644
--- a/pkg/dev_compiler/web/stack_trace_mapper.dart
+++ b/pkg/dev_compiler/web/stack_trace_mapper.dart
@@ -24,11 +24,12 @@
 
 import 'package:js/js.dart';
 import 'package:path/path.dart' as p;
-import 'source_map_stack_trace.dart';
 import 'package:source_maps/source_maps.dart';
 import 'package:source_span/source_span.dart';
 import 'package:stack_trace/stack_trace.dart';
 
+import 'source_map_stack_trace.dart';
+
 typedef void ReadyCallback();
 
 /// Global object DDC uses to see if a stack trace utility has been registered.
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 18f3e8f..ef8ceec 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -112,7 +112,7 @@
   /**
    * Checks whether the expected and actual values are equal (using `==`).
    */
-  static void equals(var expected, var actual, [String reason = ""]) {
+  static void equals(dynamic expected, dynamic actual, [String reason = ""]) {
     if (expected == actual) return;
     String msg = _getMessage(reason);
     if (expected is String && actual is String) {
@@ -129,7 +129,7 @@
   /**
    * Checks whether the actual value is a bool and its value is true.
    */
-  static void isTrue(var actual, [String reason = ""]) {
+  static void isTrue(dynamic actual, [String reason = ""]) {
     if (_identical(actual, true)) return;
     String msg = _getMessage(reason);
     _fail("Expect.isTrue($actual$msg) fails.");
@@ -138,7 +138,7 @@
   /**
    * Checks whether the actual value is a bool and its value is false.
    */
-  static void isFalse(var actual, [String reason = ""]) {
+  static void isFalse(dynamic actual, [String reason = ""]) {
     if (_identical(actual, false)) return;
     String msg = _getMessage(reason);
     _fail("Expect.isFalse($actual$msg) fails.");
@@ -147,7 +147,7 @@
   /**
    * Checks whether [actual] is null.
    */
-  static void isNull(actual, [String reason = ""]) {
+  static void isNull(dynamic actual, [String reason = ""]) {
     if (null == actual) return;
     String msg = _getMessage(reason);
     _fail("Expect.isNull(actual: <$actual>$msg) fails.");
@@ -156,7 +156,7 @@
   /**
    * Checks whether [actual] is not null.
    */
-  static void isNotNull(actual, [String reason = ""]) {
+  static void isNotNull(dynamic actual, [String reason = ""]) {
     if (null != actual) return;
     String msg = _getMessage(reason);
     _fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
@@ -166,7 +166,8 @@
    * Checks whether the expected and actual values are identical
    * (using `identical`).
    */
-  static void identical(var expected, var actual, [String reason = ""]) {
+  static void identical(dynamic expected, dynamic actual,
+      [String reason = ""]) {
     if (_identical(expected, actual)) return;
     String msg = _getMessage(reason);
     if (expected is String && actual is String) {
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 3a500f5..42b36d0 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -57,47 +57,7 @@
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
-import '../fasta_codes.dart'
-    show
-        LocatedMessage,
-        Message,
-        messageExtendsFutureOr,
-        messageExtendsNever,
-        messageExtendsVoid,
-        messageGenericFunctionTypeUsedAsActualTypeArgument,
-        messageImplementsFutureOr,
-        messageImplementsNever,
-        messageImplementsVoid,
-        messagePatchClassOrigin,
-        messagePatchClassTypeVariablesMismatch,
-        messagePatchDeclarationMismatch,
-        messagePatchDeclarationOrigin,
-        noLength,
-        templateGenericFunctionTypeInferredAsActualTypeArgument,
-        templateImplementsRepeated,
-        templateImplementsSuperClass,
-        templateImplicitMixinOverride,
-        templateIncompatibleRedirecteeFunctionType,
-        templateIncorrectTypeArgument,
-        templateIncorrectTypeArgumentInSupertype,
-        templateIncorrectTypeArgumentInSupertypeInferred,
-        templateInterfaceCheck,
-        templateInternalProblemNotFoundIn,
-        templateInvalidTypeVariableVariancePosition,
-        templateInvalidTypeVariableVariancePositionInReturnType,
-        templateMixinApplicationIncompatibleSupertype,
-        templateNamedMixinOverride,
-        templateOverriddenMethodCause,
-        templateOverrideFewerNamedArguments,
-        templateOverrideFewerPositionalArguments,
-        templateOverrideMismatchNamedParameter,
-        templateOverrideMoreRequiredArguments,
-        templateOverrideTypeMismatchParameter,
-        templateOverrideTypeMismatchReturnType,
-        templateOverrideTypeMismatchSetter,
-        templateOverrideTypeVariablesMismatch,
-        templateRedirectingFactoryIncompatibleTypeArgument,
-        templateTypeArgumentMismatch;
+import '../fasta_codes.dart';
 
 import '../kernel/redirecting_factory_body.dart' show getRedirectingFactoryBody;
 
@@ -852,6 +812,15 @@
           positionalParameters: redirecting.positionalParameters,
           namedParameters: redirecting.namedParameters);
     }
+
+    // Check initializers.
+    forEach((String name, Builder builder) {
+      if (builder is FunctionBuilder &&
+          !builder.isAbstract &&
+          builder.formals != null) {
+        library.checkInitializersInFormals(builder.formals);
+      }
+    });
   }
 
   void checkVarianceInField(Field field, TypeEnvironment typeEnvironment,
@@ -1090,6 +1059,7 @@
           types.hierarchy
               .getKernelTypeArgumentsAsInstanceOf(thisType, enclosingClass));
     }
+
     if (declaredFunction?.typeParameters?.length !=
         interfaceFunction?.typeParameters?.length) {
       reportInvalidOverride(
@@ -1130,15 +1100,21 @@
                 interfaceSubstitution.substituteType(interfaceBound);
           }
           DartType computedBound = substitution.substituteType(interfaceBound);
-          if (declaredBound != computedBound) {
+          if (!types
+              .isSameTypeKernel(declaredBound, computedBound)
+              .isSubtypeWhenUsingNullabilities()) {
             reportInvalidOverride(
                 isInterfaceCheck,
                 declaredMember,
-                templateOverrideTypeVariablesMismatch.withArguments(
+                templateOverrideTypeVariablesBoundMismatch.withArguments(
+                    declaredBound,
+                    declaredParameter.name,
                     "${declaredMember.enclosingClass.name}."
                         "${declaredMember.name.name}",
+                    computedBound,
                     "${interfaceMember.enclosingClass.name}."
-                        "${interfaceMember.name.name}"),
+                        "${interfaceMember.name.name}",
+                    library.isNonNullableByDefault),
                 declaredMember.fileOffset,
                 noLength,
                 context: [
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 26f3db3..1d4511b 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -119,7 +119,8 @@
           isConst: isConst,
           isFieldFormal: isInitializingFormal,
           isCovariant: isCovariant,
-          isRequired: isNamedRequired)
+          isRequired: isNamedRequired,
+          hasDeclaredInitializer: hasDeclaredInitializer)
         ..fileOffset = charOffset;
     }
     return variable;
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index e6f973d..8bd7669 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -390,6 +390,7 @@
 
         if (library.isNonNullableByDefault &&
             library.loader.target.performNnbdChecks) {
+          // Required named parameters can't have default values.
           if (formal.isNamedRequired && formal.initializerToken != null) {
             if (library.loader.nnbdStrongMode) {
               library.addProblem(
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 820b4b2..38df523 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -93,8 +93,8 @@
   }
 
   static void recordDependency(Uri uri) {
-    if (uri.scheme != "file") {
-      throw new ArgumentError("Expected a file-URI, but got: '$uri'.");
+    if (uri.scheme != "file" && uri.scheme != "http") {
+      throw new ArgumentError("Expected a file or http URI, but got: '$uri'.");
     }
     CompilerContext context = Zone.current[compilerContextKey];
     if (context != null) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
index 6096e3f..4af16f1 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
@@ -2001,6 +2001,79 @@
 const Template<
         Message Function(
             String name, DartType _type, bool isNonNullableByDefault)>
+    templateNullableOperatorCallError = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""Operator '#name' cannot be called on '#type' because it is potentially null.""",
+        withArguments: _withArgumentsNullableOperatorCallError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeNullableOperatorCallError = const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>(
+  "NullableOperatorCallError",
+  templateNullableOperatorCallError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableOperatorCallError(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeNullableOperatorCallError,
+      message:
+          """Operator '${name}' cannot be called on '${type}' because it is potentially null.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateNullableOperatorCallWarning = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""Operator '#name' is called on '#type' which is potentially null.""",
+        withArguments: _withArgumentsNullableOperatorCallWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeNullableOperatorCallWarning = const Code<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        "NullableOperatorCallWarning", templateNullableOperatorCallWarning,
+        severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsNullableOperatorCallWarning(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeNullableOperatorCallWarning,
+      message:
+          """Operator '${name}' is called on '${type}' which is potentially null.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
     templateNullablePropertyAccessError = const Template<
             Message Function(
                 String name, DartType _type, bool isNonNullableByDefault)>(
@@ -2076,6 +2149,82 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateOptionalNonNullableWithoutInitializerError = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""Optional parameter '#name' should have a default value because its type '#type' doesn't allow null.""",
+        withArguments:
+            _withArgumentsOptionalNonNullableWithoutInitializerError);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeOptionalNonNullableWithoutInitializerError = const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>(
+  "OptionalNonNullableWithoutInitializerError",
+  templateOptionalNonNullableWithoutInitializerError,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOptionalNonNullableWithoutInitializerError(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeOptionalNonNullableWithoutInitializerError,
+      message:
+          """Optional parameter '${name}' should have a default value because its type '${type}' doesn't allow null.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    templateOptionalNonNullableWithoutInitializerWarning = const Template<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""Optional parameter '#name' doesn't have a default value and its type '#type' doesn't allow null.""",
+        withArguments:
+            _withArgumentsOptionalNonNullableWithoutInitializerWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(
+            String name, DartType _type, bool isNonNullableByDefault)>
+    codeOptionalNonNullableWithoutInitializerWarning = const Code<
+            Message Function(
+                String name, DartType _type, bool isNonNullableByDefault)>(
+        "OptionalNonNullableWithoutInitializerWarning",
+        templateOptionalNonNullableWithoutInitializerWarning,
+        severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOptionalNonNullableWithoutInitializerWarning(
+    String name, DartType _type, bool isNonNullableByDefault) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeOptionalNonNullableWithoutInitializerWarning,
+      message:
+          """Optional parameter '${name}' doesn't have a default value and its type '${type}' doesn't allow null.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
         Message Function(String name, String name2, DartType _type,
             DartType _type2, String name3, bool isNonNullableByDefault)>
     templateOverrideTypeMismatchParameter = const Template<
@@ -2229,6 +2378,60 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
+        Message Function(DartType _type, String name, String name2,
+            DartType _type2, String name3, bool isNonNullableByDefault)>
+    templateOverrideTypeVariablesBoundMismatch = const Template<
+            Message Function(DartType _type, String name, String name2,
+                DartType _type2, String name3, bool isNonNullableByDefault)>(
+        messageTemplate:
+            r"""Declared bound '#type' of type variable '#name' of '#name2' doesn't match the bound '#type2' on overridden method '#name3'.""",
+        withArguments: _withArgumentsOverrideTypeVariablesBoundMismatch);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+        Message Function(DartType _type, String name, String name2,
+            DartType _type2, String name3, bool isNonNullableByDefault)>
+    codeOverrideTypeVariablesBoundMismatch = const Code<
+        Message Function(DartType _type, String name, String name2,
+            DartType _type2, String name3, bool isNonNullableByDefault)>(
+  "OverrideTypeVariablesBoundMismatch",
+  templateOverrideTypeVariablesBoundMismatch,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOverrideTypeVariablesBoundMismatch(
+    DartType _type,
+    String name,
+    String name2,
+    DartType _type2,
+    String name3,
+    bool isNonNullableByDefault) {
+  TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+  List<Object> typeParts = labeler.labelType(_type);
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  if (name3.isEmpty) throw 'No name provided';
+  name3 = demangleMixinApplicationName(name3);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  return new Message(codeOverrideTypeVariablesBoundMismatch,
+      message:
+          """Declared bound '${type}' of type variable '${name}' of '${name2}' doesn't match the bound '${type2}' on overridden method '${name3}'.""" +
+              labeler.originMessages,
+      arguments: {
+        'type': _type,
+        'name': name,
+        'name2': name2,
+        'type2': _type2,
+        'name3': name3
+      });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
         Message Function(
             DartType _type, DartType _type2, bool isNonNullableByDefault)>
     templateRedirectingFactoryIncompatibleTypeArgument = const Template<
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 6f48e62..d2a091b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -167,357 +167,260 @@
     ticker.reset();
     entryPoints ??= context.options.inputs;
     return context.runInContext<Component>((CompilerContext c) async {
-      IncrementalCompilerData data = new IncrementalCompilerData();
+      // Initial setup: Load platform, initialize from dill or component etc.
+      UriTranslator uriTranslator = await setupPackagesAndUriTranslator(c);
+      IncrementalCompilerData data =
+          await ensurePlatformAndInitialize(uriTranslator, c);
 
-      bool bypassCache = false;
-      if (!identical(previousPackagesUri, c.options.packagesUriRaw)) {
-        previousPackagesUri = c.options.packagesUriRaw;
-        bypassCache = true;
-      } else if (this.invalidatedUris.contains(c.options.packagesUri)) {
-        bypassCache = true;
-      }
-      hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
-      UriTranslator uriTranslator =
-          await c.options.getUriTranslator(bypassCache: bypassCache);
-      previousPackagesMap = currentPackagesMap;
-      currentPackagesMap = uriTranslator.packages.asMap();
-      ticker.logMs("Read packages file");
-
-      if (dillLoadedData == null) {
-        int bytesLength = 0;
-        if (componentToInitializeFrom != null) {
-          // If initializing from a component it has to include the sdk,
-          // so we explicitly don't load it here.
-          initializeFromComponent(uriTranslator, c, data);
-        } else {
-          List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
-          bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
-          if (initializeFromDillUri != null) {
-            try {
-              bytesLength += await initializeFromDill(uriTranslator, c, data);
-            } catch (e, st) {
-              // We might have loaded x out of y libraries into the component.
-              // To avoid any unforeseen problems start over.
-              bytesLength =
-                  prepareSummary(summaryBytes, uriTranslator, c, data);
-
-              if (e is InvalidKernelVersionError ||
-                  e is PackageChangedError ||
-                  e is CanonicalNameSdkError) {
-                // Don't report any warning.
-              } else {
-                Uri gzInitializedFrom;
-                if (c.options.writeFileOnCrashReport) {
-                  gzInitializedFrom = saveAsGzip(
-                      data.initializationBytes, "initialize_from.dill");
-                  recordTemporaryFileForTesting(gzInitializedFrom);
-                }
-                if (e is CanonicalNameError) {
-                  Message message = gzInitializedFrom != null
-                      ? templateInitializeFromDillNotSelfContained
-                          .withArguments(initializeFromDillUri.toString(),
-                              gzInitializedFrom)
-                      : templateInitializeFromDillNotSelfContainedNoDump
-                          .withArguments(initializeFromDillUri.toString());
-                  dillLoadedData.loader
-                      .addProblem(message, TreeNode.noOffset, 1, null);
-                } else {
-                  // Unknown error: Report problem as such.
-                  Message message = gzInitializedFrom != null
-                      ? templateInitializeFromDillUnknownProblem.withArguments(
-                          initializeFromDillUri.toString(),
-                          "$e",
-                          "$st",
-                          gzInitializedFrom)
-                      : templateInitializeFromDillUnknownProblemNoDump
-                          .withArguments(
-                              initializeFromDillUri.toString(), "$e", "$st");
-                  dillLoadedData.loader
-                      .addProblem(message, TreeNode.noOffset, 1, null);
-                }
-              }
-            }
-          }
-        }
-        appendLibraries(data, bytesLength);
-
-        await dillLoadedData.buildOutlines();
-        userBuilders = <Uri, LibraryBuilder>{};
-        platformBuilders = <LibraryBuilder>[];
-        dillLoadedData.loader.builders.forEach((uri, builder) {
-          if (builder.uri.scheme == "dart") {
-            platformBuilders.add(builder);
-          } else {
-            userBuilders[uri] = builder;
-          }
-        });
-        if (userBuilders.isEmpty) userBuilders = null;
-      }
-      data.initializationBytes = null;
-
+      // Figure out what to keep and what to throw away.
       Set<Uri> invalidatedUris = this.invalidatedUris.toSet();
-
       invalidateNotKeptUserBuilders(invalidatedUris);
+      ReusageResult reusedResult =
+          computeReusedLibraries(invalidatedUris, uriTranslator);
 
+      // Experimental invalidation initialization (e.g. figure out if we can).
+      ExperimentalInvalidation experimentalInvalidation =
+          await initializeExperimentalInvalidation(reusedResult, c);
+      recordRebuildBodiesCountForTesting(
+          experimentalInvalidation?.missingSources?.length ?? 0);
+
+      // Cleanup: After (potentially) removing builders we have stuff to cleanup
+      // to not leak, and we might need to re-create the dill target.
+      cleanupRemovedBuilders(reusedResult, uriTranslator);
+      recreateDillTargetIfPackageWasUpdated(uriTranslator, c);
       ClassHierarchy hierarchy = userCode?.loader?.hierarchy;
-      Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
-      List<LibraryBuilder> directlyInvalidated = new List<LibraryBuilder>();
-      // TODO(jensj): Do something smarter than this.
-      List<bool> invalidatedBecauseOfPackageUpdate = new List<bool>();
-      List<LibraryBuilder> reusedLibraries = computeReusedLibraries(
-          invalidatedUris, uriTranslator,
-          notReused: notReusedLibraries,
-          directlyInvalidated: directlyInvalidated,
-          invalidatedBecauseOfPackageUpdate: invalidatedBecauseOfPackageUpdate);
-
-      bool apiUnchanged = false;
-      Set<LibraryBuilder> rebuildBodies = new Set<LibraryBuilder>();
-      Set<LibraryBuilder> originalNotReusedLibraries;
-      Set<Uri> missingSources = new Set<Uri>();
-      if (useExperimentalInvalidation &&
-          modulesToLoad == null &&
-          directlyInvalidated.isNotEmpty &&
-          invalidatedBecauseOfPackageUpdate.isEmpty) {
-        // Figure out if the file(s) have changed outline, or we can just
-        // rebuild the bodies.
-        apiUnchanged = true;
-        apiUnchangedLoop:
-        for (int i = 0; i < directlyInvalidated.length; i++) {
-          LibraryBuilder builder = directlyInvalidated[i];
-          Iterator<Builder> iterator = builder.iterator;
-          while (iterator.moveNext()) {
-            Builder childBuilder = iterator.current;
-            if (childBuilder.isDuplicate) {
-              apiUnchanged = false;
-              break apiUnchangedLoop;
-            }
-          }
-
-          List<int> previousSource =
-              CompilerContext.current.uriToSource[builder.fileUri].source;
-          if (previousSource == null || previousSource.isEmpty) {
-            apiUnchanged = false;
-            break;
-          }
-          String before = textualOutline(previousSource);
-          if (before == null) {
-            apiUnchanged = false;
-            break;
-          }
-          String now;
-          FileSystemEntity entity =
-              c.options.fileSystem.entityForUri(builder.fileUri);
-          if (await entity.exists()) {
-            now = textualOutline(await entity.readAsBytes());
-          }
-          if (before != now) {
-            apiUnchanged = false;
-            break;
-          }
-          // TODO(jensj): We should only do this when we're sure we're going to
-          // do it!
-          CompilerContext.current.uriToSource.remove(builder.fileUri);
-          missingSources.add(builder.fileUri);
-          LibraryBuilder partOfLibrary = builder.partOfLibrary;
-          if (partOfLibrary != null) {
-            rebuildBodies.add(partOfLibrary);
-          } else {
-            rebuildBodies.add(builder);
-          }
-        }
-
-        if (apiUnchanged) {
-          // TODO(jensj): Check for mixins in a smarter and faster way.
-          apiUnchangedLoop:
-          for (LibraryBuilder builder in notReusedLibraries) {
-            if (missingSources.contains(builder.fileUri)) continue;
-            Library lib = builder.library;
-            for (Class c in lib.classes) {
-              if (!c.isAnonymousMixin && !c.isEliminatedMixin) continue;
-              for (Supertype supertype in c.implementedTypes) {
-                if (missingSources.contains(supertype.classNode.fileUri)) {
-                  // This is probably a mixin from one of the libraries we want
-                  // to rebuild only the body of.
-                  // TODO(jensj): We can probably add this to the rebuildBodies
-                  // list and just rebuild that library too.
-                  // print("Usage of mixin in ${lib.importUri}");
-                  apiUnchanged = false;
-                  continue apiUnchangedLoop;
-                }
-              }
-            }
-          }
-        }
-
-        if (apiUnchanged) {
-          originalNotReusedLibraries = new Set<LibraryBuilder>();
-          Set<Uri> seenUris = new Set<Uri>();
-          for (LibraryBuilder builder in notReusedLibraries) {
-            if (builder.isPart) continue;
-            if (builder.isPatch) continue;
-            if (rebuildBodies.contains(builder)) continue;
-            if (!seenUris.add(builder.uri)) continue;
-            reusedLibraries.add(builder);
-            originalNotReusedLibraries.add(builder);
-          }
-          notReusedLibraries.clear();
-          notReusedLibraries.addAll(rebuildBodies);
-        } else {
-          missingSources.clear();
-          rebuildBodies.clear();
-        }
-      }
-      recordRebuildBodiesCountForTesting(missingSources.length);
-
-      bool removedDillBuilders = false;
-      for (LibraryBuilder builder in notReusedLibraries) {
-        cleanupSourcesForBuilder(
-            builder, uriTranslator, CompilerContext.current.uriToSource);
-        incrementalSerializer?.invalidate(builder.fileUri);
-
-        LibraryBuilder dillBuilder =
-            dillLoadedData.loader.builders.remove(builder.uri);
-        if (dillBuilder != null) {
-          removedDillBuilders = true;
-          userBuilders?.remove(builder.uri);
-        }
-
-        // Remove component problems for libraries we don't reuse.
-        if (remainingComponentProblems.isNotEmpty) {
-          Library lib = builder.library;
-          removeLibraryFromRemainingComponentProblems(lib, uriTranslator);
-        }
-      }
-
-      if (removedDillBuilders) {
-        dillLoadedData.loader.libraries.clear();
-        for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
-          dillLoadedData.loader.libraries.add(builder.library);
-        }
-      }
-
-      if (hasToCheckPackageUris) {
-        // The package file was changed.
-        // Make sure the dill loader is on the same page.
-        DillTarget oldDillLoadedData = dillLoadedData;
-        dillLoadedData =
-            new DillTarget(ticker, uriTranslator, c.options.target);
-        for (DillLibraryBuilder library
-            in oldDillLoadedData.loader.builders.values) {
-          library.loader = dillLoadedData.loader;
-          dillLoadedData.loader.builders[library.uri] = library;
-          if (library.uri.scheme == "dart" && library.uri.path == "core") {
-            dillLoadedData.loader.coreLibrary = library;
-          }
-        }
-        dillLoadedData.loader.first = oldDillLoadedData.loader.first;
-        dillLoadedData.loader.libraries
-            .addAll(oldDillLoadedData.loader.libraries);
-      }
-
-      if (hierarchy != null) {
-        List<Library> removedLibraries = new List<Library>();
-        // TODO(jensj): For now remove all the original from the class hierarchy
-        // to avoid the class hierarchy getting confused.
-        if (originalNotReusedLibraries != null) {
-          for (LibraryBuilder builder in originalNotReusedLibraries) {
-            Library lib = builder.library;
-            removedLibraries.add(lib);
-          }
-        }
-        for (LibraryBuilder builder in notReusedLibraries) {
-          Library lib = builder.library;
-          removedLibraries.add(lib);
-        }
-        hierarchy.applyTreeChanges(removedLibraries, const []);
-      }
-      notReusedLibraries = null;
+      cleanupHierarchy(hierarchy, experimentalInvalidation, reusedResult);
+      List<LibraryBuilder> reusedLibraries = reusedResult.reusedLibraries;
+      reusedResult = null;
 
       if (userCode != null) {
         ticker.logMs("Decided to reuse ${reusedLibraries.length}"
             " of ${userCode.loader.builders.length} libraries");
       }
 
+      // For modular compilation we can be asked to load components and track
+      // which libraries we actually use for the compilation. Set that up now.
       await loadEnsureLoadedComponents(reusedLibraries);
+      resetTrackingOfUsedLibraries(hierarchy);
 
+      // For each computeDelta call we create a new userCode object which needs
+      // to be setup, and in the case of experimental invalidation some of the
+      // builders needs to be patched up.
       KernelTarget userCodeOld = userCode;
-      userCode = new KernelTarget(
-          new HybridFileSystem(
-              new MemoryFileSystem(
-                  new Uri(scheme: "org-dartlang-debug", path: "/")),
-              c.fileSystem),
-          false,
-          dillLoadedData,
-          uriTranslator);
-      userCode.loader.hierarchy = hierarchy;
+      setupNewUserCode(c, uriTranslator, hierarchy, reusedLibraries,
+          experimentalInvalidation, entryPoints.first);
+      Map<LibraryBuilder, List<SourceLibraryBuilder>> rebuildBodiesMap =
+          experimentalInvalidationCreateRebuildBodiesBuilders(
+              experimentalInvalidation, uriTranslator);
+      entryPoints = userCode.setEntryPoints(entryPoints);
+      await userCode.loader.buildOutlines();
+      experimentalInvalidationPatchUpScopes(
+          experimentalInvalidation, rebuildBodiesMap);
 
-      if (trackNeededDillLibraries) {
-        // Reset dill loaders and kernel class hierarchy.
-        for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
-          if (builder is DillLibraryBuilder) {
-            if (builder.isBuiltAndMarked) {
-              // Clear cached calculations in classes which upon calculation can
-              // mark things as needed.
-              for (Builder builder in builder.scope.localMembers) {
-                if (builder is DillClassBuilder) {
-                  builder.supertype = null;
-                  builder.interfaces = null;
-                }
-              }
-              builder.isBuiltAndMarked = false;
-            }
+      // Checkpoint: Build the actual outline.
+      // Note that the [Component] is not the "full" component.
+      // It is a component consisting of all newly compiled libraries and all
+      // libraries loaded from .dill files or directly from components.
+      // Technically, it's the combination of userCode.loader.libraries and
+      // dillLoadedData.loader.libraries.
+      Component componentWithDill = await userCode.buildOutlines();
+
+      if (!outlineOnly) {
+        // Checkpoint: Build the actual bodies.
+        componentWithDill =
+            await userCode.buildComponent(verify: c.options.verify);
+      }
+      hierarchy ??= userCode.loader.hierarchy;
+      recordNonFullComponentForTesting(componentWithDill);
+
+      // Perform actual dill usage tracking.
+      performDillUsageTracking(hierarchy);
+
+      // If we actually got a result we can throw away the old userCode and the
+      // list of invalidated uris.
+      if (componentWithDill != null) {
+        this.invalidatedUris.clear();
+        hasToCheckPackageUris = false;
+        userCodeOld?.loader?.releaseAncillaryResources();
+        userCodeOld = null;
+      }
+
+      // Compute which libraries to output and which (previous) errors/warnings
+      // we have to reissue. In the process do some cleanup too.
+      List<Library> compiledLibraries =
+          new List<Library>.from(userCode.loader.libraries);
+      Map<Uri, Source> uriToSource = componentWithDill?.uriToSource;
+      experimentalCompilationPostCompilePatchup(
+          experimentalInvalidation, compiledLibraries, uriToSource);
+      List<Library> outputLibraries =
+          calculateOutputLibrariesAndIssueLibraryProblems(
+              data.component != null || fullComponent,
+              compiledLibraries,
+              entryPoints,
+              reusedLibraries,
+              hierarchy,
+              uriTranslator,
+              uriToSource,
+              c);
+      List<String> problemsAsJson = reissueComponentProblems(componentWithDill);
+
+      // If we didn't get a result, go back to the previous one so expression
+      // calculation has the potential to work.
+      if (componentWithDill == null) {
+        userCode.loader.builders.clear();
+        userCode = userCodeOld;
+      }
+
+      // Output result.
+      Procedure mainMethod = componentWithDill == null
+          ? data.userLoadedUriMain
+          : componentWithDill.mainMethod;
+      return context.options.target.configureComponent(
+          new Component(libraries: outputLibraries, uriToSource: uriToSource))
+        ..mainMethod = mainMethod
+        ..problemsAsJson = problemsAsJson;
+    });
+  }
+
+  /// Compute which libraries to output and which (previous) errors/warnings we
+  /// have to reissue. In the process do some cleanup too.
+  List<Library> calculateOutputLibrariesAndIssueLibraryProblems(
+      bool fullComponent,
+      List<Library> compiledLibraries,
+      List<Uri> entryPoints,
+      List<LibraryBuilder> reusedLibraries,
+      ClassHierarchy hierarchy,
+      UriTranslator uriTranslator,
+      Map<Uri, Source> uriToSource,
+      CompilerContext c) {
+    List<Library> outputLibraries;
+    Set<Library> allLibraries;
+    if (fullComponent) {
+      outputLibraries = computeTransitiveClosure(compiledLibraries, entryPoints,
+          reusedLibraries, hierarchy, uriTranslator, uriToSource);
+      allLibraries = outputLibraries.toSet();
+      if (!c.options.omitPlatform) {
+        for (int i = 0; i < platformBuilders.length; i++) {
+          Library lib = platformBuilders[i].library;
+          outputLibraries.add(lib);
+        }
+      }
+    } else {
+      outputLibraries = new List<Library>();
+      allLibraries = computeTransitiveClosure(
+              compiledLibraries,
+              entryPoints,
+              reusedLibraries,
+              hierarchy,
+              uriTranslator,
+              uriToSource,
+              outputLibraries)
+          .toSet();
+    }
+
+    reissueLibraryProblems(allLibraries, compiledLibraries);
+    return outputLibraries;
+  }
+
+  /// If doing experimental compilation, make sure [compiledLibraries] and
+  /// [uriToSource] looks as they would have if we hadn't done experimental
+  /// compilation, i.e. before this call [compiledLibraries] might only contain
+  /// the single Library we compiled again, but after this call, it will also
+  /// contain all the libraries that would normally have been recompiled.
+  /// This might be a temporary thing, but we need to figure out if the VM
+  /// can (always) work with only getting the actually rebuild stuff.
+  void experimentalCompilationPostCompilePatchup(
+      ExperimentalInvalidation experimentalInvalidation,
+      List<Library> compiledLibraries,
+      Map<Uri, Source> uriToSource) {
+    if (experimentalInvalidation != null) {
+      // Make sure "compiledLibraries" contains what it would have, had we not
+      // only re-done the bodies, but invalidated everything.
+      experimentalInvalidation.originalNotReusedLibraries
+          .removeAll(experimentalInvalidation.rebuildBodies);
+      for (LibraryBuilder builder
+          in experimentalInvalidation.originalNotReusedLibraries) {
+        compiledLibraries.add(builder.library);
+      }
+
+      // uriToSources are created in the outline stage which we skipped for
+      // some of the libraries.
+      for (Uri uri in experimentalInvalidation.missingSources) {
+        // TODO(jensj): KernelTargets "link" takes some "excludeSource"
+        // setting into account.
+        uriToSource[uri] = CompilerContext.current.uriToSource[uri];
+      }
+    }
+  }
+
+  /// Perform dill usage tracking if asked. Use the marking on dill builders as
+  /// well as the class hierarchy to figure out which dill libraries was
+  /// actually used by the compilation.
+  void performDillUsageTracking(ClassHierarchy hierarchy) {
+    if (trackNeededDillLibraries) {
+      // Which dill builders were built?
+      neededDillLibraries = new Set<Library>();
+      for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
+        if (builder is DillLibraryBuilder) {
+          if (builder.isBuiltAndMarked) {
+            neededDillLibraries.add(builder.library);
           }
         }
+      }
 
-        if (hierarchy is ClosedWorldClassHierarchy) {
-          hierarchy.resetUsed();
+      updateNeededDillLibrariesWithHierarchy(
+          hierarchy, userCode.loader.builderHierarchy);
+    }
+  }
+
+  /// Fill in the replacement maps that describe the replacements that need to
+  /// happen because of experimental invalidation.
+  void experimentalInvalidationFillReplacementMaps(
+      Map<LibraryBuilder, List<SourceLibraryBuilder>> rebuildBodiesMap,
+      Map<LibraryBuilder, Map<String, Builder>> replacementMap,
+      Map<LibraryBuilder, Map<String, Builder>> replacementSettersMap) {
+    for (MapEntry<LibraryBuilder, List<SourceLibraryBuilder>> entry
+        in rebuildBodiesMap.entries) {
+      Map<String, Builder> childReplacementMap = {};
+      Map<String, Builder> childReplacementSettersMap = {};
+      List<SourceLibraryBuilder> builders = rebuildBodiesMap[entry.key];
+      replacementMap[entry.key] = childReplacementMap;
+      replacementSettersMap[entry.key] = childReplacementSettersMap;
+      for (SourceLibraryBuilder builder in builders) {
+        NameIterator iterator = builder.nameIterator;
+        while (iterator.moveNext()) {
+          Builder childBuilder = iterator.current;
+          String name = iterator.name;
+          Map<String, Builder> map;
+          if (childBuilder.isSetter) {
+            map = childReplacementSettersMap;
+          } else {
+            map = childReplacementMap;
+          }
+          assert(
+              !map.containsKey(name),
+              "Unexpected double-entry for $name in ${builder.uri} "
+              "(org from ${entry.key.uri}): $childBuilder and ${map[name]}");
+          map[name] = childBuilder;
         }
       }
+    }
+  }
 
-      // Re-use the libraries we've deemed re-usable.
-      for (LibraryBuilder library in reusedLibraries) {
-        userCode.loader.builders[library.uri] = library;
-        if (library.uri.scheme == "dart" && library.uri.path == "core") {
-          userCode.loader.coreLibrary = library;
-        }
-      }
-
-      // The entry point(s) has to be set first for loader.first to be setup
-      // correctly. If the first one is in the rebuildBodies, we have to add it
-      // from there first.
-      Uri firstEntryPoint = entryPoints.first;
-      Uri firstEntryPointImportUri =
-          userCode.getEntryPointUri(firstEntryPoint, issueProblem: false);
-      bool wasFirstSet = false;
-      for (LibraryBuilder library in rebuildBodies) {
-        if (library.uri == firstEntryPointImportUri) {
-          userCode.loader.read(library.uri, -1,
-              accessor: userCode.loader.first,
-              fileUri: library.fileUri,
-              referencesFrom: library.library);
-          wasFirstSet = true;
-          break;
-        }
-      }
-      if (!wasFirstSet) {
-        userCode.loader.read(firstEntryPointImportUri, -1,
-            accessor: userCode.loader.first,
-            fileUri: firstEntryPointImportUri != firstEntryPoint
-                ? firstEntryPoint
-                : null);
-      }
-      if (userCode.loader.first == null &&
-          userCode.loader.builders[firstEntryPointImportUri] != null) {
-        userCode.loader.first =
-            userCode.loader.builders[firstEntryPointImportUri];
-      }
-
-      // Any builder(s) in [rebuildBodies] should be semi-reused: Create source
-      // builders based on the underlying libraries.
-      // Maps from old library builder to list of new library builder(s).
-      Map<LibraryBuilder, List<SourceLibraryBuilder>> rebuildBodiesMap =
-          new Map<LibraryBuilder, List<SourceLibraryBuilder>>.identity();
-      for (LibraryBuilder library in rebuildBodies) {
+  /// When doing experimental invalidation, we have some builders that needs to
+  /// be rebuild special, namely they have to be [userCode.loader.read] with
+  /// references from the original [Library] for things to work.
+  Map<LibraryBuilder, List<SourceLibraryBuilder>>
+      experimentalInvalidationCreateRebuildBodiesBuilders(
+          ExperimentalInvalidation experimentalInvalidation,
+          UriTranslator uriTranslator) {
+    // Any builder(s) in [rebuildBodies] should be semi-reused: Create source
+    // builders based on the underlying libraries.
+    // Maps from old library builder to list of new library builder(s).
+    Map<LibraryBuilder, List<SourceLibraryBuilder>> rebuildBodiesMap =
+        new Map<LibraryBuilder, List<SourceLibraryBuilder>>.identity();
+    if (experimentalInvalidation != null) {
+      for (LibraryBuilder library in experimentalInvalidation.rebuildBodies) {
         LibraryBuilder newBuilder = userCode.loader.read(library.uri, -1,
             accessor: userCode.loader.first,
             fileUri: library.fileUri,
@@ -540,218 +443,454 @@
           builders.add(newPartBuilder);
         }
       }
+    }
+    return rebuildBodiesMap;
+  }
 
-      entryPoints = userCode.setEntryPoints(entryPoints);
-      if (userCode.loader.first == null &&
-          userCode.loader.builders[entryPoints.first] != null) {
-        userCode.loader.first = userCode.loader.builders[entryPoints.first];
-      }
-
-      // Create builders for the new entries.
-      await userCode.loader.buildOutlines();
-
+  /// When doing experimental invalidation we have to patch up the scopes of the
+  /// the libraries we're not recompiling but should have recompiled if we
+  /// didn't do anything special.
+  void experimentalInvalidationPatchUpScopes(
+      ExperimentalInvalidation experimentalInvalidation,
+      Map<LibraryBuilder, List<SourceLibraryBuilder>> rebuildBodiesMap) {
+    if (experimentalInvalidation != null) {
       // Maps from old library builder to map of new content.
       Map<LibraryBuilder, Map<String, Builder>> replacementMap = {};
+
       // Maps from old library builder to map of new content.
       Map<LibraryBuilder, Map<String, Builder>> replacementSettersMap = {};
-      for (MapEntry<LibraryBuilder, List<SourceLibraryBuilder>> entry
-          in rebuildBodiesMap.entries) {
-        Map<String, Builder> childReplacementMap = {};
-        Map<String, Builder> childReplacementSettersMap = {};
-        List<SourceLibraryBuilder> builders = rebuildBodiesMap[entry.key];
-        replacementMap[entry.key] = childReplacementMap;
-        replacementSettersMap[entry.key] = childReplacementSettersMap;
-        for (SourceLibraryBuilder builder in builders) {
-          NameIterator iterator = builder.nameIterator;
+
+      experimentalInvalidationFillReplacementMaps(
+          rebuildBodiesMap, replacementMap, replacementSettersMap);
+
+      for (LibraryBuilder builder
+          in experimentalInvalidation.originalNotReusedLibraries) {
+        if (builder is SourceLibraryBuilder) {
+          builder.clearExtensionsInScopeCache();
+          for (Import import in builder.imports) {
+            assert(import.importer == builder);
+            List<LibraryBuilder> replacements =
+                rebuildBodiesMap[import.imported];
+            if (replacements != null) {
+              import.imported = replacements.first;
+            }
+            if (import.prefixBuilder?.exportScope != null) {
+              Scope scope = import.prefixBuilder?.exportScope;
+              scope.patchUpScope(replacementMap, replacementSettersMap);
+            }
+          }
+          for (Export export in builder.exports) {
+            assert(export.exporter == builder);
+            List<LibraryBuilder> replacements =
+                rebuildBodiesMap[export.exported];
+
+            if (replacements != null) {
+              export.exported = replacements.first;
+            }
+          }
+          builder.exportScope
+              .patchUpScope(replacementMap, replacementSettersMap);
+          builder.importScope
+              .patchUpScope(replacementMap, replacementSettersMap);
+
+          Iterator<Builder> iterator = builder.iterator;
           while (iterator.moveNext()) {
             Builder childBuilder = iterator.current;
-            String name = iterator.name;
-            Map<String, Builder> map;
-            if (childBuilder.isSetter) {
-              map = childReplacementSettersMap;
-            } else {
-              map = childReplacementMap;
-            }
-            assert(
-                !map.containsKey(name),
-                "Unexpected double-entry for $name in ${builder.uri} "
-                "(org from ${entry.key.uri}): $childBuilder and ${map[name]}");
-            map[name] = childBuilder;
-          }
-        }
-      }
-
-      // We have to reset the import and export scopes and force
-      // re-calculation of those for the libraries we're not recompiling but
-      // should have recompiled if we didn't do special a special
-      // "only-body-change" operation.
-      // We also have to patch up imports and exports to point to the correct
-      // builders, and further more setup the "wrong-way-links" between
-      // exporters and exportees.
-      if (originalNotReusedLibraries != null) {
-        for (LibraryBuilder builder in originalNotReusedLibraries) {
-          if (builder is SourceLibraryBuilder) {
-            builder.clearExtensionsInScopeCache();
-            for (Import import in builder.imports) {
-              assert(import.importer == builder);
-              List<LibraryBuilder> replacements =
-                  rebuildBodiesMap[import.imported];
-              if (replacements != null) {
-                import.imported = replacements.first;
-              }
-              if (import.prefixBuilder?.exportScope != null) {
-                Scope scope = import.prefixBuilder?.exportScope;
-                scope.patchUpScope(replacementMap, replacementSettersMap);
-              }
-            }
-            for (Export export in builder.exports) {
-              assert(export.exporter == builder);
-              List<LibraryBuilder> replacements =
-                  rebuildBodiesMap[export.exported];
-
-              if (replacements != null) {
-                export.exported = replacements.first;
-              }
-            }
-            builder.exportScope
-                .patchUpScope(replacementMap, replacementSettersMap);
-            builder.importScope
-                .patchUpScope(replacementMap, replacementSettersMap);
-
-            Iterator<Builder> iterator = builder.iterator;
-            while (iterator.moveNext()) {
-              Builder childBuilder = iterator.current;
-              if (childBuilder is SourceClassBuilder) {
-                TypeBuilder typeBuilder = childBuilder.supertype;
-                replaceTypeBuilder(
-                    replacementMap, replacementSettersMap, typeBuilder);
-                typeBuilder = childBuilder.mixedInType;
-                replaceTypeBuilder(
-                    replacementMap, replacementSettersMap, typeBuilder);
-                if (childBuilder.onTypes != null) {
-                  for (typeBuilder in childBuilder.onTypes) {
-                    replaceTypeBuilder(
-                        replacementMap, replacementSettersMap, typeBuilder);
-                  }
+            if (childBuilder is SourceClassBuilder) {
+              TypeBuilder typeBuilder = childBuilder.supertype;
+              replaceTypeBuilder(
+                  replacementMap, replacementSettersMap, typeBuilder);
+              typeBuilder = childBuilder.mixedInType;
+              replaceTypeBuilder(
+                  replacementMap, replacementSettersMap, typeBuilder);
+              if (childBuilder.onTypes != null) {
+                for (typeBuilder in childBuilder.onTypes) {
+                  replaceTypeBuilder(
+                      replacementMap, replacementSettersMap, typeBuilder);
                 }
-                if (childBuilder.interfaces != null) {
-                  for (typeBuilder in childBuilder.interfaces) {
-                    replaceTypeBuilder(
-                        replacementMap, replacementSettersMap, typeBuilder);
-                  }
+              }
+              if (childBuilder.interfaces != null) {
+                for (typeBuilder in childBuilder.interfaces) {
+                  replaceTypeBuilder(
+                      replacementMap, replacementSettersMap, typeBuilder);
                 }
               }
             }
-          } else {
-            throw "Currently unsupported";
           }
+        } else {
+          throw "Currently unsupported";
         }
       }
+    }
+  }
 
-      Component componentWithDill = await userCode.buildOutlines();
+  /// Create a new [userCode] object, and add the reused builders to it.
+  void setupNewUserCode(
+      CompilerContext c,
+      UriTranslator uriTranslator,
+      ClassHierarchy hierarchy,
+      List<LibraryBuilder> reusedLibraries,
+      ExperimentalInvalidation experimentalInvalidation,
+      Uri firstEntryPoint) {
+    userCode = new KernelTarget(
+        new HybridFileSystem(
+            new MemoryFileSystem(
+                new Uri(scheme: "org-dartlang-debug", path: "/")),
+            c.fileSystem),
+        false,
+        dillLoadedData,
+        uriTranslator);
+    userCode.loader.hierarchy = hierarchy;
 
-      // This is not the full component. It is the component consisting of all
-      // newly compiled libraries and all libraries loaded from .dill files or
-      // directly from components.
-      // Technically, it's the combination of userCode.loader.libraries and
-      // dillLoadedData.loader.libraries.
-      if (!outlineOnly) {
-        componentWithDill =
-            await userCode.buildComponent(verify: c.options.verify);
+    // Re-use the libraries we've deemed re-usable.
+    for (LibraryBuilder library in reusedLibraries) {
+      userCode.loader.builders[library.uri] = library;
+      if (library.uri.scheme == "dart" && library.uri.path == "core") {
+        userCode.loader.coreLibrary = library;
       }
-      hierarchy ??= userCode.loader.hierarchy;
+    }
 
-      recordNonFullComponentForTesting(componentWithDill);
-      if (trackNeededDillLibraries) {
-        // Which dill builders were built?
-        neededDillLibraries = new Set<Library>();
-        for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
-          if (builder is DillLibraryBuilder) {
-            if (builder.isBuiltAndMarked) {
-              neededDillLibraries.add(builder.library);
+    // The entry point(s) has to be set first for loader.first to be setup
+    // correctly. If the first one is in the rebuildBodies, we have to add it
+    // from there first.
+    Uri firstEntryPointImportUri =
+        userCode.getEntryPointUri(firstEntryPoint, issueProblem: false);
+    bool wasFirstSet = false;
+    if (experimentalInvalidation != null) {
+      for (LibraryBuilder library in experimentalInvalidation.rebuildBodies) {
+        if (library.uri == firstEntryPointImportUri) {
+          userCode.loader.read(library.uri, -1,
+              accessor: userCode.loader.first,
+              fileUri: library.fileUri,
+              referencesFrom: library.library);
+          wasFirstSet = true;
+          break;
+        }
+      }
+    }
+    if (!wasFirstSet) {
+      userCode.loader.read(firstEntryPointImportUri, -1,
+          accessor: userCode.loader.first,
+          fileUri: firstEntryPointImportUri != firstEntryPoint
+              ? firstEntryPoint
+              : null);
+    }
+    if (userCode.loader.first == null &&
+        userCode.loader.builders[firstEntryPointImportUri] != null) {
+      userCode.loader.first =
+          userCode.loader.builders[firstEntryPointImportUri];
+    }
+  }
+
+  /// When tracking used libraries we mark them when we use them. To track
+  /// correctly we have to unmark before the next iteration to not have too much
+  /// marked and therefore incorrectly marked something as used when it is not.
+  void resetTrackingOfUsedLibraries(ClassHierarchy hierarchy) {
+    if (trackNeededDillLibraries) {
+      // Reset dill loaders and kernel class hierarchy.
+      for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
+        if (builder is DillLibraryBuilder) {
+          if (builder.isBuiltAndMarked) {
+            // Clear cached calculations in classes which upon calculation can
+            // mark things as needed.
+            for (Builder builder in builder.scope.localMembers) {
+              if (builder is DillClassBuilder) {
+                builder.supertype = null;
+                builder.interfaces = null;
+              }
             }
+            builder.isBuiltAndMarked = false;
           }
         }
-
-        updateNeededDillLibrariesWithHierarchy(
-            hierarchy, userCode.loader.builderHierarchy);
       }
 
-      if (componentWithDill != null) {
-        this.invalidatedUris.clear();
-        hasToCheckPackageUris = false;
-        userCodeOld?.loader?.releaseAncillaryResources();
-        userCodeOld = null;
+      if (hierarchy is ClosedWorldClassHierarchy) {
+        hierarchy.resetUsed();
       }
+    }
+  }
 
-      List<Library> compiledLibraries =
-          new List<Library>.from(userCode.loader.libraries);
-      Map<Uri, Source> uriToSource = componentWithDill?.uriToSource;
-      if (originalNotReusedLibraries != null) {
-        // Make sure "compiledLibraries" contains what it would have, had we not
-        // only re-done the bodies, but invalidated everything.
-        originalNotReusedLibraries.removeAll(rebuildBodies);
-        for (LibraryBuilder builder in originalNotReusedLibraries) {
-          compiledLibraries.add(builder.library);
+  /// Cleanup the hierarchy to no longer reference libraries that we are
+  /// invalidating (or would normally have invalidated if we hadn't done any
+  /// experimental invalidation).
+  void cleanupHierarchy(
+      ClassHierarchy hierarchy,
+      ExperimentalInvalidation experimentalInvalidation,
+      ReusageResult reusedResult) {
+    if (hierarchy != null) {
+      List<Library> removedLibraries = new List<Library>();
+      // TODO(jensj): For now remove all the original from the class hierarchy
+      // to avoid the class hierarchy getting confused.
+      if (experimentalInvalidation != null) {
+        for (LibraryBuilder builder
+            in experimentalInvalidation.originalNotReusedLibraries) {
+          Library lib = builder.library;
+          removedLibraries.add(lib);
         }
+      }
+      for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
+        Library lib = builder.library;
+        removedLibraries.add(lib);
+      }
+      hierarchy.applyTreeChanges(removedLibraries, const []);
+    }
+  }
 
-        // uriToSources are created in the outline stage which we skipped for
-        // some of the libraries.
-        for (Uri uri in missingSources) {
-          // TODO(jensj): KernelTargets "link" takes some "excludeSource"
-          // setting into account.
-          uriToSource[uri] = CompilerContext.current.uriToSource[uri];
+  /// If the package uris needs to be re-checked the uri translator has changed,
+  /// and the [DillTarget] needs to get the new uri translator. We do that
+  /// by creating a new one.
+  void recreateDillTargetIfPackageWasUpdated(
+      UriTranslator uriTranslator, CompilerContext c) {
+    if (hasToCheckPackageUris) {
+      // The package file was changed.
+      // Make sure the dill loader is on the same page.
+      DillTarget oldDillLoadedData = dillLoadedData;
+      dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
+      for (DillLibraryBuilder library
+          in oldDillLoadedData.loader.builders.values) {
+        library.loader = dillLoadedData.loader;
+        dillLoadedData.loader.builders[library.uri] = library;
+        if (library.uri.scheme == "dart" && library.uri.path == "core") {
+          dillLoadedData.loader.coreLibrary = library;
+        }
+      }
+      dillLoadedData.loader.first = oldDillLoadedData.loader.first;
+      dillLoadedData.loader.libraries
+          .addAll(oldDillLoadedData.loader.libraries);
+    }
+  }
+
+  /// Builders we don't use again should be removed from places like
+  /// uriToSource (used in places for dependency tracking), the incremental
+  /// serializer (they are no longer kept up-to-date) and the DillTarget
+  /// (to avoid leaks).
+  /// We also have to remove any component problems beloning to any such
+  /// no-longer-used library (to avoid re-issuing errors about no longer
+  /// relevant stuff).
+  void cleanupRemovedBuilders(
+      ReusageResult reusedResult, UriTranslator uriTranslator) {
+    bool removedDillBuilders = false;
+    for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
+      cleanupSourcesForBuilder(
+          builder, uriTranslator, CompilerContext.current.uriToSource);
+      incrementalSerializer?.invalidate(builder.fileUri);
+
+      LibraryBuilder dillBuilder =
+          dillLoadedData.loader.builders.remove(builder.uri);
+      if (dillBuilder != null) {
+        removedDillBuilders = true;
+        userBuilders?.remove(builder.uri);
+      }
+
+      // Remove component problems for libraries we don't reuse.
+      if (remainingComponentProblems.isNotEmpty) {
+        Library lib = builder.library;
+        removeLibraryFromRemainingComponentProblems(lib, uriTranslator);
+      }
+    }
+
+    if (removedDillBuilders) {
+      dillLoadedData.loader.libraries.clear();
+      for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
+        dillLoadedData.loader.libraries.add(builder.library);
+      }
+    }
+  }
+
+  /// Figure out if we can (and was asked to) do experimental invalidation.
+  /// Note that this returns (future or) [null] if we're not doing experimental
+  /// invalidation.
+  Future<ExperimentalInvalidation> initializeExperimentalInvalidation(
+      ReusageResult reusedResult, CompilerContext c) async {
+    Set<LibraryBuilder> rebuildBodies;
+    Set<LibraryBuilder> originalNotReusedLibraries;
+    Set<Uri> missingSources;
+
+    if (!useExperimentalInvalidation) return null;
+    if (modulesToLoad != null) return null;
+    if (reusedResult.directlyInvalidated.isEmpty) return null;
+    if (reusedResult.invalidatedBecauseOfPackageUpdate) return null;
+
+    // Figure out if the file(s) have changed outline, or we can just
+    // rebuild the bodies.
+    for (int i = 0; i < reusedResult.directlyInvalidated.length; i++) {
+      LibraryBuilder builder = reusedResult.directlyInvalidated[i];
+      Iterator<Builder> iterator = builder.iterator;
+      while (iterator.moveNext()) {
+        Builder childBuilder = iterator.current;
+        if (childBuilder.isDuplicate) {
+          return null;
         }
       }
 
-      Procedure mainMethod = componentWithDill == null
-          ? data.userLoadedUriMain
-          : componentWithDill.mainMethod;
-
-      List<Library> outputLibraries;
-      Set<Library> allLibraries;
-      if (data.component != null || fullComponent) {
-        outputLibraries = computeTransitiveClosure(
-            compiledLibraries,
-            entryPoints,
-            reusedLibraries,
-            hierarchy,
-            uriTranslator,
-            uriToSource);
-        allLibraries = outputLibraries.toSet();
-        if (!c.options.omitPlatform) {
-          for (int i = 0; i < platformBuilders.length; i++) {
-            Library lib = platformBuilders[i].library;
-            outputLibraries.add(lib);
-          }
-        }
+      List<int> previousSource =
+          CompilerContext.current.uriToSource[builder.fileUri].source;
+      if (previousSource == null || previousSource.isEmpty) {
+        return null;
+      }
+      String before = textualOutline(previousSource);
+      if (before == null) {
+        return null;
+      }
+      String now;
+      FileSystemEntity entity =
+          c.options.fileSystem.entityForUri(builder.fileUri);
+      if (await entity.exists()) {
+        now = textualOutline(await entity.readAsBytes());
+      }
+      if (before != now) {
+        return null;
+      }
+      // TODO(jensj): We should only do this when we're sure we're going to
+      // do it!
+      CompilerContext.current.uriToSource.remove(builder.fileUri);
+      missingSources ??= new Set<Uri>();
+      missingSources.add(builder.fileUri);
+      LibraryBuilder partOfLibrary = builder.partOfLibrary;
+      rebuildBodies ??= new Set<LibraryBuilder>();
+      if (partOfLibrary != null) {
+        rebuildBodies.add(partOfLibrary);
       } else {
-        outputLibraries = new List<Library>();
-        allLibraries = computeTransitiveClosure(
-                compiledLibraries,
-                entryPoints,
-                reusedLibraries,
-                hierarchy,
-                uriTranslator,
-                uriToSource,
-                outputLibraries)
-            .toSet();
+        rebuildBodies.add(builder);
       }
+    }
 
-      List<String> problemsAsJson = reissueComponentProblems(componentWithDill);
-      reissueLibraryProblems(allLibraries, compiledLibraries);
-
-      if (componentWithDill == null) {
-        userCode.loader.builders.clear();
-        userCode = userCodeOld;
+    // TODO(jensj): Check for mixins in a smarter and faster way.
+    for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
+      if (missingSources.contains(builder.fileUri)) {
+        continue;
       }
+      Library lib = builder.library;
+      for (Class c in lib.classes) {
+        if (!c.isAnonymousMixin && !c.isEliminatedMixin) {
+          continue;
+        }
+        for (Supertype supertype in c.implementedTypes) {
+          if (missingSources.contains(supertype.classNode.fileUri)) {
+            // This is probably a mixin from one of the libraries we want
+            // to rebuild only the body of.
+            // TODO(jensj): We can probably add this to the rebuildBodies
+            // list and just rebuild that library too.
+            // print("Usage of mixin in ${lib.importUri}");
+            return null;
+          }
+        }
+      }
+    }
 
-      // This is the incremental component.
-      return context.options.target.configureComponent(
-          new Component(libraries: outputLibraries, uriToSource: uriToSource))
-        ..mainMethod = mainMethod
-        ..problemsAsJson = problemsAsJson;
-    });
+    originalNotReusedLibraries = new Set<LibraryBuilder>();
+    Set<Uri> seenUris = new Set<Uri>();
+    for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
+      if (builder.isPart) continue;
+      if (builder.isPatch) continue;
+      if (rebuildBodies.contains(builder)) continue;
+      if (!seenUris.add(builder.uri)) continue;
+      reusedResult.reusedLibraries.add(builder);
+      originalNotReusedLibraries.add(builder);
+    }
+    reusedResult.notReusedLibraries.clear();
+    reusedResult.notReusedLibraries.addAll(rebuildBodies);
+
+    return new ExperimentalInvalidation(
+        rebuildBodies, originalNotReusedLibraries, missingSources);
+  }
+
+  /// Get UriTranslator, and figure out if the packages file was (potentially)
+  /// changed.
+  Future<UriTranslator> setupPackagesAndUriTranslator(CompilerContext c) async {
+    bool bypassCache = false;
+    if (!identical(previousPackagesUri, c.options.packagesUriRaw)) {
+      previousPackagesUri = c.options.packagesUriRaw;
+      bypassCache = true;
+    } else if (this.invalidatedUris.contains(c.options.packagesUri)) {
+      bypassCache = true;
+    }
+    UriTranslator uriTranslator =
+        await c.options.getUriTranslator(bypassCache: bypassCache);
+    previousPackagesMap = currentPackagesMap;
+    currentPackagesMap = uriTranslator.packages.asMap();
+    // TODO(jensj): We can probably (from the maps above) figure out if anything
+    // changed and only set this to true if it did.
+    hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
+    ticker.logMs("Read packages file");
+    return uriTranslator;
+  }
+
+  /// Load platform and (potentially) initialize from dill,
+  /// or initialize from component.
+  Future<IncrementalCompilerData> ensurePlatformAndInitialize(
+      UriTranslator uriTranslator, CompilerContext c) async {
+    IncrementalCompilerData data = new IncrementalCompilerData();
+    if (dillLoadedData == null) {
+      int bytesLength = 0;
+      if (componentToInitializeFrom != null) {
+        // If initializing from a component it has to include the sdk,
+        // so we explicitly don't load it here.
+        initializeFromComponent(uriTranslator, c, data);
+      } else {
+        List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
+        bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
+        if (initializeFromDillUri != null) {
+          try {
+            bytesLength += await initializeFromDill(uriTranslator, c, data);
+          } catch (e, st) {
+            // We might have loaded x out of y libraries into the component.
+            // To avoid any unforeseen problems start over.
+            bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
+
+            if (e is InvalidKernelVersionError ||
+                e is PackageChangedError ||
+                e is CanonicalNameSdkError) {
+              // Don't report any warning.
+            } else {
+              Uri gzInitializedFrom;
+              if (c.options.writeFileOnCrashReport) {
+                gzInitializedFrom = saveAsGzip(
+                    data.initializationBytes, "initialize_from.dill");
+                recordTemporaryFileForTesting(gzInitializedFrom);
+              }
+              if (e is CanonicalNameError) {
+                Message message = gzInitializedFrom != null
+                    ? templateInitializeFromDillNotSelfContained.withArguments(
+                        initializeFromDillUri.toString(), gzInitializedFrom)
+                    : templateInitializeFromDillNotSelfContainedNoDump
+                        .withArguments(initializeFromDillUri.toString());
+                dillLoadedData.loader
+                    .addProblem(message, TreeNode.noOffset, 1, null);
+              } else {
+                // Unknown error: Report problem as such.
+                Message message = gzInitializedFrom != null
+                    ? templateInitializeFromDillUnknownProblem.withArguments(
+                        initializeFromDillUri.toString(),
+                        "$e",
+                        "$st",
+                        gzInitializedFrom)
+                    : templateInitializeFromDillUnknownProblemNoDump
+                        .withArguments(
+                            initializeFromDillUri.toString(), "$e", "$st");
+                dillLoadedData.loader
+                    .addProblem(message, TreeNode.noOffset, 1, null);
+              }
+            }
+          }
+        }
+      }
+      appendLibraries(data, bytesLength);
+
+      await dillLoadedData.buildOutlines();
+      userBuilders = <Uri, LibraryBuilder>{};
+      platformBuilders = <LibraryBuilder>[];
+      dillLoadedData.loader.builders.forEach((uri, builder) {
+        if (builder.uri.scheme == "dart") {
+          platformBuilders.add(builder);
+        } else {
+          userBuilders[uri] = builder;
+        }
+      });
+      if (userBuilders.isEmpty) userBuilders = null;
+    }
+    data.initializationBytes = null;
+    return data;
   }
 
   void replaceTypeBuilder(
@@ -1340,16 +1479,16 @@
   }
 
   /// Internal method.
-  List<LibraryBuilder> computeReusedLibraries(
-      Set<Uri> invalidatedUris, UriTranslator uriTranslator,
-      {Set<LibraryBuilder> notReused,
-      List<LibraryBuilder> directlyInvalidated,
-      List<bool> invalidatedBecauseOfPackageUpdate}) {
-    List<LibraryBuilder> result = <LibraryBuilder>[];
-    result.addAll(platformBuilders);
+  ReusageResult computeReusedLibraries(
+      Set<Uri> invalidatedUris, UriTranslator uriTranslator) {
+    List<LibraryBuilder> reusedLibraries = <LibraryBuilder>[];
+    reusedLibraries.addAll(platformBuilders);
     if (userCode == null && userBuilders == null) {
-      return result;
+      return new ReusageResult({}, [], false, reusedLibraries);
     }
+    bool invalidatedBecauseOfPackageUpdate = false;
+    List<LibraryBuilder> directlyInvalidated = new List<LibraryBuilder>();
+    Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
 
     // Maps all non-platform LibraryBuilders from their import URI.
     Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
@@ -1375,7 +1514,7 @@
                 currentPackagesMap[packageName])) {
           Uri newFileUri = uriTranslator.translate(importUri, false);
           if (newFileUri != fileUri) {
-            invalidatedBecauseOfPackageUpdate?.add(true);
+            invalidatedBecauseOfPackageUpdate = true;
             return true;
           }
         }
@@ -1386,7 +1525,7 @@
 
     addBuilderAndInvalidateUris(Uri uri, LibraryBuilder libraryBuilder) {
       if (uri.scheme == "dart" && !libraryBuilder.isSynthetic) {
-        result.add(libraryBuilder);
+        reusedLibraries.add(libraryBuilder);
         return;
       }
       builders[uri] = libraryBuilder;
@@ -1425,10 +1564,8 @@
     }
 
     recordInvalidatedImportUrisForTesting(invalidatedImportUris);
-    if (directlyInvalidated != null) {
-      for (Uri uri in invalidatedImportUris) {
-        directlyInvalidated.add(builders[uri]);
-      }
+    for (Uri uri in invalidatedImportUris) {
+      directlyInvalidated.add(builders[uri]);
     }
 
     BuilderGraph graph = new BuilderGraph(builders);
@@ -1464,7 +1601,7 @@
             workList.add(dependency);
           }
         }
-        notReused?.add(current);
+        notReusedLibraries.add(current);
       }
     }
 
@@ -1477,9 +1614,11 @@
       // https://dart-review.googlesource.com/47442 lands.
       if (builder.isPatch) continue;
       if (!seenUris.add(builder.uri)) continue;
-      result.add(builder);
+      reusedLibraries.add(builder);
     }
-    return result;
+
+    return new ReusageResult(notReusedLibraries, directlyInvalidated,
+        invalidatedBecauseOfPackageUpdate, reusedLibraries);
   }
 
   @override
@@ -1531,3 +1670,29 @@
   Component component = null;
   List<int> initializationBytes = null;
 }
+
+class ReusageResult {
+  final Set<LibraryBuilder> notReusedLibraries;
+  final List<LibraryBuilder> directlyInvalidated;
+  final bool invalidatedBecauseOfPackageUpdate;
+  final List<LibraryBuilder> reusedLibraries;
+
+  ReusageResult(this.notReusedLibraries, this.directlyInvalidated,
+      this.invalidatedBecauseOfPackageUpdate, this.reusedLibraries)
+      : assert(notReusedLibraries != null),
+        assert(directlyInvalidated != null),
+        assert(invalidatedBecauseOfPackageUpdate != null),
+        assert(reusedLibraries != null);
+}
+
+class ExperimentalInvalidation {
+  final Set<LibraryBuilder> rebuildBodies;
+  final Set<LibraryBuilder> originalNotReusedLibraries;
+  final Set<Uri> missingSources;
+
+  ExperimentalInvalidation(
+      this.rebuildBodies, this.originalNotReusedLibraries, this.missingSources)
+      : assert(rebuildBodies != null),
+        assert(originalNotReusedLibraries != null),
+        assert(missingSources != null);
+}
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 e6d9ed3..7aba059 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -88,7 +88,7 @@
 import '../messages.dart' as messages show getLocationFromUri;
 
 import '../modifier.dart'
-    show Modifier, constMask, covariantMask, finalMask, lateMask;
+    show Modifier, constMask, covariantMask, finalMask, lateMask, requiredMask;
 
 import '../names.dart' show emptyName, minusName, plusName;
 
@@ -1011,6 +1011,7 @@
           ..fileOffset = body.fileOffset;
       }
     }
+
     resolveRedirectingFactoryTargets();
     finishVariableMetadata();
   }
@@ -1884,11 +1885,14 @@
   /// Helper method to create a [VariableGet] of the [variable] using
   /// [charOffset] as the file offset.
   @override
-  VariableGet createVariableGet(VariableDeclaration variable, int charOffset) {
+  VariableGet createVariableGet(VariableDeclaration variable, int charOffset,
+      {bool forNullGuardedAccess: false}) {
     Object fact =
         typePromoter?.getFactForAccess(variable, functionNestingLevel);
     Object scope = typePromoter?.currentScope;
-    return new VariableGetImpl(variable, fact, scope)..fileOffset = charOffset;
+    return new VariableGetImpl(variable, fact, scope,
+        forNullGuardedAccess: forNullGuardedAccess)
+      ..fileOffset = charOffset;
   }
 
   /// Helper method to create a [ReadOnlyAccessGenerator] on the [variable]
@@ -2304,6 +2308,7 @@
     bool isConst = (currentLocalVariableModifiers & constMask) != 0;
     bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
     bool isLate = (currentLocalVariableModifiers & lateMask) != 0;
+    bool isRequired = (currentLocalVariableModifiers & requiredMask) != 0;
     assert(isConst == (constantContext == ConstantContext.inferred));
     VariableDeclaration variable = new VariableDeclarationImpl(
         identifier.name, functionNestingLevel,
@@ -2312,7 +2317,9 @@
         type: buildDartType(currentLocalVariableType),
         isFinal: isFinal,
         isConst: isConst,
-        isLate: isLate)
+        isLate: isLate,
+        isRequired: isRequired,
+        hasDeclaredInitializer: initializer != null)
       ..fileOffset = identifier.charOffset
       ..fileEqualsOffset = offsetForToken(equalsToken);
     typeInferrer?.assignedVariables?.declare(variable);
@@ -2521,13 +2528,17 @@
     }
   }
 
-  List<VariableDeclaration> buildVariableDeclarations(variableOrExpression) {
+  List<VariableDeclaration> _buildForLoopVariableDeclarations(
+      variableOrExpression) {
     // TODO(ahe): This can be simplified now that we have the events
     // `handleForInitializer...` events.
     if (variableOrExpression is Generator) {
       variableOrExpression = variableOrExpression.buildForEffect();
     }
     if (variableOrExpression is VariableDeclaration) {
+      // Late for loop variables are not supported. An error has already been
+      // reported by the parser.
+      variableOrExpression.isLate = false;
       return <VariableDeclaration>[variableOrExpression];
     } else if (variableOrExpression is Expression) {
       VariableDeclaration variable =
@@ -2543,7 +2554,7 @@
     } else if (variableOrExpression is List<Object>) {
       List<VariableDeclaration> variables = <VariableDeclaration>[];
       for (Object v in variableOrExpression) {
-        variables.addAll(buildVariableDeclarations(v));
+        variables.addAll(_buildForLoopVariableDeclarations(v));
       }
       return variables;
     } else if (variableOrExpression == null) {
@@ -2627,7 +2638,7 @@
 
     transformCollections = true;
     List<VariableDeclaration> variables =
-        buildVariableDeclarations(variableOrExpression);
+        _buildForLoopVariableDeclarations(variableOrExpression);
     Expression condition;
     if (conditionStatement is ExpressionStatement) {
       condition = conditionStatement.expression;
@@ -2692,7 +2703,7 @@
 
     Object variableOrExpression = pop();
     List<VariableDeclaration> variables =
-        buildVariableDeclarations(variableOrExpression);
+        _buildForLoopVariableDeclarations(variableOrExpression);
     exitLocalScope();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
@@ -3235,6 +3246,7 @@
       reportNonNullableModifierError(requiredToken);
     }
     push((covariantToken != null ? covariantMask : 0) |
+        (requiredToken != null ? requiredMask : 0) |
         Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
   }
 
@@ -3291,7 +3303,8 @@
       }
     } else {
       parameter = new FormalParameterBuilder(null, modifiers, type?.builder,
-          name?.name, libraryBuilder, offsetForToken(nameToken), uri);
+          name?.name, libraryBuilder, offsetForToken(nameToken), uri)
+        ..hasDeclaredInitializer = (initializerStart != null);
     }
     VariableDeclaration variable =
         parameter.build(libraryBuilder, functionNestingLevel);
@@ -4660,6 +4673,9 @@
       Token forToken, Token inToken, Object lvalue, Statement body) {
     ForInElements elements = new ForInElements();
     if (lvalue is VariableDeclaration) {
+      // Late for-in variables are not supported. An error has already been
+      // reported by the parser.
+      lvalue.isLate = false;
       elements.explicitVariableDeclaration = lvalue;
       typeInferrer?.assignedVariables?.write(lvalue);
       if (lvalue.isConst) {
@@ -4688,7 +4704,8 @@
             typePromoter?.getFactForAccess(variable, functionNestingLevel);
         TypePromotionScope scope = typePromoter?.currentScope;
         elements.syntheticAssignment = lvalue.buildAssignment(
-            new VariableGetImpl(variable, fact, scope)
+            new VariableGetImpl(variable, fact, scope,
+                forNullGuardedAccess: false)
               ..fileOffset = inToken.offset,
             voidContext: true);
       } else {
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 2f34a5b..6f25949 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -494,10 +494,17 @@
       {bool voidContext = false}) {
     VariableDeclaration variable =
         _helper.forest.createVariableDeclarationForValue(receiver);
-    PropertyGet read = _forest.createPropertyGet(fileOffset,
-        _helper.createVariableGet(variable, receiver.fileOffset), name);
-    PropertySet write = _helper.forest.createPropertySet(fileOffset,
-        _helper.createVariableGet(variable, receiver.fileOffset), name, value,
+    PropertyGet read = _forest.createPropertyGet(
+        fileOffset,
+        _helper.createVariableGet(variable, receiver.fileOffset,
+            forNullGuardedAccess: true),
+        name);
+    PropertySet write = _helper.forest.createPropertySet(
+        fileOffset,
+        _helper.createVariableGet(variable, receiver.fileOffset,
+            forNullGuardedAccess: true),
+        name,
+        value,
         forEffect: voidContext);
     return new IfNullPropertySet(variable, read, write, forEffect: voidContext)
       ..fileOffset = offset;
@@ -726,7 +733,8 @@
         _helper.forest.createVariableDeclarationForValue(receiverExpression);
     PropertyGet read = _forest.createPropertyGet(
         fileOffset,
-        _helper.createVariableGet(variable, receiverExpression.fileOffset),
+        _helper.createVariableGet(variable, receiverExpression.fileOffset,
+            forNullGuardedAccess: true),
         name);
     return new NullAwarePropertyGet(variable, read)
       ..fileOffset = receiverExpression.fileOffset;
@@ -738,7 +746,8 @@
         _helper.forest.createVariableDeclarationForValue(receiverExpression);
     PropertySet read = _helper.forest.createPropertySet(
         fileOffset,
-        _helper.createVariableGet(variable, receiverExpression.fileOffset),
+        _helper.createVariableGet(variable, receiverExpression.fileOffset,
+            forNullGuardedAccess: true),
         name,
         value,
         forEffect: voidContext,
@@ -943,7 +952,8 @@
     Expression receiverValue;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
     } else {
       receiverValue = receiver;
     }
@@ -963,7 +973,8 @@
     bool readOnlyReceiver;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
       readOnlyReceiver = true;
     } else {
       receiverValue = receiver;
@@ -987,7 +998,8 @@
     bool readOnlyReceiver;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
       readOnlyReceiver = true;
     } else {
       receiverValue = receiver;
@@ -1018,7 +1030,8 @@
     bool readOnlyReceiver;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
       readOnlyReceiver = true;
     } else {
       receiverValue = receiver;
@@ -1913,8 +1926,10 @@
     if (isNullAware) {
       VariableDeclaration variable =
           _helper.forest.createVariableDeclarationForValue(receiver);
-      return new NullAwareExtension(variable,
-          _createRead(_helper.createVariableGet(variable, variable.fileOffset)))
+      return new NullAwareExtension(
+          variable,
+          _createRead(_helper.createVariableGet(variable, variable.fileOffset,
+              forNullGuardedAccess: true)))
         ..fileOffset = fileOffset;
     } else {
       return _createRead(receiver);
@@ -1945,9 +1960,13 @@
           _helper.forest.createVariableDeclarationForValue(receiver);
       return new NullAwareExtension(
           variable,
-          _createWrite(fileOffset,
-              _helper.createVariableGet(variable, variable.fileOffset), value,
-              forEffect: voidContext, readOnlyReceiver: true))
+          _createWrite(
+              fileOffset,
+              _helper.createVariableGet(variable, variable.fileOffset,
+                  forNullGuardedAccess: true),
+              value,
+              forEffect: voidContext,
+              readOnlyReceiver: true))
         ..fileOffset = fileOffset;
     } else {
       return _createWrite(fileOffset, receiver, value,
@@ -1975,11 +1994,16 @@
     if (isNullAware) {
       VariableDeclaration variable =
           _helper.forest.createVariableDeclarationForValue(receiver);
-      Expression read =
-          _createRead(_helper.createVariableGet(variable, receiver.fileOffset));
-      Expression write = _createWrite(fileOffset,
-          _helper.createVariableGet(variable, receiver.fileOffset), value,
-          forEffect: voidContext, readOnlyReceiver: true);
+      Expression read = _createRead(_helper.createVariableGet(
+          variable, receiver.fileOffset,
+          forNullGuardedAccess: true));
+      Expression write = _createWrite(
+          fileOffset,
+          _helper.createVariableGet(variable, receiver.fileOffset,
+              forNullGuardedAccess: true),
+          value,
+          forEffect: voidContext,
+          readOnlyReceiver: true);
       return new NullAwareExtension(
           variable,
           new IfNullSet(read, write, forEffect: voidContext)
@@ -2010,12 +2034,17 @@
           _helper.forest.createVariableDeclarationForValue(receiver);
       Expression binary = _helper.forest.createBinary(
           offset,
-          _createRead(_helper.createVariableGet(variable, receiver.fileOffset)),
+          _createRead(_helper.createVariableGet(variable, receiver.fileOffset,
+              forNullGuardedAccess: true)),
           binaryOperator,
           value);
-      Expression write = _createWrite(fileOffset,
-          _helper.createVariableGet(variable, receiver.fileOffset), binary,
-          forEffect: voidContext, readOnlyReceiver: true);
+      Expression write = _createWrite(
+          fileOffset,
+          _helper.createVariableGet(variable, receiver.fileOffset,
+              forNullGuardedAccess: true),
+          binary,
+          forEffect: voidContext,
+          readOnlyReceiver: true);
       return new NullAwareExtension(variable, write)..fileOffset = offset;
     } else {
       return new CompoundExtensionSet(extension, explicitTypeArguments,
@@ -2041,13 +2070,18 @@
           _helper.forest.createVariableDeclarationForValue(receiver);
       VariableDeclaration read = _helper.forest
           .createVariableDeclarationForValue(_createRead(
-              _helper.createVariableGet(variable, receiver.fileOffset)));
+              _helper.createVariableGet(variable, receiver.fileOffset,
+                  forNullGuardedAccess: true)));
       Expression binary = _helper.forest.createBinary(offset,
           _helper.createVariableGet(read, fileOffset), binaryOperator, value);
       VariableDeclaration write = _helper.forest
-          .createVariableDeclarationForValue(_createWrite(fileOffset,
-              _helper.createVariableGet(variable, receiver.fileOffset), binary,
-              forEffect: voidContext, readOnlyReceiver: true)
+          .createVariableDeclarationForValue(_createWrite(
+              fileOffset,
+              _helper.createVariableGet(variable, receiver.fileOffset,
+                  forNullGuardedAccess: true),
+              binary,
+              forEffect: voidContext,
+              readOnlyReceiver: true)
             ..fileOffset = fileOffset);
       return new NullAwareExtension(
           variable, new LocalPostIncDec(read, write)..fileOffset = offset)
@@ -2077,7 +2111,8 @@
       receiverVariable =
           _helper.forest.createVariableDeclarationForValue(receiver);
       receiverExpression = _helper.createVariableGet(
-          receiverVariable, receiverVariable.fileOffset);
+          receiverVariable, receiverVariable.fileOffset,
+          forNullGuardedAccess: true);
     }
     Expression invocation;
     if (invokeTarget != null) {
@@ -2249,7 +2284,8 @@
     Expression receiverValue;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
     } else {
       receiverValue = receiver;
     }
@@ -2278,7 +2314,8 @@
     Expression receiverValue;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
     } else {
       receiverValue = receiver;
     }
@@ -2313,7 +2350,8 @@
     bool readOnlyReceiver;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
       readOnlyReceiver = true;
     } else {
       receiverValue = receiver;
@@ -2350,7 +2388,8 @@
     bool readOnlyReceiver;
     if (isNullAware) {
       variable = _forest.createVariableDeclarationForValue(receiver);
-      receiverValue = _helper.createVariableGet(variable, fileOffset);
+      receiverValue = _helper.createVariableGet(variable, fileOffset,
+          forNullGuardedAccess: true);
       readOnlyReceiver = true;
     } else {
       receiverValue = receiver;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index dde3a93..1d4799e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -148,7 +148,8 @@
 
   /// Creates a [VariableGet] of the [variable] using [charOffset] as the file
   /// offset of the created node.
-  Expression createVariableGet(VariableDeclaration variable, int charOffset);
+  Expression createVariableGet(VariableDeclaration variable, int charOffset,
+      {bool forNullGuardedAccess: false});
 
   /// Registers that [variable] is assigned to.
   ///
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index a5f87a7..ce53e3d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -568,7 +568,8 @@
         isConst: isConst,
         isFieldFormal: isFieldFormal,
         isCovariant: isCovariant,
-        isLocalFunction: isLocalFunction);
+        isLocalFunction: isLocalFunction,
+        hasDeclaredInitializer: initializer != null);
   }
 
   VariableDeclaration createVariableDeclarationForValue(Expression initializer,
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 4b523d4..070a818 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1073,7 +1073,7 @@
     // To infer `e0 ?? e1` in context K:
     // - Infer e0 in context K to get T0
     ExpressionInferenceResult lhsResult = inferrer.inferExpression(
-        node.left, typeContext.withNullability(inferrer.library.nullable), true,
+        node.left, inferrer.computeNullable(typeContext), true,
         isVoidAllowed: false);
 
     Member equalsMember = inferrer
@@ -2273,24 +2273,19 @@
     ExpressionInferenceResult result =
         inferrer.inferExpression(node.receiver, const UnknownType(), true);
     Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = result.nullAwareGuards;
       receiver = result.nullAwareAction;
+      receiverType = result.nullAwareActionType;
     } else {
       receiver = result.expression;
+      receiverType = result.inferredType;
     }
-    DartType receiverType = result.inferredType;
-    ExpressionInferenceResult invocationResult = inferrer.inferMethodInvocation(
-        node.fileOffset,
-        nullAwareGuards,
-        receiver,
-        receiverType,
-        node.name,
-        node.arguments,
-        typeContext,
+    return inferrer.inferMethodInvocation(node.fileOffset, nullAwareGuards,
+        receiver, receiverType, node.name, node.arguments, typeContext,
         isExpressionInvocation: false);
-    return invocationResult;
   }
 
   ExpressionInferenceResult visitExpressionInvocation(
@@ -2298,14 +2293,16 @@
     ExpressionInferenceResult result =
         inferrer.inferExpression(node.expression, const UnknownType(), true);
     Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = result.nullAwareGuards;
       receiver = result.nullAwareAction;
+      receiverType = result.nullAwareActionType;
     } else {
       receiver = result.expression;
+      receiverType = result.inferredType;
     }
-    DartType receiverType = result.inferredType;
     ExpressionInferenceResult invocationResult = inferrer.inferMethodInvocation(
         node.fileOffset,
         nullAwareGuards,
@@ -2318,7 +2315,7 @@
     if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
       if (receiverType is! DynamicType && receiverType.isPotentiallyNullable) {
         if (inferrer.nnbdStrongMode) {
-          return new ExpressionInferenceResult.nullAware(
+          return new ExpressionInferenceResult(
               invocationResult.inferredType,
               inferrer.helper.wrapInProblem(
                   invocationResult.expression..fileOffset = node.fileOffset,
@@ -2386,7 +2383,7 @@
     ExpressionInferenceResult invocationResult = inferrer.inferExpression(
         node.invocation, typeContext, true,
         isVoidAllowed: true);
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         invocationResult.inferredType,
         invocationResult.expression,
         nullAwareGuards.prepend(nullAwareGuard));
@@ -2400,8 +2397,10 @@
         inferrer.createNullAwareGuard(node.variable);
     ExpressionInferenceResult readResult =
         inferrer.inferExpression(node.read, typeContext, true);
-    return new ExpressionInferenceResult.nullAware(readResult.inferredType,
-        readResult.expression, nullAwareGuards.prepend(nullAwareGuard));
+    return inferrer.createNullAwareExpressionInferenceResult(
+        readResult.inferredType,
+        readResult.expression,
+        nullAwareGuards.prepend(nullAwareGuard));
   }
 
   ExpressionInferenceResult visitNullAwarePropertySet(
@@ -2412,8 +2411,10 @@
         inferrer.createNullAwareGuard(node.variable);
     ExpressionInferenceResult writeResult =
         inferrer.inferExpression(node.write, typeContext, true);
-    return new ExpressionInferenceResult.nullAware(writeResult.inferredType,
-        writeResult.expression, nullAwareGuards.prepend(nullAwareGuard));
+    return inferrer.createNullAwareExpressionInferenceResult(
+        writeResult.inferredType,
+        writeResult.expression,
+        nullAwareGuards.prepend(nullAwareGuard));
   }
 
   ExpressionInferenceResult visitNullAwareExtension(
@@ -2423,7 +2424,7 @@
         inferrer.createNullAwareGuard(node.variable);
     ExpressionInferenceResult expressionResult =
         inferrer.inferExpression(node.expression, const UnknownType(), true);
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         expressionResult.inferredType,
         expressionResult.expression,
         const Link<NullAwareGuard>().prepend(nullAwareGuard));
@@ -2496,13 +2497,15 @@
 
     Link<NullAwareGuard> nullAwareGuards;
     Expression receiver;
+    DartType receiverType;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
-    DartType receiverType = receiverResult.inferredType;
 
     VariableDeclaration receiverVariable;
     Expression readReceiver;
@@ -2548,7 +2551,7 @@
       replacement = createLet(receiverVariable, replacement);
     }
     replacement.fileOffset = node.fileOffset;
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         binaryType, replacement, nullAwareGuards);
   }
 
@@ -2612,7 +2615,7 @@
         ..fileOffset = node.fileOffset;
     }
 
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         inferredType, replacement, nullAwareGuards);
   }
 
@@ -2622,11 +2625,14 @@
         inferrer.inferExpression(node.read, const UnknownType(), true);
     Link<NullAwareGuard> nullAwareGuards;
     Expression read;
+    DartType readType;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = readResult.nullAwareGuards;
       read = readResult.nullAwareAction;
+      readType = readResult.nullAwareActionType;
     } else {
       read = readResult.expression;
+      readType = readResult.inferredType;
     }
     inferrer.flowAnalysis.ifNullExpression_rightBegin(read);
     ExpressionInferenceResult writeResult = inferrer
@@ -2634,11 +2640,10 @@
     inferrer.flowAnalysis.ifNullExpression_end();
 
     Member equalsMember = inferrer
-        .findInterfaceMember(
-            readResult.inferredType, equalsName, node.fileOffset)
+        .findInterfaceMember(readType, equalsName, node.fileOffset)
         .member;
 
-    DartType originalReadType = readResult.inferredType;
+    DartType originalReadType = readType;
     DartType nonNullableReadType =
         inferrer.computeNonNullable(originalReadType);
     DartType inferredType = inferrer.typeSchemaEnvironment
@@ -2664,8 +2669,7 @@
       //
       //      let v1 = a in v1 == null ? a = b : v1
       //
-      VariableDeclaration readVariable =
-          createVariable(read, readResult.inferredType);
+      VariableDeclaration readVariable = createVariable(read, readType);
       MethodInvocation equalsNull = createEqualsNull(
           node.fileOffset, createVariableGet(readVariable), equalsMember);
       VariableGet variableGet = createVariableGet(readVariable);
@@ -2679,7 +2683,7 @@
       replacement = new Let(readVariable, conditional)
         ..fileOffset = node.fileOffset;
     }
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         inferredType, replacement, nullAwareGuards);
   }
 
@@ -2688,14 +2692,16 @@
         node.receiver, const UnknownType(), true,
         isVoidAllowed: true);
     Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
-    DartType receiverType = receiverResult.inferredType;
 
     ObjectAccessTarget indexGetTarget = inferrer.findInterfaceMember(
         receiverType, indexGetName, node.fileOffset,
@@ -2714,7 +2720,7 @@
 
     ExpressionInferenceResult replacement = _computeIndexGet(node.fileOffset,
         receiver, receiverType, indexGetTarget, index, readCheckKind);
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         replacement.inferredType, replacement.expression, nullAwareGuards);
   }
 
@@ -2723,14 +2729,16 @@
         node.receiver, const UnknownType(), true,
         isVoidAllowed: true);
     Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
-    DartType receiverType = receiverResult.inferredType;
     VariableDeclaration receiverVariable;
     if (!node.forEffect && !node.readOnlyReceiver) {
       receiverVariable = createVariable(receiver, receiverType);
@@ -2790,7 +2798,7 @@
       }
     }
     replacement.fileOffset = node.fileOffset;
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         inferredType, replacement, nullAwareGuards);
   }
 
@@ -2926,14 +2934,16 @@
         isVoidAllowed: true);
 
     Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
-    DartType receiverType = receiverResult.inferredType;
     VariableDeclaration receiverVariable;
     Expression readReceiver = receiver;
     Expression writeReceiver;
@@ -3083,7 +3093,7 @@
     } else {
       replacement = inner;
     }
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         inferredType, replacement, nullAwareGuards);
   }
 
@@ -3524,6 +3534,27 @@
           ..fileOffset = fileOffset;
       }
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (leftType is! DynamicType && leftType.isPotentiallyNullable) {
+        if (inferrer.nnbdStrongMode) {
+          return new ExpressionInferenceResult(
+              binaryType,
+              inferrer.helper.wrapInProblem(
+                  binary,
+                  templateNullableOperatorCallError.withArguments(
+                      binaryName.name,
+                      leftType,
+                      inferrer.isNonNullableByDefault),
+                  binaryName.name.length));
+        } else {
+          inferrer.helper.addProblem(
+              templateNullableOperatorCallWarning.withArguments(
+                  binaryName.name, leftType, inferrer.isNonNullableByDefault),
+              binary.fileOffset,
+              binaryName.name.length);
+        }
+      }
+    }
     return new ExpressionInferenceResult(binaryType, binary);
   }
 
@@ -3588,6 +3619,30 @@
           ..fileOffset = fileOffset;
       }
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (expressionType is! DynamicType &&
+          expressionType.isPotentiallyNullable) {
+        // TODO(johnniwinther): Special case 'unary-' in messages. It should
+        // probably be referred to as "Unary operator '-' ...".
+        if (inferrer.nnbdStrongMode) {
+          return new ExpressionInferenceResult(
+              unaryType,
+              inferrer.helper.wrapInProblem(
+                  unary,
+                  templateNullableOperatorCallError.withArguments(
+                      unaryName.name,
+                      expressionType,
+                      inferrer.isNonNullableByDefault),
+                  unaryName == unaryMinusName ? 1 : unaryName.name.length));
+        } else {
+          inferrer.helper.addProblem(
+              templateNullableOperatorCallWarning.withArguments(unaryName.name,
+                  expressionType, inferrer.isNonNullableByDefault),
+              unary.fileOffset,
+              unaryName == unaryMinusName ? 1 : unaryName.name.length);
+        }
+      }
+    }
     return new ExpressionInferenceResult(unaryType, unary);
   }
 
@@ -3641,6 +3696,29 @@
           ..fileOffset = fileOffset;
       }
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (receiverType is! DynamicType && receiverType.isPotentiallyNullable) {
+        if (inferrer.nnbdStrongMode) {
+          return new ExpressionInferenceResult(
+              readType,
+              inferrer.helper.wrapInProblem(
+                  read,
+                  templateNullableOperatorCallError.withArguments(
+                      indexGetName.name,
+                      receiverType,
+                      inferrer.isNonNullableByDefault),
+                  noLength));
+        } else {
+          inferrer.helper.addProblem(
+              templateNullableOperatorCallWarning.withArguments(
+                  indexGetName.name,
+                  receiverType,
+                  inferrer.isNonNullableByDefault),
+              read.fileOffset,
+              noLength);
+        }
+      }
+    }
     return new ExpressionInferenceResult(readType, read);
   }
 
@@ -3678,6 +3756,25 @@
           writeTarget.member)
         ..fileOffset = fileOffset;
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (receiverType is! DynamicType && receiverType.isPotentiallyNullable) {
+        if (inferrer.nnbdStrongMode) {
+          return inferrer.helper.wrapInProblem(
+              write,
+              templateNullableOperatorCallError.withArguments(indexSetName.name,
+                  receiverType, inferrer.isNonNullableByDefault),
+              noLength);
+        } else {
+          inferrer.helper.addProblem(
+              templateNullableOperatorCallWarning.withArguments(
+                  indexSetName.name,
+                  receiverType,
+                  inferrer.isNonNullableByDefault),
+              write.fileOffset,
+              noLength);
+        }
+      }
+    }
     return write;
   }
 
@@ -3777,6 +3874,32 @@
         return inferrer.instantiateTearOff(readType, typeContext, read);
       }
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (receiverType is! DynamicType &&
+          receiverType.isPotentiallyNullable &&
+          !inferrer.matchesObjectMemberCall(
+              propertyName, const [], const [], const [])) {
+        if (inferrer.nnbdStrongMode) {
+          return new ExpressionInferenceResult(
+              readType,
+              inferrer.helper.wrapInProblem(
+                  read,
+                  templateNullablePropertyAccessError.withArguments(
+                      propertyName.name,
+                      receiverType,
+                      inferrer.isNonNullableByDefault),
+                  propertyName.name.length));
+        } else {
+          inferrer.helper.addProblem(
+              templateNullablePropertyAccessWarning.withArguments(
+                  propertyName.name,
+                  receiverType,
+                  inferrer.isNonNullableByDefault),
+              read.fileOffset,
+              propertyName.name.length);
+        }
+      }
+    }
     return new ExpressionInferenceResult(readType, read);
   }
 
@@ -3835,6 +3958,28 @@
       write = new PropertySet(receiver, propertyName, value, writeTarget.member)
         ..fileOffset = fileOffset;
     }
+    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
+      if (receiverType is! DynamicType && receiverType.isPotentiallyNullable) {
+        if (inferrer.nnbdStrongMode) {
+          return inferrer.helper.wrapInProblem(
+              write,
+              templateNullablePropertyAccessError.withArguments(
+                  propertyName.name,
+                  receiverType,
+                  inferrer.isNonNullableByDefault),
+              propertyName.name.length);
+        } else {
+          inferrer.helper.addProblem(
+              templateNullablePropertyAccessWarning.withArguments(
+                  propertyName.name,
+                  receiverType,
+                  inferrer.isNonNullableByDefault),
+              write.fileOffset,
+              propertyName.name.length);
+        }
+      }
+    }
+
     return write;
   }
 
@@ -3845,14 +3990,16 @@
         isVoidAllowed: true);
     Expression receiver;
     Link<NullAwareGuard> nullAwareGuards;
+    DartType receiverType;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
     VariableDeclaration receiverVariable;
-    DartType receiverType = receiverResult.inferredType;
     Expression readReceiver = receiver;
     Expression writeReceiver;
     if (node.readOnlyReceiver) {
@@ -3981,7 +4128,7 @@
     } else {
       replacement = inner;
     }
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         node.forPostIncDec ? readType : binaryType,
         replacement,
         nullAwareGuards);
@@ -3992,27 +4139,34 @@
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
         node.receiver, const UnknownType(), true,
         isVoidAllowed: true);
-    DartType receiverType = receiverResult.inferredType;
 
+    Expression receiver;
+    DartType receiverType;
     Link<NullAwareGuard> nullAwareGuards;
-    VariableDeclaration receiverVariable;
     if (inferrer.isNonNullableByDefault) {
-      receiverVariable =
-          createVariable(receiverResult.nullAwareAction, receiverType);
+      receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
       nullAwareGuards = receiverResult.nullAwareGuards;
     } else {
-      receiverVariable =
-          createVariable(receiverResult.expression, receiverType);
+      receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
       nullAwareGuards = const Link<NullAwareGuard>();
     }
 
+    VariableDeclaration receiverVariable =
+        createVariable(receiver, receiverType);
     NullAwareGuard nullAwareGuard =
         inferrer.createNullAwareGuard(receiverVariable);
     Expression readReceiver = createVariableGet(receiverVariable);
     Expression writeReceiver = createVariableGet(receiverVariable);
+    DartType nonNullReceiverType = inferrer.computeNonNullable(receiverType);
 
-    ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
-        readReceiver, receiverType, node.propertyName, const UnknownType(),
+    ExpressionInferenceResult readResult = _computePropertyGet(
+        node.readOffset,
+        readReceiver,
+        nonNullReceiverType,
+        node.propertyName,
+        const UnknownType(),
         isThisReceiver: node.receiver is ThisExpression);
     Expression read = readResult.expression;
     DartType readType = readResult.inferredType;
@@ -4034,10 +4188,11 @@
     DartType binaryType = binaryResult.inferredType;
 
     ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
-        receiverType, node.propertyName, node.writeOffset,
+        nonNullReceiverType, node.propertyName, node.writeOffset,
         setter: true, includeExtensionMethods: true);
 
-    DartType valueType = inferrer.getSetterType(writeTarget, receiverType);
+    DartType valueType =
+        inferrer.getSetterType(writeTarget, nonNullReceiverType);
     binary = inferrer.ensureAssignable(valueType, binaryType, binary,
         fileOffset: node.fileOffset);
 
@@ -4051,7 +4206,7 @@
     }
 
     Expression write = _computePropertySet(node.writeOffset, writeReceiver,
-        receiverType, node.propertyName, writeTarget, valueExpression,
+        nonNullReceiverType, node.propertyName, writeTarget, valueExpression,
         forEffect: true);
 
     DartType resultType = node.forPostIncDec ? readType : binaryType;
@@ -4109,7 +4264,7 @@
           createLet(writeVariable, createVariableGet(valueVariable)));
     }
 
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         resultType, action, nullAwareGuards.prepend(nullAwareGuard));
   }
 
@@ -4447,14 +4602,16 @@
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
         node.receiver, const UnknownType(), true,
         isVoidAllowed: false);
-    DartType receiverType = receiverResult.inferredType;
+    DartType receiverType;
     Expression receiver;
     Link<NullAwareGuard> nullAwareGuards;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
     ObjectAccessTarget target = inferrer.findInterfaceMember(
         receiverType, node.name, node.fileOffset,
@@ -4481,27 +4638,8 @@
     Expression replacement = _computePropertySet(
         node.fileOffset, receiver, receiverType, node.name, target, rhs,
         valueType: rhsType, forEffect: node.forEffect);
-    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
-      if (receiverType is! DynamicType && receiverType.isPotentiallyNullable) {
-        if (inferrer.nnbdStrongMode) {
-          replacement = inferrer.helper.wrapInProblem(
-              replacement,
-              templateNullablePropertyAccessError.withArguments(node.name.name,
-                  receiverType, inferrer.isNonNullableByDefault),
-              node.name.name.length);
-        } else {
-          inferrer.helper.addProblem(
-              templateNullablePropertyAccessWarning.withArguments(
-                  node.name.name,
-                  receiverType,
-                  inferrer.isNonNullableByDefault),
-              replacement.fileOffset,
-              node.name.name.length);
-        }
-      }
-    }
 
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         rhsType, replacement, nullAwareGuards);
   }
 
@@ -4510,25 +4648,30 @@
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
         node.receiver, const UnknownType(), true,
         isVoidAllowed: false);
+
     Link<NullAwareGuard> nullAwareGuards;
     Expression receiver;
-    DartType receiverType = receiverResult.inferredType;
+    DartType receiverType;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = receiverResult.nullAwareGuards;
       receiver = receiverResult.nullAwareAction;
+      receiverType = receiverResult.nullAwareActionType;
     } else {
       nullAwareGuards = const Link<NullAwareGuard>();
       receiver = receiverResult.expression;
+      receiverType = receiverResult.inferredType;
     }
+
     VariableDeclaration receiverVariable =
         createVariable(receiver, receiverType);
     NullAwareGuard nullAwareGuard =
         inferrer.createNullAwareGuard(receiverVariable);
     Expression readReceiver = createVariableGet(receiverVariable);
     Expression writeReceiver = createVariableGet(receiverVariable);
+    DartType nonNullReceiverType = inferrer.computeNonNullable(receiverType);
 
-    ExpressionInferenceResult readResult = _computePropertyGet(
-        node.readOffset, readReceiver, receiverType, node.name, typeContext,
+    ExpressionInferenceResult readResult = _computePropertyGet(node.readOffset,
+        readReceiver, nonNullReceiverType, node.name, typeContext,
         isThisReceiver: node.receiver is ThisExpression);
     Expression read = readResult.expression;
     DartType readType = readResult.inferredType;
@@ -4545,17 +4688,18 @@
     }
 
     ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
-        receiverType, node.name, node.writeOffset,
+        nonNullReceiverType, node.name, node.writeOffset,
         setter: true, includeExtensionMethods: true);
 
-    DartType valueType = inferrer.getSetterType(writeTarget, receiverType);
+    DartType valueType =
+        inferrer.getSetterType(writeTarget, nonNullReceiverType);
 
     ExpressionInferenceResult valueResult = inferrer
         .inferExpression(node.value, valueType, true, isVoidAllowed: true);
     Expression value = inferrer.ensureAssignableResult(valueType, valueResult);
 
     Expression write = _computePropertySet(node.writeOffset, writeReceiver,
-        receiverType, node.name, writeTarget, value,
+        nonNullReceiverType, node.name, writeTarget, value,
         valueType: valueResult.inferredType, forEffect: node.forEffect);
 
     inferrer.flowAnalysis.ifNullExpression_end();
@@ -4603,7 +4747,7 @@
       replacement = createLet(readVariable, condition);
     }
 
-    return new ExpressionInferenceResult.nullAware(
+    return inferrer.createNullAwareExpressionInferenceResult(
         inferredType, replacement, nullAwareGuards.prepend(nullAwareGuard));
   }
 
@@ -4614,42 +4758,21 @@
         inferrer.inferExpression(node.receiver, const UnknownType(), true);
     Link<NullAwareGuard> nullAwareGuards;
     Expression receiver;
-    DartType receiverType = result.inferredType;
+    DartType receiverType;
     if (inferrer.isNonNullableByDefault) {
       nullAwareGuards = result.nullAwareGuards;
       receiver = result.nullAwareAction;
+      receiverType = result.nullAwareActionType;
     } else {
       receiver = result.expression;
+      receiverType = result.inferredType;
     }
     node.receiver = receiver..parent = node;
     ExpressionInferenceResult readResult = _computePropertyGet(
         node.fileOffset, receiver, receiverType, node.name, typeContext,
         isThisReceiver: node.receiver is ThisExpression);
-    Expression resultExpression = readResult.expression;
-    if (inferrer.isNonNullableByDefault && inferrer.performNnbdChecks) {
-      if (receiverType is! DynamicType &&
-          receiverType.isPotentiallyNullable &&
-          !inferrer.matchesObjectMemberCall(
-              node.name, const [], const [], const [])) {
-        if (inferrer.nnbdStrongMode) {
-          resultExpression = inferrer.helper.wrapInProblem(
-              resultExpression,
-              templateNullablePropertyAccessError.withArguments(node.name.name,
-                  receiverType, inferrer.isNonNullableByDefault),
-              node.name.name.length);
-        } else {
-          inferrer.helper.addProblem(
-              templateNullablePropertyAccessWarning.withArguments(
-                  node.name.name,
-                  receiverType,
-                  inferrer.isNonNullableByDefault),
-              resultExpression.fileOffset,
-              node.name.name.length);
-        }
-      }
-    }
-    return new ExpressionInferenceResult.nullAware(
-        readResult.inferredType, resultExpression, nullAwareGuards);
+    return inferrer.createNullAwareExpressionInferenceResult(
+        readResult.inferredType, readResult.expression, nullAwareGuards);
   }
 
   @override
@@ -5278,7 +5401,8 @@
         result.add(setter);
       }
       node.isLate = false;
-      node.type = node.type.withNullability(Nullability.nullable);
+      node.lateType = node.type;
+      node.type = inferrer.computeNullable(node.type);
       node.initializer = null;
 
       return new StatementInferenceResult.multiple(node.fileOffset, result);
@@ -5296,9 +5420,14 @@
     }
 
     DartType promotedType;
-    DartType declaredOrInferredType = variable.type;
+    DartType declaredOrInferredType = variable.lateType ?? variable.type;
     if (inferrer.isNonNullableByDefault) {
-      if (!variable.isLocalFunction) {
+      if (node.forNullGuardedAccess) {
+        DartType nonNullableType = inferrer.computeNonNullable(variable.type);
+        if (nonNullableType != variable.type) {
+          promotedType = nonNullableType;
+        }
+      } else if (!variable.isLocalFunction) {
         // Don't promote local functions.
         promotedType = inferrer.flowAnalysis.variableRead(node, variable);
       }
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 5b57388..7464992 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1052,6 +1052,9 @@
   /// the kernel.
   final bool isImplicitlyTyped;
 
+  /// True if the initializer was specified by the programmer.
+  final bool hasDeclaredInitializer;
+
   // TODO(ahe): Remove this field. We can get rid of it by recording closure
   // mutation in [BodyBuilder].
   final int functionNestingLevel;
@@ -1075,6 +1078,7 @@
 
   VariableDeclarationImpl(String name, this.functionNestingLevel,
       {this.forSyntheticToken: false,
+      this.hasDeclaredInitializer: false,
       Expression initializer,
       DartType type,
       bool isFinal: false,
@@ -1101,6 +1105,7 @@
         functionNestingLevel = 0,
         isImplicitlyTyped = false,
         isLocalFunction = false,
+        hasDeclaredInitializer = true,
         super.forValue(initializer);
 
   VariableDeclarationImpl.forValue(Expression initializer)
@@ -1108,10 +1113,27 @@
         functionNestingLevel = 0,
         isImplicitlyTyped = true,
         isLocalFunction = false,
+        hasDeclaredInitializer = true,
         super.forValue(initializer);
 
+  // The synthesized local getter function for a lowered late variable.
+  //
+  // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+  // lowering is enabled.
   VariableDeclaration lateGetter;
+
+  // The synthesized local setter function for an assignable lowered late
+  // variable.
+  //
+  // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+  // lowering is enabled.
   VariableDeclaration lateSetter;
+
+  // The original type (declared or inferred) of a lowered late variable.
+  //
+  // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+  // lowering is enabled.
+  DartType lateType;
 }
 
 /// Front end specific implementation of [VariableGet].
@@ -1120,8 +1142,14 @@
 
   final TypePromotionScope scope;
 
-  VariableGetImpl(VariableDeclaration variable, this.fact, this.scope)
-      : super(variable);
+  // TODO(johnniwinther): Remove the need for this by encoding all null aware
+  // expressions explicitly.
+  final bool forNullGuardedAccess;
+
+  VariableGetImpl(VariableDeclaration variable, this.fact, this.scope,
+      {this.forNullGuardedAccess})
+      : assert(forNullGuardedAccess != null),
+        super(variable);
 }
 
 /// Front end specific implementation of [LoadLibrary].
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 09e564e..c5cd908 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -53,16 +53,19 @@
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
+import '../builder/dynamic_type_builder.dart';
 import '../builder/field_builder.dart';
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
 import '../builder/named_type_builder.dart';
+import '../builder/never_type_builder.dart';
 import '../builder/nullability_builder.dart';
 import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
+import '../builder/void_type_builder.dart';
 
 import '../compiler_context.dart' show CompilerContext;
 
@@ -297,7 +300,7 @@
       loader.computeHierarchy();
       loader.performTopLevelInference(myClasses);
       loader.checkSupertypes(myClasses);
-      loader.checkBounds();
+      loader.checkTypes();
       loader.checkOverrides(myClasses);
       loader.checkAbstractMembers(myClasses);
       loader.checkRedirectingFactories(myClasses);
@@ -527,7 +530,10 @@
         }
       }
     } else if (supertype is InvalidTypeDeclarationBuilder ||
-        supertype is TypeVariableBuilder) {
+        supertype is TypeVariableBuilder ||
+        supertype is DynamicTypeBuilder ||
+        supertype is VoidTypeBuilder ||
+        supertype is NeverTypeBuilder) {
       builder.addSyntheticConstructor(
           makeDefaultConstructor(builder.cls, referenceFrom));
     } else {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index c372621..f561749 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -97,6 +97,7 @@
 
   DeclarationBuilder _currentDeclaration;
   ClassBuilder _currentClass;
+  bool _inRedirectingFactory = false;
 
   bool currentClassIsParserRecovery = false;
 
@@ -590,7 +591,7 @@
     if (name is ParserRecovery || currentClassIsParserRecovery) return;
 
     FunctionBuilder builder = lookupConstructor(beginToken, name);
-    if (bodyToken == null || optional("=", bodyToken.endGroup.next)) {
+    if (_inRedirectingFactory) {
       buildRedirectingFactoryMethod(
           bodyToken, builder, MemberKind.Factory, metadata);
     } else {
@@ -625,6 +626,7 @@
   void endRedirectingFactoryBody(Token beginToken, Token endToken) {
     debugEvent("RedirectingFactoryBody");
     discard(1); // ConstructorReference.
+    _inRedirectingFactory = true;
   }
 
   @override
@@ -793,6 +795,7 @@
   void endMember() {
     debugEvent("Member");
     checkEmpty(-1);
+    _inRedirectingFactory = false;
   }
 
   @override
@@ -933,6 +936,11 @@
       token = parser.parseInitializersOpt(token);
       token = parser.parseAsyncModifierOpt(token);
       AsyncMarker asyncModifier = getAsyncMarker(listener) ?? AsyncMarker.Sync;
+      if (kind == MemberKind.Factory && asyncModifier != AsyncMarker.Sync) {
+        // Factories has to be sync. The parser issued an error.
+        // Recover to sync.
+        asyncModifier = AsyncMarker.Sync;
+      }
       bool isExpression = false;
       bool allowAbstract = asyncModifier == AsyncMarker.Sync;
       parser.parseFunctionBody(token, isExpression, allowAbstract);
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 21006f7..59bbed4 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -23,7 +23,8 @@
 
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
 
-import 'package:kernel/ast.dart' show InvalidType, ProcedureKind, Variance;
+import 'package:kernel/ast.dart'
+    show InvalidType, Nullability, ProcedureKind, Variance;
 
 import '../builder/constructor_reference_builder.dart';
 import '../builder/enum_builder.dart';
@@ -572,6 +573,80 @@
     final int startCharOffset =
         metadata == null ? beginToken.charOffset : metadata.first.charOffset;
 
+    if (libraryBuilder.isNonNullableByDefault &&
+        libraryBuilder.loader.performNnbdChecks) {
+      String classNameForErrors = "${name}";
+      TypeBuilder supertypeForErrors = supertype is MixinApplicationBuilder
+          ? supertype.supertype
+          : supertype;
+      List<TypeBuilder> mixins =
+          supertype is MixinApplicationBuilder ? supertype.mixins : null;
+      if (supertypeForErrors != null) {
+        if (supertypeForErrors.nullabilityBuilder.build(libraryBuilder) ==
+            Nullability.nullable) {
+          if (libraryBuilder.loader.nnbdStrongMode) {
+            libraryBuilder.addProblem(
+                templateNullableSuperclassError
+                    .withArguments(supertypeForErrors.fullNameForErrors),
+                nameOffset,
+                classNameForErrors.length,
+                uri);
+          } else {
+            libraryBuilder.addProblem(
+                templateNullableSuperclassWarning
+                    .withArguments(supertypeForErrors.fullNameForErrors),
+                nameOffset,
+                classNameForErrors.length,
+                uri);
+          }
+        }
+      }
+      if (mixins != null) {
+        for (TypeBuilder mixin in mixins) {
+          if (mixin.nullabilityBuilder.build(libraryBuilder) ==
+              Nullability.nullable) {
+            if (libraryBuilder.loader.nnbdStrongMode) {
+              libraryBuilder.addProblem(
+                  templateNullableMixinError
+                      .withArguments(mixin.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            } else {
+              libraryBuilder.addProblem(
+                  templateNullableMixinWarning
+                      .withArguments(mixin.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            }
+          }
+        }
+      }
+      if (interfaces != null) {
+        for (TypeBuilder interface in interfaces) {
+          if (interface.nullabilityBuilder.build(libraryBuilder) ==
+              Nullability.nullable) {
+            if (libraryBuilder.loader.nnbdStrongMode) {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceError
+                      .withArguments(interface.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            } else {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceWarning
+                      .withArguments(interface.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            }
+          }
+        }
+      }
+    }
+
     libraryBuilder.addClass(
         documentationComment,
         metadata,
@@ -619,6 +694,56 @@
             supertypeConstraints.first, supertypeConstraints.skip(1).toList());
       }
     }
+
+    if (libraryBuilder.isNonNullableByDefault &&
+        libraryBuilder.loader.performNnbdChecks) {
+      String classNameForErrors = "${name}";
+      if (supertypeConstraints != null) {
+        for (TypeBuilder supertype in supertypeConstraints) {
+          if (supertype.nullabilityBuilder.build(libraryBuilder) ==
+              Nullability.nullable) {
+            if (libraryBuilder.loader.nnbdStrongMode) {
+              libraryBuilder.addProblem(
+                  templateNullableSuperclassError
+                      .withArguments(supertype.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            } else {
+              libraryBuilder.addProblem(
+                  templateNullableSuperclassWarning
+                      .withArguments(supertype.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            }
+          }
+        }
+      }
+      if (interfaces != null) {
+        for (TypeBuilder interface in interfaces) {
+          if (interface.nullabilityBuilder.build(libraryBuilder) ==
+              Nullability.nullable) {
+            if (libraryBuilder.loader.nnbdStrongMode) {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceError
+                      .withArguments(interface.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            } else {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceWarning
+                      .withArguments(interface.fullNameForErrors),
+                  nameOffset,
+                  classNameForErrors.length,
+                  uri);
+            }
+          }
+        }
+      }
+    }
+
     libraryBuilder.addMixinDeclaration(
         documentationComment,
         metadata,
@@ -1103,6 +1228,76 @@
       return;
     }
 
+    if (libraryBuilder.isNonNullableByDefault &&
+        libraryBuilder.loader.performNnbdChecks) {
+      String classNameForErrors = "${name}";
+      MixinApplicationBuilder mixinApplicationBuilder = mixinApplication;
+      TypeBuilder supertype = mixinApplicationBuilder.supertype;
+      List<TypeBuilder> mixins = mixinApplicationBuilder.mixins;
+      if (supertype != null && supertype is! MixinApplicationBuilder) {
+        if (supertype.nullabilityBuilder.build(libraryBuilder) ==
+            Nullability.nullable) {
+          if (libraryBuilder.loader.nnbdStrongMode) {
+            libraryBuilder.addProblem(
+                templateNullableSuperclassError
+                    .withArguments(supertype.fullNameForErrors),
+                charOffset,
+                classNameForErrors.length,
+                uri);
+          } else {
+            libraryBuilder.addProblem(
+                templateNullableSuperclassWarning
+                    .withArguments(supertype.fullNameForErrors),
+                charOffset,
+                classNameForErrors.length,
+                uri);
+          }
+        }
+      }
+      for (TypeBuilder mixin in mixins) {
+        if (mixin.nullabilityBuilder.build(libraryBuilder) ==
+            Nullability.nullable) {
+          if (libraryBuilder.loader.nnbdStrongMode) {
+            libraryBuilder.addProblem(
+                templateNullableMixinError
+                    .withArguments(mixin.fullNameForErrors),
+                charOffset,
+                classNameForErrors.length,
+                uri);
+          } else {
+            libraryBuilder.addProblem(
+                templateNullableMixinWarning
+                    .withArguments(mixin.fullNameForErrors),
+                charOffset,
+                classNameForErrors.length,
+                uri);
+          }
+        }
+      }
+      if (interfaces != null) {
+        for (TypeBuilder interface in interfaces) {
+          if (interface.nullabilityBuilder.build(libraryBuilder) ==
+              Nullability.nullable) {
+            if (libraryBuilder.loader.nnbdStrongMode) {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceError
+                      .withArguments(interface.fullNameForErrors),
+                  charOffset,
+                  classNameForErrors.length,
+                  uri);
+            } else {
+              libraryBuilder.addProblem(
+                  templateNullableInterfaceWarning
+                      .withArguments(interface.fullNameForErrors),
+                  charOffset,
+                  classNameForErrors.length,
+                  uri);
+            }
+          }
+        }
+      }
+    }
+
     int startCharOffset = beginToken.charOffset;
     int charEndOffset = endToken.charOffset;
     libraryBuilder.addNamedMixinApplication(
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 96fc62b..11ef3f6 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -365,11 +365,14 @@
 
   bool isOptOutTest(Uri uri) {
     String path = uri.path;
-    int start = path.indexOf('/tests/');
-    if (start == -1) return false;
-    int end = path.indexOf('/', start + '/tests/'.length + 1);
-    if (end == -1) return false;
-    return optOutTestPaths.contains(path.substring(start, end));
+    for (String testDir in ['/tests/', '/generated_tests/']) {
+      int start = path.indexOf(testDir);
+      if (start == -1) continue;
+      int end = path.indexOf('/', start + testDir.length + 1);
+      if (end == -1) continue;
+      return optOutTestPaths.contains(path.substring(start, end));
+    }
+    return false;
   }
 
   // TODO(johnniwinther): remove this logic. Opted out packages should be
@@ -435,6 +438,7 @@
     'mockito',
     'modular_test',
     'mustache',
+    'native_stack_traces',
     'nnbd_migration',
     'oauth2',
     'observatory',
@@ -491,6 +495,11 @@
     '/tests/language_2',
     '/tests/lib_2',
     '/tests/standalone_2',
+    '/generated_tests/co19_2',
+    '/generated_tests/corelib_2',
+    '/generated_tests/language_2',
+    '/generated_tests/lib_2',
+    '/generated_tests/standalone_2',
   };
 
   LanguageVersion get languageVersion => _languageVersion;
@@ -3054,12 +3063,45 @@
         allowSuperBounded: true);
   }
 
+  void checkInitializersInFormals(List<FormalParameterBuilder> formals) {
+    bool performInitializerChecks =
+        isNonNullableByDefault && loader.performNnbdChecks;
+    if (!performInitializerChecks) return;
+
+    for (FormalParameterBuilder formal in formals) {
+      bool isOptionalPositional = formal.isOptional && formal.isPositional;
+      bool isOptionalNamed = !formal.isNamedRequired && formal.isNamed;
+      bool isOptional = isOptionalPositional || isOptionalNamed;
+      if (isOptional &&
+          formal.variable.type.isPotentiallyNonNullable &&
+          !formal.hasDeclaredInitializer) {
+        if (loader.nnbdStrongMode) {
+          addProblem(
+              templateOptionalNonNullableWithoutInitializerError.withArguments(
+                  formal.name, formal.variable.type, isNonNullableByDefault),
+              formal.charOffset,
+              formal.name.length,
+              uri);
+        } else {
+          addProblem(
+              templateOptionalNonNullableWithoutInitializerWarning
+                  .withArguments(formal.name, formal.variable.type,
+                      isNonNullableByDefault),
+              formal.charOffset,
+              formal.name.length,
+              uri);
+        }
+      }
+    }
+  }
+
   void checkBoundsInFunctionNodeParts(
       TypeEnvironment typeEnvironment, Uri fileUri, int fileOffset,
       {List<TypeParameter> typeParameters,
       List<VariableDeclaration> positionalParameters,
       List<VariableDeclaration> namedParameters,
-      DartType returnType}) {
+      DartType returnType,
+      int requiredParameterCount}) {
     if (typeParameters != null) {
       for (TypeParameter parameter in typeParameters) {
         checkBoundsInType(
@@ -3068,14 +3110,16 @@
       }
     }
     if (positionalParameters != null) {
-      for (VariableDeclaration formal in positionalParameters) {
+      for (int i = 0; i < positionalParameters.length; ++i) {
+        VariableDeclaration parameter = positionalParameters[i];
         checkBoundsInType(
-            formal.type, typeEnvironment, fileUri, formal.fileOffset,
+            parameter.type, typeEnvironment, fileUri, parameter.fileOffset,
             allowSuperBounded: true);
       }
     }
     if (namedParameters != null) {
-      for (VariableDeclaration named in namedParameters) {
+      for (int i = 0; i < namedParameters.length; ++i) {
+        VariableDeclaration named = namedParameters[i];
         checkBoundsInType(
             named.type, typeEnvironment, fileUri, named.fileOffset,
             allowSuperBounded: true);
@@ -3120,7 +3164,8 @@
         typeParameters: function.typeParameters,
         positionalParameters: function.positionalParameters,
         namedParameters: function.namedParameters,
-        returnType: function.returnType);
+        returnType: function.returnType,
+        requiredParameterCount: function.requiredParameterCount);
   }
 
   void checkBoundsInListLiteral(
@@ -3284,7 +3329,7 @@
     }
   }
 
-  void checkBoundsInOutline(TypeEnvironment typeEnvironment) {
+  void checkTypesInOutline(TypeEnvironment typeEnvironment) {
     Iterator<Builder> iterator = this.iterator;
     while (iterator.moveNext()) {
       Builder declaration = iterator.current;
@@ -3293,6 +3338,9 @@
       } else if (declaration is ProcedureBuilder) {
         checkBoundsInFunctionNode(declaration.procedure.function,
             typeEnvironment, declaration.fileUri);
+        if (declaration.formals != null) {
+          checkInitializersInFormals(declaration.formals);
+        }
       } else if (declaration is ClassBuilder) {
         declaration.checkTypesInOutline(typeEnvironment);
       }
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 82edea3..d0a8f91 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -959,12 +959,12 @@
     ticker.logMs("Checked supertypes");
   }
 
-  void checkBounds() {
+  void checkTypes() {
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library is SourceLibraryBuilder) {
         if (library.loader == this) {
           library
-              .checkBoundsInOutline(typeInferenceEngine.typeSchemaEnvironment);
+              .checkTypesInOutline(typeInferenceEngine.typeSchemaEnvironment);
         }
       }
     });
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 73af49e..20de17c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -261,7 +261,8 @@
 
   @override
   DartType promoteToNonNull(DartType type) {
-    if (type is TypeParameterType) {
+    if (type is TypeParameterType &&
+        type.typeParameterTypeNullability != Nullability.nullable) {
       DartType bound = type.bound.withNullability(Nullability.nonNullable);
       if (bound != type.bound) {
         return new 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 f90f5c1..f1d7ed6 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
@@ -528,6 +528,13 @@
         library.loader.performNnbdChecks;
   }
 
+  DartType computeNullable(DartType type) {
+    if (type == coreTypes.nullType || type is NeverType) {
+      return coreTypes.nullType;
+    }
+    return type.withNullability(library.nullable);
+  }
+
   DartType computeNonNullable(DartType type) {
     if (type == coreTypes.nullType) {
       return isNonNullableByDefault
@@ -1831,6 +1838,21 @@
         variable, variable.fileOffset, equalsMember, this);
   }
 
+  ExpressionInferenceResult createNullAwareExpressionInferenceResult(
+      DartType inferredType,
+      Expression expression,
+      Link<NullAwareGuard> nullAwareGuards) {
+    if (nullAwareGuards != null && nullAwareGuards.isNotEmpty) {
+      return new NullAwareExpressionInferenceResult(
+          computeNullable(inferredType),
+          inferredType,
+          nullAwareGuards,
+          expression);
+    } else {
+      return new ExpressionInferenceResult(inferredType, expression);
+    }
+  }
+
   /// Performs type inference on the given [expression].
   ///
   /// [typeContext] is the expected type of the expression, based on surrounding
@@ -2404,6 +2426,59 @@
             'type', new InstrumentationValueForType(inferredType));
         formal.type = inferredType;
       }
+
+      if (isNonNullableByDefault && performNnbdChecks) {
+        // If a parameter is a positional or named optional parameter and its
+        // type is potentially non-nullable, it should have an initializer.
+        bool isOptionalPositional = function.requiredParameterCount <= i &&
+            i < function.positionalParameters.length;
+        bool isOptionalNamed =
+            i >= function.positionalParameters.length && !formal.isRequired;
+        if ((isOptionalPositional || isOptionalNamed) &&
+            formal.type.isPotentiallyNonNullable &&
+            !formal.hasDeclaredInitializer) {
+          if (nnbdStrongMode) {
+            library.addProblem(
+                templateOptionalNonNullableWithoutInitializerError
+                    .withArguments(
+                        formal.name, formal.type, isNonNullableByDefault),
+                formal.fileOffset,
+                formal.name.length,
+                library.uri);
+          } else {
+            library.addProblem(
+                templateOptionalNonNullableWithoutInitializerWarning
+                    .withArguments(
+                        formal.name, formal.type, isNonNullableByDefault),
+                formal.fileOffset,
+                formal.name.length,
+                library.uri);
+          }
+        }
+      }
+    }
+
+    if (isNonNullableByDefault && performNnbdChecks) {
+      for (VariableDeclarationImpl formal in function.namedParameters) {
+        // Required named parameters shouldn't have initializers.
+        if (formal.isRequired && formal.hasDeclaredInitializer) {
+          if (nnbdStrongMode) {
+            library.addProblem(
+                templateRequiredNamedParameterHasDefaultValueError
+                    .withArguments(formal.name),
+                formal.fileOffset,
+                formal.name.length,
+                library.uri);
+          } else {
+            library.addProblem(
+                templateRequiredNamedParameterHasDefaultValueWarning
+                    .withArguments(formal.name),
+                formal.fileOffset,
+                formal.name.length,
+                library.uri);
+          }
+        }
+      }
     }
 
     // Let `N'` be `N[T/S]`.  The [ClosureContext] constructor will adjust
@@ -2499,7 +2574,7 @@
         typeContext, fileOffset, unknownFunction, arguments, name,
         receiverType: const DynamicType());
     assert(name != equalsName);
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         result.inferredType,
         result.applyResult(new MethodInvocation(receiver, name, arguments)
           ..fileOffset = fileOffset),
@@ -2524,7 +2599,7 @@
         receiverType: receiverType);
     assert(name != equalsName);
     // TODO(johnniwinther): Use InvalidType instead.
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         const DynamicType(), error, nullAwareGuards);
   }
 
@@ -2562,7 +2637,7 @@
       library.checkBoundsInStaticInvocation(staticInvocation,
           typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
     }
-    return new ExpressionInferenceResult.nullAware(result.inferredType,
+    return createNullAwareExpressionInferenceResult(result.inferredType,
         result.applyResult(staticInvocation), nullAwareGuards);
   }
 
@@ -2577,10 +2652,10 @@
     assert(target.isCallFunction);
     FunctionType functionType = getFunctionType(target, receiverType);
     InvocationInferenceResult result = inferInvocation(
-        typeContext, fileOffset, functionType, arguments, target.member?.name,
+        typeContext, fileOffset, functionType, arguments, callName,
         receiverType: receiverType);
     // TODO(johnniwinther): Check that type arguments against the bounds.
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         result.inferredType,
         result.applyResult(new MethodInvocation(receiver, callName, arguments)
           ..fileOffset = fileOffset),
@@ -2673,7 +2748,7 @@
         new MethodInvocation(receiver, methodName, arguments, method)
           ..fileOffset = fileOffset;
 
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         result.inferredType, result.applyResult(replacement), nullAwareGuards);
   }
 
@@ -2770,7 +2845,7 @@
         new MethodInvocation(receiver, getter.name, arguments, getter)
           ..fileOffset = fileOffset;
 
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         result.inferredType, result.applyResult(replacement), nullAwareGuards);
   }
 
@@ -2844,7 +2919,7 @@
     replacement ??= new MethodInvocation(receiver, field.name, arguments, field)
       ..fileOffset = fileOffset;
 
-    return new ExpressionInferenceResult.nullAware(
+    return createNullAwareExpressionInferenceResult(
         result.inferredType, result.applyResult(replacement), nullAwareGuards);
   }
 
@@ -3396,7 +3471,7 @@
           templateUndefinedMethod.withArguments(unaryName.name,
               resolveTypeParameter(expressionType), isNonNullableByDefault),
           fileOffset,
-          unaryName.name == unaryMinusName.name ? 1 : unaryName.name.length);
+          unaryName == unaryMinusName ? 1 : unaryName.name.length);
     }
   }
 }
@@ -3657,17 +3732,6 @@
   /// The inferred expression.
   final Expression expression;
 
-  factory ExpressionInferenceResult.nullAware(
-      DartType inferredType, Expression expression,
-      [Link<NullAwareGuard> nullAwareGuards = const Link<NullAwareGuard>()]) {
-    if (nullAwareGuards != null && nullAwareGuards.isNotEmpty) {
-      return new NullAwareExpressionInferenceResult(
-          inferredType, nullAwareGuards, expression);
-    } else {
-      return new ExpressionInferenceResult(inferredType, expression);
-    }
-  }
-
   ExpressionInferenceResult(this.inferredType, this.expression)
       : assert(expression != null);
 
@@ -3680,6 +3744,8 @@
   /// Otherwise, this is the same as [expression].
   Expression get nullAwareAction => expression;
 
+  DartType get nullAwareActionType => inferredType;
+
   String toString() => 'ExpressionInferenceResult($inferredType,$expression)';
 }
 
@@ -3750,6 +3816,9 @@
   /// The inferred type of the expression.
   final DartType inferredType;
 
+  /// The inferred type of the [nullAwareAction].
+  final DartType nullAwareActionType;
+
   @override
   final Link<NullAwareGuard> nullAwareGuards;
 
@@ -3758,8 +3827,8 @@
 
   Expression _expression;
 
-  NullAwareExpressionInferenceResult(
-      this.inferredType, this.nullAwareGuards, this.nullAwareAction)
+  NullAwareExpressionInferenceResult(this.inferredType,
+      this.nullAwareActionType, this.nullAwareGuards, this.nullAwareAction)
       : assert(nullAwareGuards.isNotEmpty),
         assert(nullAwareAction != null);
 
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 1d83e2b..b5e8ccf 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE.md file.
 
+# Note that test/spelling: Status will have no effect. Spelling errors can
+# always be fixed by either spelling correctly or updating the dictionary.
+
 AbstractClassInstantiation/example: Fail
 AbstractClassMember/part_wrapped_script5: Fail
 AbstractClassMember/part_wrapped_script6: Fail
@@ -351,7 +354,6 @@
 InterpolationInUri/example: Fail
 InvalidAssignmentWarning/analyzerCode: Fail
 InvalidAssignmentWarning/example: Fail
-InvalidAssignmentWarning/spelling: Fail
 InvalidBreakTarget/analyzerCode: Fail
 InvalidBreakTarget/example: Fail
 InvalidCastFunctionExpr/example: Fail
@@ -447,7 +449,6 @@
 NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
 NonNullableOptOut/analyzerCode: Fail
 NonNullableOptOut/example: Fail
-NonNullableOptOutComment/spelling: Fail
 NonPartOfDirectiveInPart/part_wrapped_script1: Fail
 NonPartOfDirectiveInPart/script1: Fail
 NotAConstantExpression/example: Fail
@@ -460,14 +461,30 @@
 NullableExpressionCallError/example: Fail
 NullableExpressionCallWarning/analyzerCode: Fail
 NullableExpressionCallWarning/example: Fail
+NullableInterfaceError/analyzerCode: Fail
+NullableInterfaceError/example: Fail
+NullableInterfaceWarning/analyzerCode: Fail
+NullableInterfaceWarning/example: Fail
 NullableMethodCallError/analyzerCode: Fail
 NullableMethodCallError/example: Fail
 NullableMethodCallWarning/analyzerCode: Fail
 NullableMethodCallWarning/example: Fail
+NullableMixinError/analyzerCode: Fail
+NullableMixinError/example: Fail
+NullableMixinWarning/analyzerCode: Fail
+NullableMixinWarning/example: Fail
+NullableOperatorCallError/analyzerCode: Fail
+NullableOperatorCallError/example: Fail
+NullableOperatorCallWarning/analyzerCode: Fail
+NullableOperatorCallWarning/example: Fail
 NullablePropertyAccessError/analyzerCode: Fail
 NullablePropertyAccessError/example: Fail
 NullablePropertyAccessWarning/analyzerCode: Fail
 NullablePropertyAccessWarning/example: Fail
+NullableSuperclassError/analyzerCode: Fail
+NullableSuperclassError/example: Fail
+NullableSuperclassWarning/analyzerCode: Fail
+NullableSuperclassWarning/example: Fail
 OperatorMinusParameterMismatch/example: Fail
 OperatorParameterMismatch0/analyzerCode: Fail
 OperatorParameterMismatch0/example: Fail
@@ -475,6 +492,10 @@
 OperatorParameterMismatch2/example: Fail
 OperatorWithOptionalFormals/analyzerCode: Fail
 OperatorWithOptionalFormals/example: Fail
+OptionalNonNullableWithoutInitializerError/analyzerCode: Fail
+OptionalNonNullableWithoutInitializerError/example: Fail
+OptionalNonNullableWithoutInitializerWarning/analyzerCode: Fail
+OptionalNonNullableWithoutInitializerWarning/example: Fail
 OverrideFewerNamedArguments/example: Fail
 OverrideFewerPositionalArguments/example: Fail
 OverrideMismatchNamedParameter/example: Fail
@@ -482,6 +503,8 @@
 OverrideTypeMismatchParameter/example: Fail
 OverrideTypeMismatchReturnType/example: Fail
 OverrideTypeMismatchSetter/example: Fail
+OverrideTypeVariablesBoundMismatch/analyzerCode: Fail
+OverrideTypeVariablesBoundMismatch/example: Fail
 OverrideTypeVariablesMismatch/example: Fail
 PackageNotFound/analyzerCode: Fail
 PackageNotFound/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index e723593..48c9bee 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2021,6 +2021,9 @@
   template: "Declared type variables of '#name' doesn't match those on overridden method '#name2'."
   analyzerCode: INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS
 
+OverrideTypeVariablesBoundMismatch:
+  template: "Declared bound '#type' of type variable '#name' of '#name2' doesn't match the bound '#type2' on overridden method '#name3'."
+
 OverriddenMethodCause:
   template: "This is the overridden method ('#name')."
   severity: CONTEXT
@@ -3781,6 +3784,13 @@
   tip: "Try calling using ?.call instead."
   severity: WARNING
 
+NullableOperatorCallError:
+  template: "Operator '#name' cannot be called on '#type' because it is potentially null."
+
+NullableOperatorCallWarning:
+  template: "Operator '#name' is called on '#type' which is potentially null."
+  severity: WARNING
+
 ThrowingNotAssignableToObjectError:
   template: "Can't throw a value of '#type' since it is neither dynamic nor non-nullable."
 
@@ -3789,10 +3799,10 @@
   severity: WARNING
 
 RequiredNamedParameterHasDefaultValueError:
-  template: "Required named parameter '#name' can't have a default value."
+  template: "Named parameter '#name' is required and can't have a default value."
 
 RequiredNamedParameterHasDefaultValueWarning:
-  template: "Required named parameter '#name' has a default value."
+  template: "Named parameter '#name' is required and has a default value."
   severity: WARNING
 
 ValueForRequiredParameterNotProvidedError:
@@ -3802,6 +3812,13 @@
   template: "Missing required named parameter '#name'."
   severity: WARNING
 
+OptionalNonNullableWithoutInitializerError:
+  template: "Optional parameter '#name' should have a default value because its type '#type' doesn't allow null."
+
+OptionalNonNullableWithoutInitializerWarning:
+  template: "Optional parameter '#name' doesn't have a default value and its type '#type' doesn't allow null."
+  severity: WARNING
+
 NonNullableOptOut:
   template: "Null safety features are disabled for this library."
   tip: "Try removing the `@dart=` annotation or setting the language version to at least `@dart=2.7`."
@@ -3812,3 +3829,24 @@
 
 AwaitInLateLocalInitializer:
   template: "`await` expressions are not supported in late local initializers."
+
+NullableSuperclassError:
+  template: "Can't extend '#name' because it's marked with '?'."
+
+NullableSuperclassWarning:
+  template: "Extending '#name' marked with '?'."
+  severity: WARNING
+
+NullableInterfaceError:
+  template: "Can't implement '#name' because it's marked with '?'."
+
+NullableInterfaceWarning:
+  template: "Implementing '#name' marked with '?'."
+  severity: WARNING
+
+NullableMixinError:
+  template: "Can't mix '#name' in because it's marked with '?'."
+
+NullableMixinWarning:
+  template: "Mixing in '#name' marked with '?'."
+  severity: WARNING
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index c326659..49fd246 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -24,3 +24,5 @@
   test_reflective_loader: ^0.1.0
   web_socket_channel: ^1.0.4
   yaml: '^2.1.12'
+  vm_service:
+    path: ../vm_service
diff --git a/pkg/front_end/test/dijkstras_sssp_algorithm.dart b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
new file mode 100644
index 0000000..c3079e9
--- /dev/null
+++ b/pkg/front_end/test/dijkstras_sssp_algorithm.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2020, 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:collection';
+
+/// Dijkstra's algorithm for single source shortest path.
+///
+/// Adopted from https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocode
+///
+/// Note that this is not an optimal implementation in that it uses a
+/// (Splay) Tree as the priority queue which takes O(log n) time to (fake) a
+/// decrease of priority whereas e.g. a fibonacci heap would have done it in
+/// (amortized) O(1).
+class DijkstrasAlgorithm<E> {
+  Map<GraphNode<E>, int> dist = new Map<GraphNode<E>, int>();
+  Map<GraphNode<E>, GraphNode<E>> prev = new Map<GraphNode<E>, GraphNode<E>>();
+
+  DijkstrasAlgorithm(Iterable<GraphNode<E>> graphNodes, GraphNode<E> source,
+      int Function(E, E) comparator, int Function(E, E) distance) {
+    SplayTreeSet<GraphNode<E>> q = new SplayTreeSet<GraphNode<E>>((a, b) {
+      int distA = dist[a];
+      int distB = dist[b];
+
+      int when0() {
+        if (identical(a, b)) return 0;
+        int result = comparator(a.node, b.node);
+        if (result == 0) {
+          throw "The nodes ${b.node} and ${a.node} are not the same but "
+              "compares to the same. That's not allowed!";
+        }
+        return result;
+      }
+
+      if (distA != null && distB == null) return -1;
+      if (distA == null && distB != null) return 1;
+      if (distA == null && distB == null) {
+        return when0();
+      }
+      if (distA < distB) return -1;
+      if (distA > distB) return 1;
+      return when0();
+    });
+
+    dist[source] = 0;
+    int index = 0;
+    for (GraphNode<E> g in graphNodes) {
+      // dist and prev not set, we see "null" as "infinity" and "undefined".
+      if (!q.add(g)) {
+        throw "Couldn't add ${g.node} (index $index).";
+      }
+      index++;
+    }
+
+    while (q.isNotEmpty) {
+      GraphNode<E> u = q.first;
+      int distToU = dist[u];
+      if (distToU == null) {
+        // No path to any of the remaining ${q.length} nodes.
+        break;
+      }
+      q.remove(u);
+      for (GraphNode<E> v in u.outgoing) {
+        // Wikipedia says "only v that are still in Q" but it shouldn't matter
+        // --- the length via u would be longer.
+        int distanceUToV = distance(u.node, v.node);
+        if (distanceUToV < 0) throw "Got negative distance. That's not allowed";
+        int alt = distToU + distanceUToV;
+        int distToV = dist[v];
+        if (distToV == null || alt < distToV) {
+          // Decrease length (decrease priority in priority queue).
+          q.remove(v);
+          dist[v] = alt;
+          prev[v] = u;
+          q.add(v);
+        }
+      }
+    }
+  }
+
+  List<E> getPathFromTarget(GraphNode<E> source, GraphNode<E> target) {
+    List<E> path = new List<E>();
+    GraphNode<E> u = target;
+    while (u == source || prev[u] != null) {
+      path.add(u.node);
+      u = prev[u];
+    }
+    return path.reversed.toList();
+  }
+}
+
+class GraphNode<E> {
+  final E node;
+  final Set<GraphNode<E>> outgoing = new Set<GraphNode<E>>();
+  final Set<GraphNode<E>> incoming = new Set<GraphNode<E>>();
+
+  GraphNode(this.node);
+
+  void addOutgoing(GraphNode<E> other) {
+    if (outgoing.add(other)) {
+      other.incoming.add(this);
+    }
+  }
+
+  String toString() {
+    return "GraphNode[$node]";
+  }
+}
diff --git a/pkg/front_end/test/fasta/messages_suite.dart b/pkg/front_end/test/fasta/messages_suite.dart
index b849547..41b00d1 100644
--- a/pkg/front_end/test/fasta/messages_suite.dart
+++ b/pkg/front_end/test/fasta/messages_suite.dart
@@ -21,7 +21,7 @@
 import "package:kernel/target/targets.dart" show TargetFlags;
 
 import "package:testing/testing.dart"
-    show Chain, ChainContext, Result, Step, TestDescription, runMe;
+    show Chain, ChainContext, Expectation, Result, Step, TestDescription, runMe;
 
 import "package:vm/target/vm.dart" show VmTarget;
 
@@ -81,6 +81,15 @@
       : fileSystem = new MemoryFileSystem(Uri.parse("org-dartlang-fasta:///")),
         compiler = new BatchCompiler(null);
 
+  @override
+  Set<Expectation> processExpectedOutcomes(
+      Set<Expectation> outcomes, TestDescription description) {
+    if (description.shortName.contains("/spelling")) {
+      return {Expectation.Pass};
+    }
+    return outcomes;
+  }
+
   /// Convert all the examples found in `messages.yaml` to a test
   /// description. In addition, create a test description for each kind of
   /// problem that a message can have. This problem will then be reported as a
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 8d5bda9..0e54fb3 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -161,6 +161,14 @@
   }
 }
 
+class LinkDependenciesOptions {
+  final Set<Uri> content;
+  Component component;
+  String errors;
+
+  LinkDependenciesOptions(this.content) : assert(content != null);
+}
+
 class FastaContext extends ChainContext with MatchContext {
   final UriTranslator uriTranslator;
   final List<Step> steps;
@@ -176,6 +184,7 @@
       <Component, StringBuffer>{};
   final Uri platformBinaries;
   final Map<Uri, TestOptions> _testOptions = {};
+  final Map<Uri, LinkDependenciesOptions> _linkDependencies = {};
 
   @override
   final bool updateExpectations;
@@ -296,6 +305,33 @@
     return testOptions;
   }
 
+  /// Computes the link dependencies for [description].
+  LinkDependenciesOptions computeLinkDependenciesOptions(
+      TestDescription description) {
+    Directory directory = new File.fromUri(description.uri).parent;
+    LinkDependenciesOptions linkDependenciesOptions =
+        _linkDependencies[directory.uri];
+    if (linkDependenciesOptions == null) {
+      File optionsFile =
+          new File.fromUri(directory.uri.resolve('link.options'));
+      Set<Uri> content = new Set<Uri>();
+      if (optionsFile.existsSync()) {
+        for (String line in optionsFile.readAsStringSync().split('\n')) {
+          line = line.trim();
+          if (line.isEmpty) continue;
+          File f = new File.fromUri(description.uri.resolve(line));
+          if (!f.existsSync()) {
+            throw new UnsupportedError("No file found: $f ($line)");
+          }
+          content.add(f.uri);
+        }
+      }
+      linkDependenciesOptions = new LinkDependenciesOptions(content);
+      _linkDependencies[directory.uri] = linkDependenciesOptions;
+    }
+    return linkDependenciesOptions;
+  }
+
   Expectation get verificationError => expectationSet["VerificationError"];
 
   Future ensurePlatformUris() async {
@@ -327,7 +363,8 @@
   }
 
   @override
-  Set<Expectation> processExpectedOutcomes(Set<Expectation> outcomes) {
+  Set<Expectation> processExpectedOutcomes(
+      Set<Expectation> outcomes, TestDescription description) {
     if (skipVm && outcomes.length == 1 && outcomes.single == runtimeError) {
       return new Set<Expectation>.from([Expectation.Pass]);
     } else {
@@ -439,6 +476,8 @@
   Future<Result<Component>> run(
       TestDescription description, FastaContext context) async {
     StringBuffer errors = new StringBuffer();
+    LinkDependenciesOptions linkDependenciesOptions =
+        context.computeLinkDependenciesOptions(description);
     TestOptions testOptions = context.computeTestOptions(description);
     ProcessedOptions options = new ProcessedOptions(
         options: new CompilerOptions()
@@ -454,31 +493,44 @@
           ..performNnbdChecks = testOptions.forceNnbdChecks
           ..nnbdStrongMode = !context.weak,
         inputs: <Uri>[description.uri]);
-    return await CompilerContext.runWithOptions(options, (_) async {
-      // Disable colors to ensure that expectation files are the same across
-      // platforms and independent of stdin/stderr.
-      colors.enableColors = false;
-      Component platform = await context.loadPlatform();
-      Ticker ticker = new Ticker();
-      DillTarget dillTarget = new DillTarget(
-        ticker,
-        context.uriTranslator,
-        new TestVmTarget(new TargetFlags(
-            forceLateLoweringForTesting: testOptions.forceLateLowering)),
-      );
-      dillTarget.loader.appendLibraries(platform);
-      // We create a new URI translator to avoid reading platform libraries from
-      // file system.
-      UriTranslator uriTranslator = new UriTranslator(
-          const TargetLibrariesSpecification('vm'),
-          context.uriTranslator.packages);
-      KernelTarget sourceTarget = new KernelTarget(
-          StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
-      sourceTarget.setEntryPoints(<Uri>[description.uri]);
-      await dillTarget.buildOutlines();
-      ValidatingInstrumentation instrumentation;
-      instrumentation = new ValidatingInstrumentation();
+    // Disable colors to ensure that expectation files are the same across
+    // platforms and independent of stdin/stderr.
+    colors.enableColors = false;
+
+    if (linkDependenciesOptions.content.isNotEmpty &&
+        linkDependenciesOptions.component == null) {
+      // Compile linked dependency.
+      await CompilerContext.runWithOptions(options, (_) async {
+        KernelTarget sourceTarget = await outlineInitialization(
+            context, testOptions, linkDependenciesOptions.content.toList());
+        if (linkDependenciesOptions.errors != null) {
+          errors.write(linkDependenciesOptions.errors);
+        }
+        Component p = await sourceTarget.buildOutlines();
+        if (fullCompile) {
+          p = await sourceTarget.buildComponent(verify: context.verify);
+        }
+        linkDependenciesOptions.component = p;
+        List<Library> keepLibraries = new List<Library>();
+        for (Library lib in p.libraries) {
+          if (linkDependenciesOptions.content.contains(lib.fileUri)) {
+            keepLibraries.add(lib);
+          }
+        }
+        p.libraries.clear();
+        p.libraries.addAll(keepLibraries);
+        linkDependenciesOptions.errors = errors.toString();
+        errors.clear();
+      });
+    }
+
+    return await CompilerContext.runWithOptions(options, (_) async {
+      KernelTarget sourceTarget = await outlineInitialization(
+          context, testOptions, <Uri>[description.uri],
+          alsoAppend: linkDependenciesOptions.component);
+      ValidatingInstrumentation instrumentation =
+          new ValidatingInstrumentation();
       await instrumentation.loadExpectations(description.uri);
       sourceTarget.loader.instrumentation = instrumentation;
       Component p = await sourceTarget.buildOutlines();
@@ -488,8 +540,8 @@
       context.componentToDiagnostics[p] = errors;
       if (fullCompile) {
         p = await sourceTarget.buildComponent(verify: context.verify);
-        instrumentation?.finish();
-        if (instrumentation != null && instrumentation.hasProblems) {
+        instrumentation.finish();
+        if (instrumentation.hasProblems) {
           if (updateComments) {
             await instrumentation.fixSource(description.uri, false);
           } else {
@@ -504,6 +556,34 @@
       return pass(p);
     });
   }
+
+  Future<KernelTarget> outlineInitialization(
+      FastaContext context, TestOptions testOptions, List<Uri> entryPoints,
+      {Component alsoAppend}) async {
+    Component platform = await context.loadPlatform();
+    Ticker ticker = new Ticker();
+    DillTarget dillTarget = new DillTarget(
+      ticker,
+      context.uriTranslator,
+      new TestVmTarget(new TargetFlags(
+          forceLateLoweringForTesting: testOptions.forceLateLowering)),
+    );
+    dillTarget.loader.appendLibraries(platform);
+    if (alsoAppend != null) {
+      dillTarget.loader.appendLibraries(alsoAppend);
+    }
+    // We create a new URI translator to avoid reading platform libraries
+    // from file system.
+    UriTranslator uriTranslator = new UriTranslator(
+        const TargetLibrariesSpecification('vm'),
+        context.uriTranslator.packages);
+    KernelTarget sourceTarget = new KernelTarget(
+        StandardFileSystem.instance, false, dillTarget, uriTranslator);
+
+    sourceTarget.setEntryPoints(entryPoints);
+    await dillTarget.buildOutlines();
+    return sourceTarget;
+  }
 }
 
 class Transform extends Step<Component, Component, FastaContext> {
diff --git a/pkg/front_end/test/incremental_load_from_dill_suite.dart b/pkg/front_end/test/incremental_load_from_dill_suite.dart
index b747fd9..0f7194b 100644
--- a/pkg/front_end/test/incremental_load_from_dill_suite.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_suite.dart
@@ -4,6 +4,8 @@
 
 import 'dart:async' show Future;
 
+import 'dart:developer' show debugger;
+
 import 'dart:io' show Directory, File;
 
 import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
@@ -82,7 +84,8 @@
   // Disable colors to ensure that expectation files are the same across
   // platforms and independent of stdin/stderr.
   colors.enableColors = false;
-  return new Context(environment["updateExpectations"] == "true");
+  return new Context(environment["updateExpectations"] == "true",
+      environment["addDebugBreaks"] == "true");
 }
 
 class Context extends ChainContext {
@@ -92,7 +95,12 @@
   ];
 
   final bool updateExpectations;
-  Context(this.updateExpectations);
+
+  /// Add a debug break (via dart:developers `debugger()` call) after each
+  /// iteration (or 'world run') when doing a "new world test".
+  final bool breakBetween;
+
+  Context(this.updateExpectations, this.breakBetween);
 
   @override
   Future<void> cleanUp(TestDescription description, Result result) async {
@@ -775,6 +783,7 @@
       Component component3 = await compilerFromScratch.computeDelta(
           entryPoints: entries,
           simulateTransformer: world["simulateTransformer"]);
+      compilerFromScratch = null;
       performErrorAndWarningCheck(
           world, gotError, formattedErrors, gotWarning, formattedWarnings);
       util.throwOnEmptyMixinBodies(component3);
@@ -809,6 +818,11 @@
         newestWholeComponentData = incrementalSerializationBytes;
       }
     }
+
+    if (context.breakBetween) {
+      debugger();
+      print("Continuing after debug break");
+    }
   }
 }
 
diff --git a/pkg/front_end/test/spell_checking_list_blacklist.txt b/pkg/front_end/test/spell_checking_list_blacklist.txt
index f127418..3978cf1 100644
--- a/pkg/front_end/test/spell_checking_list_blacklist.txt
+++ b/pkg/front_end/test/spell_checking_list_blacklist.txt
@@ -6,6 +6,9 @@
 # Comments can also be inline like 'correct # this is ok'.
 # Note that at least one space before the hash is required.
 
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
 alread
 chnage
 clonable
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index ae10113..5796688 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -6,6 +6,9 @@
 # Comments can also be inline like 'correct # this is ok'.
 # Note that at least one space before the hash is required.
 
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
 a+b
 abbreviate
 abcdef
@@ -82,6 +85,7 @@
 behave
 bellow
 belonging
+beloning
 benchmark
 benchmarks
 bf
@@ -138,6 +142,7 @@
 char
 charcode
 chars
+checkpoint
 ci
 ck
 cl
@@ -416,6 +421,7 @@
 gzip
 gzipped
 h
+hadn't
 harness
 hashes
 hashing
@@ -487,6 +493,7 @@
 io
 is64
 issuecomment
+issuing
 iterables
 iterating
 iterations
@@ -503,7 +510,6 @@
 juxtaposition
 juxtapositions
 k
-k’s
 kallentu
 kernel
 kernel's
@@ -512,6 +518,7 @@
 kmillikin
 kustermann
 kv
+k’s
 l
 lacks
 lang
@@ -564,10 +571,14 @@
 me
 merely
 meta
+method10a
+method10b
 method1a
 method1b
+method1c
 method2a
 method2b
+method2c
 method3a
 method3b
 method3c
@@ -586,8 +597,6 @@
 method8b
 method9a
 method9b
-method10a
-method10b
 mi
 migration
 mime
@@ -633,6 +642,9 @@
 nullabilities
 nullability
 nullable
+nullable1
+nullable2
+nullable3
 nullary
 nulls
 o
@@ -684,6 +696,7 @@
 parens
 parenteses
 particularly
+patchup
 path
 paulberry
 pay
@@ -743,13 +756,13 @@
 quiver
 quoted
 r
+r'$creation
 r'\f
 r'\r
 r'\s
 r'\t
 r'\u
 r'\v
-r'$creation
 r0i
 r1i
 r2i
@@ -818,6 +831,7 @@
 restriction
 resumed
 ret
+reusage
 rewrites
 rewrote
 rf
@@ -1064,6 +1078,7 @@
 universally
 unlinked
 unlower
+unmark
 unordered
 unpaired
 unparsed
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index e7c6b89..25c78da 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -6,6 +6,9 @@
 # Comments can also be inline like 'correct # this is ok'.
 # Note that at least one space before the hash is required.
 
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
 a
 abbreviations
 ability
@@ -1791,6 +1794,7 @@
 mixes
 mixin
 mixin's
+mixing
 mixins
 mock
 mode
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index 1010375..888bc3d 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -6,7 +6,11 @@
 # Comments can also be inline like 'correct # this is ok'.
 # Note that at least one space before the hash is required.
 
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
 argument(s)
+assigning
 b
 c
 compilercontext.runincontext
@@ -35,6 +39,7 @@
 nosuchmethod
 num1%.3ms
 o
+opts
 part(s)
 patch(es)
 re
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 805c75b..8a63992 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -6,6 +6,9 @@
 # Comments can also be inline like 'correct # this is ok'.
 # Note that at least one space before the hash is required.
 
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
 a0x
 a1x
 a2x
@@ -14,15 +17,20 @@
 abc
 abcompile
 actions
+adopted
 affected
 albeit
 allocations
+alt
+amortized
 anon
+aoo
 approval
 approximation
 asdf
 asserter
 auth
+authority
 auto
 autobianchi
 b0x
@@ -45,6 +53,7 @@
 blindly
 blocked
 blorp
+boo
 bootstrap
 bots
 bowtie
@@ -75,6 +84,7 @@
 collisions
 commit
 companion
+comparator
 comparer
 comparisons
 compilations
@@ -89,18 +99,22 @@
 contract
 conversion
 conversions
+coo
 cov
 crashes
 cumulative
 dacoharkes
+dadd
 daemon
 dartanalyzer
 dartfile
 dashes
 day
 db
+decrease
 decrements
 def
+deleting
 depended
 depfile
 desc
@@ -109,17 +123,22 @@
 dictionaries
 dictionary
 differs
+dijkstra
+dijkstras
 dillfile
 dills
+dinteractive
 dirname
 disagree
 disallowed
 disconnect
 discovering
 dispatcher
+dist
 doctype
 doesnt
 dog
+doo
 downstream
 dumping
 dupe
@@ -134,6 +153,7 @@
 ell
 entrypoint
 entrypoints
+eoo
 epoch
 err
 everytime
@@ -170,9 +190,11 @@
 futures
 gallery
 gamma
+gc
 gen
 generators
 git
+goo
 greeting
 gtgt
 gulp
@@ -184,6 +206,7 @@
 hi
 hints
 home
+hoo
 hosting
 hot
 hotreload
@@ -198,19 +221,24 @@
 increased
 incrementally
 increments
+infinity
 inspect
 insufficient
 intact
+interactive
 internet
 interpolate
 inv
 invalidating
+ioo
 isolate
 isolates
 iter
+joo
 jumped
 kernels
 ko
+koo
 la
 lc
 ld
@@ -225,6 +253,7 @@
 ll
 logd
 logs
+loo
 loopback
 mac
 maker
@@ -243,26 +272,33 @@
 mistake
 mistakes
 month
+moo
 mx
 mysdk
 negatable
 ninja
 nonexisting
+noo
 numerator
 observable
 observatory
 oh
 okay
+ooo
+optimal
 oracle
+outbound
 overlay
 party
 pause
+paused
 periodic
 periodically
 person
 phrase
 pink
 places
+pointed
 policy
 portions
 pp
@@ -270,11 +306,13 @@
 prematurely
 pretends
 producer
+profile
 profiler
 promotes
 propagated
 protected
 provider
+pseudocode
 pubspec
 pv
 px
@@ -316,7 +354,9 @@
 sdks
 secondary
 segment
+severe
 shipped
+shortest
 shot
 signalled
 somehow
@@ -326,8 +366,10 @@
 spelled
 spelling
 spent
+splay
 splitting
 sqrt
+sssp
 std
 stdio
 strip
@@ -392,6 +434,7 @@
 whitelisting
 wins
 workflow
+ws
 x's
 xxx
 y's
diff --git a/pkg/front_end/test/spelling_test_base.dart b/pkg/front_end/test/spelling_test_base.dart
index 60c1471..9f8d58a 100644
--- a/pkg/front_end/test/spelling_test_base.dart
+++ b/pkg/front_end/test/spelling_test_base.dart
@@ -4,20 +4,20 @@
 
 import 'dart:async' show Future;
 
-import 'dart:io' show File;
+import 'dart:io' show File, Platform, stdin, stdout;
 
 import 'dart:typed_data' show Uint8List;
 
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show ErrorToken;
 
-import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
-    show Utf8BytesScanner;
-
 import 'package:_fe_analyzer_shared/src/scanner/token.dart'
     show Token, KeywordToken, BeginToken;
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 
+import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
+    show Utf8BytesScanner;
+
 import 'package:front_end/src/fasta/command_line_reporting.dart'
     as command_line_reporting;
 
@@ -33,6 +33,10 @@
     const SpellTest(),
   ];
 
+  final bool interactive;
+
+  SpellContext({this.interactive});
+
   // Override special handling of negative tests.
   @override
   Result processTestResult(
@@ -64,15 +68,91 @@
       print("================");
       print("The following word(s) were reported as unknown:");
       print("----------------");
-      for (String s in reportedWords) {
-        print("$s");
-      }
-      if (dictionaries.isNotEmpty) {
-        print("----------------");
-        print("If the word(s) are correctly spelled please add it to one of "
-            "these files:");
+
+      spell.Dictionaries dictionaryToUse;
+      if (dictionaries.contains(spell.Dictionaries.cfeTests)) {
+        dictionaryToUse = spell.Dictionaries.cfeTests;
+      } else if (dictionaries.contains(spell.Dictionaries.cfeMessages)) {
+        dictionaryToUse = spell.Dictionaries.cfeMessages;
+      } else if (dictionaries.contains(spell.Dictionaries.cfeCode)) {
+        dictionaryToUse = spell.Dictionaries.cfeCode;
+      } else {
         for (spell.Dictionaries dictionary in dictionaries) {
-          print(" - ${spell.dictionaryToUri(dictionary)}");
+          if (dictionaryToUse == null ||
+              dictionary.index < dictionaryToUse.index) {
+            dictionaryToUse = dictionary;
+          }
+        }
+      }
+
+      if (interactive && dictionaryToUse != null) {
+        List<String> addedWords = new List<String>();
+        for (String s in reportedWords) {
+          print("- $s");
+          stdout.write("Do you want to add the word to the dictionary "
+              "$dictionaryToUse (y/n)? ");
+          String answer = stdin.readLineSync().trim().toLowerCase();
+          bool add;
+          switch (answer) {
+            case "y":
+            case "yes":
+            case "true":
+              add = true;
+              break;
+            case "n":
+            case "no":
+            case "false":
+              add = false;
+              break;
+            default:
+              throw "Didn't understand '$answer'";
+          }
+          if (add) {
+            addedWords.add(s);
+          }
+        }
+        if (addedWords.isNotEmpty) {
+          File dictionaryFile =
+              new File.fromUri(spell.dictionaryToUri(dictionaryToUse));
+          List<String> lines = dictionaryFile.readAsLinesSync();
+          List<String> header = new List<String>();
+          List<String> sortThis = new List<String>();
+          for (String line in lines) {
+            if (line.startsWith("#")) {
+              header.add(line);
+            } else if (line.trim().isEmpty && sortThis.isEmpty) {
+              header.add(line);
+            } else if (line.trim().isNotEmpty) {
+              sortThis.add(line);
+            }
+          }
+          sortThis.addAll(addedWords);
+          sortThis.sort();
+          lines = new List<String>();
+          lines.addAll(header);
+          if (header.isEmpty || header.last.isNotEmpty) {
+            lines.add("");
+          }
+          lines.addAll(sortThis);
+          lines.add("");
+          dictionaryFile.writeAsStringSync(lines.join("\n"));
+        }
+      } else {
+        for (String s in reportedWords) {
+          print("$s");
+        }
+        if (dictionaries.isNotEmpty) {
+          print("----------------");
+          print("If the word(s) are correctly spelled please add it to one of "
+              "these files:");
+          for (spell.Dictionaries dictionary in dictionaries) {
+            print(" - ${spell.dictionaryToUri(dictionary)}");
+          }
+
+          print("");
+          print("To add words easily, try to run this script in interactive "
+              "mode via the command");
+          print("dart ${Platform.script.toFilePath()} -Dinteractive=true");
         }
       }
       print("================");
diff --git a/pkg/front_end/test/spelling_test_external_targets.dart b/pkg/front_end/test/spelling_test_external_targets.dart
index 4f532a2..12a601b 100644
--- a/pkg/front_end/test/spelling_test_external_targets.dart
+++ b/pkg/front_end/test/spelling_test_external_targets.dart
@@ -18,10 +18,13 @@
 
 Future<SpellContext> createContext(
     Chain suite, Map<String, String> environment) async {
-  return new SpellContextExternal();
+  bool interactive = environment["interactive"] == "true";
+  return new SpellContextExternal(interactive: interactive);
 }
 
 class SpellContextExternal extends SpellContext {
+  SpellContextExternal({bool interactive}) : super(interactive: interactive);
+
   @override
   List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[];
 
diff --git a/pkg/front_end/test/spelling_test_not_src_suite.dart b/pkg/front_end/test/spelling_test_not_src_suite.dart
index f281d14..a67d668 100644
--- a/pkg/front_end/test/spelling_test_not_src_suite.dart
+++ b/pkg/front_end/test/spelling_test_not_src_suite.dart
@@ -15,10 +15,13 @@
 
 Future<SpellContext> createContext(
     Chain suite, Map<String, String> environment) async {
-  return new SpellContextTest();
+  bool interactive = environment["interactive"] == "true";
+  return new SpellContextTest(interactive: interactive);
 }
 
 class SpellContextTest extends SpellContext {
+  SpellContextTest({bool interactive}) : super(interactive: interactive);
+
   @override
   List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[
         spell.Dictionaries.common,
diff --git a/pkg/front_end/test/spelling_test_src_suite.dart b/pkg/front_end/test/spelling_test_src_suite.dart
index 12f5dcb..39c42f3 100644
--- a/pkg/front_end/test/spelling_test_src_suite.dart
+++ b/pkg/front_end/test/spelling_test_src_suite.dart
@@ -15,10 +15,13 @@
 
 Future<SpellContext> createContext(
     Chain suite, Map<String, String> environment) async {
-  return new SpellContextSource();
+  bool interactive = environment["interactive"] == "true";
+  return new SpellContextSource(interactive: interactive);
 }
 
 class SpellContextSource extends SpellContext {
+  SpellContextSource({bool interactive}) : super(interactive: interactive);
+
   @override
   List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[
         spell.Dictionaries.common,
diff --git a/pkg/front_end/test/static_types/data/if_null.dart b/pkg/front_end/test/static_types/data/if_null.dart
index 86c65a4..2f38469 100644
--- a/pkg/front_end/test/static_types/data/if_null.dart
+++ b/pkg/front_end/test/static_types/data/if_null.dart
@@ -78,11 +78,11 @@
 test7(A7? a) {
   var s =
       (/*A7?*/ a?. /*String!*/ /*update: String!*/ foo ??= /*String!*/ "bar");
-  /*String!*/ s;
+  /*String?*/ s;
 
   var s2 =
       (/*A7?*/ a?. /*String?*/ /*update: String!*/ bar ??= /*String!*/ "bar");
-  /*String!*/ s2;
+  /*String?*/ s2;
 }
 
 main() {}
diff --git a/pkg/front_end/test/vm_service_for_leak_detection.dart b/pkg/front_end/test/vm_service_for_leak_detection.dart
new file mode 100644
index 0000000..c1819e2
--- /dev/null
+++ b/pkg/front_end/test/vm_service_for_leak_detection.dart
@@ -0,0 +1,39 @@
+import 'dart:io';
+
+import "vm_service_heap_helper.dart" as helper;
+
+main(List<String> args) async {
+  List<helper.Interest> interests = new List<helper.Interest>();
+  interests.add(new helper.Interest(
+      Uri.parse(
+          "package:front_end/src/fasta/source/source_library_builder.dart"),
+      "SourceLibraryBuilder",
+      ["fileUri"]));
+  interests.add(new helper.Interest(
+      Uri.parse(
+          "package:front_end/src/fasta/source/source_extension_builder.dart"),
+      "SourceExtensionBuilder",
+      ["_extension"]));
+  helper.VMServiceHeapHelper heapHelper = new helper.VMServiceHeapHelper(
+      interests,
+      [
+        new helper.Interest(
+            Uri.parse(
+                "package:front_end/src/fasta/source/source_extension_builder.dart"),
+            "SourceExtensionBuilder",
+            ["_extension"]),
+        new helper.Interest(Uri.parse("package:kernel/ast.dart"), "Extension",
+            ["name", "fileUri"]),
+      ],
+      false);
+  heapHelper.start([
+    Platform.script.resolve("incremental_load_from_dill_suite.dart").toString(),
+    "-DaddDebugBreaks=true",
+    // "--",
+    // "incremental_load_from_dill/no_outline_change_34"
+    // "incremental_load_from_dill/no_outline_change_10"
+    "incremental_load_from_dill/deleting_file"
+    // "incremental_load_from_dill/no_outline_change_2"
+    // "incremental_load_from_dill/incremental_serialization_1"
+  ]);
+}
diff --git a/pkg/front_end/test/vm_service_heap_helper.dart b/pkg/front_end/test/vm_service_heap_helper.dart
new file mode 100644
index 0000000..56cb578
--- /dev/null
+++ b/pkg/front_end/test/vm_service_heap_helper.dart
@@ -0,0 +1,491 @@
+import "dart:convert";
+import "dart:io";
+
+import "package:vm_service/vm_service.dart" as vmService;
+import "package:vm_service/vm_service_io.dart" as vmService;
+
+import "dijkstras_sssp_algorithm.dart";
+
+class VMServiceHeapHelper {
+  Process _process;
+  vmService.VmService _serviceClient;
+  bool _started = false;
+  final Map<Uri, Map<String, List<String>>> _interests =
+      new Map<Uri, Map<String, List<String>>>();
+  final Map<Uri, Map<String, List<String>>> _prettyPrints =
+      new Map<Uri, Map<String, List<String>>>();
+  final bool throwOnPossibleLeak;
+
+  VMServiceHeapHelper(List<Interest> interests, List<Interest> prettyPrints,
+      this.throwOnPossibleLeak) {
+    if (interests.isEmpty) throw "Empty list of interests given";
+    for (Interest interest in interests) {
+      Map<String, List<String>> classToFields = _interests[interest.uri];
+      if (classToFields == null) {
+        classToFields = Map<String, List<String>>();
+        _interests[interest.uri] = classToFields;
+      }
+      List<String> fields = classToFields[interest.className];
+      if (fields == null) {
+        fields = new List<String>();
+        classToFields[interest.className] = fields;
+      }
+      fields.addAll(interest.fieldNames);
+    }
+    for (Interest interest in prettyPrints) {
+      Map<String, List<String>> classToFields = _prettyPrints[interest.uri];
+      if (classToFields == null) {
+        classToFields = Map<String, List<String>>();
+        _prettyPrints[interest.uri] = classToFields;
+      }
+      List<String> fields = classToFields[interest.className];
+      if (fields == null) {
+        fields = new List<String>();
+        classToFields[interest.className] = fields;
+      }
+      fields.addAll(interest.fieldNames);
+    }
+  }
+
+  void start(List<String> scriptAndArgs) async {
+    if (_started) throw "Already started";
+    _started = true;
+    _process = await Process.start(
+        Platform.resolvedExecutable,
+        ["--pause_isolates_on_start", "--enable-vm-service=0"]
+          ..addAll(scriptAndArgs));
+    _process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      const kObservatoryListening = 'Observatory listening on ';
+      if (line.startsWith(kObservatoryListening)) {
+        Uri observatoryUri =
+            Uri.parse(line.substring(kObservatoryListening.length));
+        _gotObservatoryUri(observatoryUri);
+      }
+      stdout.writeln("> $line");
+    });
+    _process.stderr
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      stderr.writeln("> $line");
+    });
+  }
+
+  void _gotObservatoryUri(Uri observatoryUri) async {
+    String wsUriString =
+        'ws://${observatoryUri.authority}${observatoryUri.path}ws';
+    _serviceClient = await vmService.vmServiceConnectUri(wsUriString,
+        log: const StdOutLog());
+    await _run();
+  }
+
+  void _run() async {
+    vmService.VM vm = await _serviceClient.getVM();
+    if (vm.isolates.length != 1) {
+      throw "Expected 1 isolate, got ${vm.isolates.length}";
+    }
+    vmService.IsolateRef isolateRef = vm.isolates.single;
+    await _forceGC(isolateRef.id);
+
+    assert(await _isPausedAtStart(isolateRef.id));
+    await _serviceClient.resume(isolateRef.id);
+
+    int iterationNumber = 1;
+    while (true) {
+      await _waitUntilPaused(isolateRef.id);
+      print("Iteration: #$iterationNumber");
+      iterationNumber++;
+      await _forceGC(isolateRef.id);
+
+      vmService.HeapSnapshotGraph heapSnapshotGraph =
+          await vmService.HeapSnapshotGraph.getSnapshot(
+              _serviceClient, isolateRef);
+      HeapGraph graph = convertHeapGraph(heapSnapshotGraph);
+
+      Set<String> seenPrints = {};
+      Set<String> duplicatePrints = {};
+      Map<String, List<HeapGraphElement>> groupedByToString = {};
+      for (HeapGraphClassActual c in graph.classes) {
+        Map<String, List<String>> interests = _interests[c.libraryUri];
+        if (interests != null && interests.isNotEmpty) {
+          List<String> fieldsToUse = interests[c.name];
+          if (fieldsToUse != null && fieldsToUse.isNotEmpty) {
+            for (HeapGraphElement instance in c.instances) {
+              StringBuffer sb = new StringBuffer();
+              sb.writeln("Instance: ${instance}");
+              if (instance is HeapGraphElementActual) {
+                for (String fieldName in fieldsToUse) {
+                  String prettyPrinted = instance
+                      .getField(fieldName)
+                      .getPrettyPrint(_prettyPrints);
+                  sb.writeln("  $fieldName: "
+                      "${prettyPrinted}");
+                }
+              }
+              String sbToString = sb.toString();
+              print(sbToString);
+              if (!seenPrints.add(sbToString)) {
+                duplicatePrints.add(sbToString);
+              }
+              groupedByToString[sbToString] ??= [];
+              groupedByToString[sbToString].add(instance);
+            }
+          }
+        }
+      }
+      if (duplicatePrints.isNotEmpty) {
+        print("======================================");
+        print("WARNING: Duplicated pretty prints of objects.");
+        print("This might be a memory leak!");
+        print("");
+        for (String s in duplicatePrints) {
+          print("$s");
+          print("");
+        }
+        print("======================================");
+        for (String duplicateString in duplicatePrints) {
+          print("$duplicateString:");
+          List<HeapGraphElement> Function(HeapGraphElement target)
+              dijkstraTarget = dijkstra(graph.elements.first, graph);
+          for (HeapGraphElement duplicate
+              in groupedByToString[duplicateString]) {
+            print("${duplicate} pointed to from:");
+            List<HeapGraphElement> shortestPath = dijkstraTarget(duplicate);
+            for (int i = 0; i < shortestPath.length - 1; i++) {
+              HeapGraphElement thisOne = shortestPath[i];
+              HeapGraphElement nextOne = shortestPath[i + 1];
+              String indexFieldName;
+              if (thisOne is HeapGraphElementActual) {
+                HeapGraphClass c = thisOne.class_;
+                if (c is HeapGraphClassActual) {
+                  for (vmService.HeapSnapshotField field in c.origin.fields) {
+                    if (thisOne.references[field.index] == nextOne) {
+                      indexFieldName = field.name;
+                    }
+                  }
+                }
+              }
+              if (indexFieldName == null) {
+                indexFieldName = "no field found; index "
+                    "${thisOne.references.indexOf(nextOne)}";
+              }
+              print("  $thisOne -> $nextOne ($indexFieldName)");
+            }
+            print("---------------------------");
+          }
+        }
+
+        if (throwOnPossibleLeak) throw "Possible leak detected.";
+      }
+      await _serviceClient.resume(isolateRef.id);
+    }
+  }
+
+  List<HeapGraphElement> Function(HeapGraphElement target) dijkstra(
+      HeapGraphElement source, HeapGraph heapGraph) {
+    Map<HeapGraphElement, int> elementNum = {};
+    Map<HeapGraphElement, GraphNode<HeapGraphElement>> elements = {};
+    elements[heapGraph.elementSentinel] =
+        new GraphNode<HeapGraphElement>(heapGraph.elementSentinel);
+    elementNum[heapGraph.elementSentinel] = elements.length;
+    for (HeapGraphElementActual element in heapGraph.elements) {
+      elements[element] = new GraphNode<HeapGraphElement>(element);
+      elementNum[element] = elements.length;
+    }
+
+    for (HeapGraphElementActual element in heapGraph.elements) {
+      GraphNode<HeapGraphElement> node = elements[element];
+      for (HeapGraphElement out in element.references) {
+        node.addOutgoing(elements[out]);
+      }
+    }
+
+    DijkstrasAlgorithm<HeapGraphElement> result =
+        new DijkstrasAlgorithm<HeapGraphElement>(
+      elements.values,
+      elements[source],
+      (HeapGraphElement a, HeapGraphElement b) {
+        if (identical(a, b)) {
+          throw "Comparing two identical ones was unexpected";
+        }
+        return elementNum[a] - elementNum[b];
+      },
+      (HeapGraphElement a, HeapGraphElement b) {
+        if (identical(a, b)) return 0;
+        // Prefer not to go via sentinel and via "Context".
+        if (b is HeapGraphElementSentinel) return 100;
+        HeapGraphElementActual bb = b;
+        if (bb.class_ is HeapGraphClassSentinel) return 100;
+        HeapGraphClassActual c = bb.class_;
+        if (c.name == "Context") {
+          if (c.libraryUri.toString().isEmpty) return 100;
+        }
+        return 1;
+      },
+    );
+
+    return (HeapGraphElement target) {
+      return result.getPathFromTarget(elements[source], elements[target]);
+    };
+  }
+
+  Future<void> _waitUntilPaused(String isolateId) async {
+    int nulls = 0;
+    while (true) {
+      bool result = await _isPaused(isolateId);
+      if (result == null) {
+        nulls++;
+        if (nulls > 5) {
+          // We've now asked for the isolate 5 times and in all cases gotten
+          // `Sentinel`. Most likely things aren't working for whatever reason.
+          return;
+        }
+      } else if (result) {
+        return;
+      } else {
+        await Future.delayed(const Duration(milliseconds: 100));
+      }
+    }
+  }
+
+  Future<bool> _isPaused(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      if (isolate.pauseEvent.kind != "Resume") return true;
+      return false;
+    }
+    return null;
+  }
+
+  Future<bool> _isPausedAtStart(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.pauseEvent.kind == "PauseStart";
+    }
+    return false;
+  }
+
+  Future<void> _forceGC(String isolateId) async {
+    await _waitUntilIsolateIsRunnable(isolateId);
+    int expectGcAfter = new DateTime.now().millisecondsSinceEpoch;
+    while (true) {
+      vmService.AllocationProfile allocationProfile =
+          await _serviceClient.getAllocationProfile(isolateId, gc: true);
+      if (allocationProfile.dateLastServiceGC != null &&
+          allocationProfile.dateLastServiceGC >= expectGcAfter) {
+        return;
+      }
+    }
+  }
+
+  Future<bool> _isIsolateRunnable(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.runnable;
+    }
+    return null;
+  }
+
+  Future<void> _waitUntilIsolateIsRunnable(String isolateId) async {
+    int nulls = 0;
+    while (true) {
+      bool result = await _isIsolateRunnable(isolateId);
+      if (result == null) {
+        nulls++;
+        if (nulls > 5) {
+          // We've now asked for the isolate 5 times and in all cases gotten
+          // `Sentinel`. Most likely things aren't working for whatever reason.
+          return;
+        }
+      } else if (result) {
+        return;
+      } else {
+        await Future.delayed(const Duration(milliseconds: 100));
+      }
+    }
+  }
+}
+
+class Interest {
+  final Uri uri;
+  final String className;
+  final List<String> fieldNames;
+
+  Interest(this.uri, this.className, this.fieldNames);
+}
+
+class StdOutLog implements vmService.Log {
+  const StdOutLog();
+
+  @override
+  void severe(String message) {
+    print("> SEVERE: $message");
+  }
+
+  @override
+  void warning(String message) {
+    print("> WARNING: $message");
+  }
+}
+
+HeapGraph convertHeapGraph(vmService.HeapSnapshotGraph graph) {
+  HeapGraphClassSentinel classSentinel = new HeapGraphClassSentinel();
+  List<HeapGraphClassActual> classes = [];
+  for (int i = 0; i < graph.classes.length; i++) {
+    vmService.HeapSnapshotClass c = graph.classes[i];
+    classes.add(new HeapGraphClassActual(c));
+  }
+
+  HeapGraphElementSentinel elementSentinel = new HeapGraphElementSentinel();
+  List<HeapGraphElementActual> elements = [];
+  for (int i = 0; i < graph.objects.length; i++) {
+    vmService.HeapSnapshotObject o = graph.objects[i];
+    elements.add(new HeapGraphElementActual(o));
+  }
+
+  for (int i = 0; i < graph.objects.length; i++) {
+    vmService.HeapSnapshotObject o = graph.objects[i];
+    HeapGraphElementActual converted = elements[i];
+    if (o.classId == 0) {
+      converted.class_ = classSentinel;
+    } else {
+      converted.class_ = classes[o.classId - 1];
+    }
+    converted.class_.instances.add(converted);
+    for (int refId in o.references) {
+      HeapGraphElement ref;
+      if (refId == 0) {
+        ref = elementSentinel;
+      } else {
+        ref = elements[refId - 1];
+      }
+      converted.references.add(ref);
+      ref.referenced.add(converted);
+    }
+  }
+
+  return new HeapGraph(classSentinel, classes, elementSentinel, elements);
+}
+
+class HeapGraph {
+  final HeapGraphClassSentinel classSentinel;
+  final List<HeapGraphClassActual> classes;
+  final HeapGraphElementSentinel elementSentinel;
+  final List<HeapGraphElementActual> elements;
+
+  HeapGraph(
+      this.classSentinel, this.classes, this.elementSentinel, this.elements);
+}
+
+abstract class HeapGraphElement {
+  /// Outbound references, i.e. this element points to elements in this list.
+  List<HeapGraphElement> references = [];
+
+  /// Inbound references, i.e. this element is pointed to by these elements.
+  Set<HeapGraphElement> referenced = {};
+
+  String getPrettyPrint(Map<Uri, Map<String, List<String>>> prettyPrints) {
+    if (this is HeapGraphElementActual) {
+      HeapGraphElementActual me = this;
+      if (me.class_.toString() == "_OneByteString") {
+        return '"${me.origin.data}"';
+      }
+      if (me.class_.toString() == "_SimpleUri") {
+        return "_SimpleUri["
+            "${me.getField("_uri").getPrettyPrint(prettyPrints)}]";
+      }
+      if (me.class_.toString() == "_Uri") {
+        return "_Uri[${me.getField("scheme").getPrettyPrint(prettyPrints)}:"
+            "${me.getField("path").getPrettyPrint(prettyPrints)}]";
+      }
+      if (me.class_ is HeapGraphClassActual) {
+        HeapGraphClassActual c = me.class_;
+        Map<String, List<String>> classToFields = prettyPrints[c.libraryUri];
+        if (classToFields != null) {
+          List<String> fields = classToFields[c.name];
+          if (fields != null) {
+            return "${c.name}[" +
+                fields.map((field) {
+                  return "$field: ${me.getField(field).getPrettyPrint(prettyPrints)}";
+                }).join(", ") +
+                "]";
+          }
+        }
+      }
+    }
+    return toString();
+  }
+}
+
+class HeapGraphElementSentinel extends HeapGraphElement {
+  String toString() => "HeapGraphElementSentinel";
+}
+
+class HeapGraphElementActual extends HeapGraphElement {
+  final vmService.HeapSnapshotObject origin;
+  HeapGraphClass class_;
+
+  HeapGraphElementActual(this.origin);
+
+  HeapGraphElement getField(String name) {
+    if (class_ is HeapGraphClassActual) {
+      HeapGraphClassActual c = class_;
+      for (vmService.HeapSnapshotField field in c.origin.fields) {
+        if (field.name == name) {
+          return references[field.index];
+        }
+      }
+    }
+    return null;
+  }
+
+  List<MapEntry<String, HeapGraphElement>> getFields() {
+    List<MapEntry<String, HeapGraphElement>> result = [];
+    if (class_ is HeapGraphClassActual) {
+      HeapGraphClassActual c = class_;
+      for (vmService.HeapSnapshotField field in c.origin.fields) {
+        result.add(new MapEntry(field.name, references[field.index]));
+      }
+    }
+    return result;
+  }
+
+  String toString() {
+    if (origin.data is vmService.HeapSnapshotObjectNoData) {
+      return "Instance of $class_";
+    }
+    if (origin.data is vmService.HeapSnapshotObjectLengthData) {
+      vmService.HeapSnapshotObjectLengthData data = origin.data;
+      return "Instance of $class_ length = ${data.length}";
+    }
+    return "Instance of $class_; data: '${origin.data}'";
+  }
+}
+
+abstract class HeapGraphClass {
+  List<HeapGraphElement> instances = [];
+}
+
+class HeapGraphClassSentinel extends HeapGraphClass {
+  String toString() => "HeapGraphClassSentinel";
+}
+
+class HeapGraphClassActual extends HeapGraphClass {
+  final vmService.HeapSnapshotClass origin;
+
+  HeapGraphClassActual(this.origin) {
+    assert(origin != null);
+  }
+
+  String get name => origin.name;
+
+  Uri get libraryUri => origin.libraryUri;
+
+  String toString() => name;
+}
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/link.options b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/link.options
new file mode 100644
index 0000000..0785ad4
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/link.options
@@ -0,0 +1 @@
+variance_from_dill_lib.dart
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart
new file mode 100644
index 0000000..9007356
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart
@@ -0,0 +1,6 @@
+import "variance_from_dill_lib.dart";
+typedef G<T> = Function(F<T>);
+
+main() {
+  print(G);
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill_lib.dart b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill_lib.dart
new file mode 100644
index 0000000..3c62f22
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill_lib.dart
@@ -0,0 +1 @@
+typedef F<T> = Function();
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
index 10b94fd..1b66228 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
@@ -9,13 +9,31 @@
   - entry: main.dart
     sources:
       main.dart: |
+        import "lib.dart";
+        void main() {
+          var c = new C.e4();
+        }
+      lib.dart: |
         class C {
           C();
           factory C.e4() async = C;
         }
-
+    expectedLibraryCount: 2
+    errors: true
+  - entry: main.dart
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        import "lib.dart";
         void main() {
           var c = new C.e4();
+          print(c);
         }
-    expectedLibraryCount: 1
+      lib.dart: |
+        class C {
+          C();
+          factory C.e4() async = C;
+        }
+    expectedLibraryCount: 2
     errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.1.expect
index 10227fc..bd5a25a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.1.expect
@@ -1,63 +1,27 @@
 main = <No Member>;
-library from "org-dartlang-test:///main.dart" as main {
+library from "org-dartlang-test:///lib.dart" as lib {
 //
 // Problems in library:
 //
-// org-dartlang-test:///main.dart:3:11: Error: Functions marked 'async' must have a return type assignable to 'Future'.
-//   factory C.e4() async = C;
-//           ^^
-//
-// org-dartlang-test:///main.dart:3:18: Error: Factory bodies can't use 'async', 'async*', or 'sync*'.
+// org-dartlang-test:///lib.dart:3:18: Error: Factory bodies can't use 'async', 'async*', or 'sync*'.
 //   factory C.e4() async = C;
 //                  ^^^^^
 //
-// org-dartlang-test:///main.dart:3:24: Error: Expected a function body or '=>'.
-// Try adding {}.
-//   factory C.e4() async = C;
-//                        ^
-//
-// org-dartlang-test:///main.dart:3:26: Error: A value of type 'Type' can't be assigned to a variable of type 'FutureOr<C>'.
-//  - 'Type' is from 'dart:core'.
-//  - 'FutureOr' is from 'dart:async'.
-//  - 'C' is from 'org-dartlang-test:///main.dart'.
-//   factory C.e4() async = C;
-//                          ^
-//
 
   class C extends dart.core::Object {
-    static field dynamic _redirecting# = <dynamic>[main::C::e4];
-    constructor •() → main::C*
+    static field dynamic _redirecting# = <dynamic>[lib::C::e4];
+    constructor •() → lib::C*
       : super dart.core::Object::•()
       ;
-    static factory e4() → main::C* /* originally async */ {
-      final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
-      dart.async::FutureOr<dynamic>* :return_value;
-      dynamic :async_stack_trace;
-      dynamic :async_op_then;
-      dynamic :async_op_error;
-      dart.core::int* :await_jump_var = 0;
-      dynamic :await_ctx_var;
-      function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
-        try {
-          #L1:
-          {
-            :return_value = let final<BottomType> #t1 = invalid-expression "org-dartlang-test:///main.dart:3:26: Error: A value of type 'Type' can't be assigned to a variable of type 'FutureOr<C>'.\n - 'Type' is from 'dart:core'.\n - 'FutureOr' is from 'dart:async'.\n - 'C' is from 'org-dartlang-test:///main.dart'.\n  factory C.e4() async = C;\n                         ^" in main::C* as{TypeError} dart.async::FutureOr<main::C*>*;
-            break #L1;
-          }
-          dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
-          return;
-        }
-        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
-          :async_completer.{dart.async::Completer::completeError}(:exception, :stack_trace);
-        }
-      :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
-      :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
-      :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-      :async_completer.start(:async_op);
-      return :async_completer.{dart.async::Completer::future};
-    }
+    static factory e4() → lib::C*
+      let dynamic #redirecting_factory = lib::C::• in invalid-expression;
   }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///lib.dart";
+
   static method main() → void {
-    main::C* c = main::C::e4();
+    lib::C* c = new lib::C::•();
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.2.expect
new file mode 100644
index 0000000..8ef39f6
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml.world.2.expect
@@ -0,0 +1,28 @@
+main = <No Member>;
+library from "org-dartlang-test:///lib.dart" as lib {
+//
+// Problems in library:
+//
+// org-dartlang-test:///lib.dart:3:18: Error: Factory bodies can't use 'async', 'async*', or 'sync*'.
+//   factory C.e4() async = C;
+//                  ^^^^^
+//
+
+  class C extends dart.core::Object {
+    static field dynamic _redirecting# = <dynamic>[lib::C::e4];
+    constructor •() → lib::C*
+      : super dart.core::Object::•()
+      ;
+    static factory e4() → lib::C*
+      let dynamic #redirecting_factory = lib::C::• in invalid-expression;
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///lib.dart";
+
+  static method main() → void {
+    lib::C* c = new lib::C::•();
+    dart.core::print(c);
+  }
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart b/pkg/front_end/testcases/late_lowering/issue40093.dart
new file mode 100644
index 0000000..a3cd00e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, 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.
+
+error() {
+  for (late int i = 0; i < 10; ++i) {
+    print(i);
+  }
+  for (late int i in <int>[]) {
+    print(i);
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.outline.expect
new file mode 100644
index 0000000..755fbee
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method error() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.expect
new file mode 100644
index 0000000..27df1f8
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  for (core::int i in <core::int>[]) {
+    core::print(i);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect
new file mode 100644
index 0000000..41e1503
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  {
+    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      core::int i = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::print(i);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.expect
new file mode 100644
index 0000000..27df1f8
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  for (core::int i in <core::int>[]) {
+    core::print(i);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect
new file mode 100644
index 0000000..41e1503
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/late_lowering/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  {
+    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      core::int i = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::print(i);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
index 6252495..f4f95e3 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.expect
@@ -12,7 +12,7 @@
       return lateLocal = #t2;
     else
       throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has already been initialized.");
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
@@ -28,7 +28,7 @@
         #lateGenericLocal#isSet = true;
         return lateGenericLocal = #t3;
       }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
     self::throws(() → T% => #lateGenericLocal#set.call(value), "Write value to initialized lateGenericLocal");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
index 6252495..f4f95e3 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.strong.transformed.expect
@@ -12,7 +12,7 @@
       return lateLocal = #t2;
     else
       throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has already been initialized.");
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
@@ -28,7 +28,7 @@
         #lateGenericLocal#isSet = true;
         return lateGenericLocal = #t3;
       }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
     self::throws(() → T% => #lateGenericLocal#set.call(value), "Write value to initialized lateGenericLocal");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
index 6252495..f4f95e3 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.expect
@@ -12,7 +12,7 @@
       return lateLocal = #t2;
     else
       throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has already been initialized.");
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
@@ -28,7 +28,7 @@
         #lateGenericLocal#isSet = true;
         return lateGenericLocal = #t3;
       }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
     self::throws(() → T% => #lateGenericLocal#set.call(value), "Write value to initialized lateGenericLocal");
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
index 6252495..f4f95e3 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
       return lateLocal = #t2;
     else
       throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has already been initialized.");
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   self::throws(() → core::int => #lateLocal#set.call(124), "Write value to initialized lateLocal");
@@ -28,7 +28,7 @@
         #lateGenericLocal#isSet = true;
         return lateGenericLocal = #t3;
       }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
     self::throws(() → T% => #lateGenericLocal#set.call(value), "Write value to initialized lateGenericLocal");
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
index 283f7ef..7f4cd1b 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.expect
@@ -9,7 +9,7 @@
     return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has not been initialized.") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
     return lateLocal = #t2;
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → core::Null? {
@@ -21,7 +21,7 @@
       #lateGenericLocal#isSet = true;
       return lateGenericLocal = #t3;
     }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
   }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
index 283f7ef..7f4cd1b 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
     return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has not been initialized.") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
     return lateLocal = #t2;
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → core::Null? {
@@ -21,7 +21,7 @@
       #lateGenericLocal#isSet = true;
       return lateGenericLocal = #t3;
     }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
   }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
index 283f7ef..7f4cd1b 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.expect
@@ -9,7 +9,7 @@
     return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has not been initialized.") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
     return lateLocal = #t2;
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → core::Null? {
@@ -21,7 +21,7 @@
       #lateGenericLocal#isSet = true;
       return lateGenericLocal = #t3;
     }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
   }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
index 283f7ef..7f4cd1b 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.weak.transformed.expect
@@ -9,7 +9,7 @@
     return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Local 'lateLocal' has not been initialized.") : #t1{core::int};
   function #lateLocal#set(core::int #t2) → dynamic
     return lateLocal = #t2;
-  self::throws(() → core::int? => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
+  self::throws(() → core::int => #lateLocal#get.call(), "Read value from uninitialized lateLocal");
   self::expect(123, #lateLocal#set.call(123));
   self::expect(123, #lateLocal#get.call());
   function local<T extends core::Object? = dynamic>(T% value) → core::Null? {
@@ -21,7 +21,7 @@
       #lateGenericLocal#isSet = true;
       return lateGenericLocal = #t3;
     }
-    self::throws(() → T? => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
+    self::throws(() → T% => #lateGenericLocal#get.call(), "Read value from uninitialized lateGenericLocal");
     self::expect(value, #lateGenericLocal#set.call(value));
     self::expect(value, #lateGenericLocal#get.call());
   }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart b/pkg/front_end/testcases/late_lowering/return_late.dart
new file mode 100644
index 0000000..04fc076
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class<E> {
+  final E field;
+
+  Class(this.field);
+
+  E returnTypeVariable() {
+    late E result = field;
+    return result;
+  }
+}
+
+int returnNonNullable(int value) {
+  late int result = value;
+  return result;
+}
+
+int? returnNullable(int? value) {
+  late int? result = value;
+  return result;
+}
+
+main() {
+  expect(42, new Class<int>(42).returnTypeVariable());
+  expect(87, new Class<int?>(87).returnTypeVariable());
+  expect(null, new Class<int?>(null).returnTypeVariable());
+  expect(42, returnNonNullable(42));
+  expect(87, returnNullable(87));
+  expect(null, returnNullable(null));
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.outline.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.outline.expect
new file mode 100644
index 0000000..b09c8c1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.outline.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    ;
+  method returnTypeVariable() → self::Class::E%
+    ;
+}
+static method returnNonNullable(core::int value) → core::int
+  ;
+static method returnNullable(core::int? value) → core::int?
+  ;
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
new file mode 100644
index 0000000..2a08564
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    self::Class::E? result;
+    core::bool #result#isSet = false;
+    function #result#get() → self::Class::E% {
+      if(!#result#isSet) {
+        #result#isSet = true;
+        result = this.{self::Class::field};
+      }
+      return result{self::Class::E%};
+    }
+    function #result#set(self::Class::E% #t1) → dynamic {
+      #result#isSet = true;
+      return result = #t1;
+    }
+    return #result#get.call();
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  core::int? result;
+  function #result#get() → core::int
+    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+  function #result#set(core::int #t3) → dynamic
+    return result = #t3;
+  return #result#get.call();
+}
+static method returnNullable(core::int? value) → core::int? {
+  core::int? result;
+  core::bool #result#isSet = false;
+  function #result#get() → core::int? {
+    if(!#result#isSet) {
+      #result#isSet = true;
+      result = value;
+    }
+    return result;
+  }
+  function #result#set(core::int? #t4) → dynamic {
+    #result#isSet = true;
+    return result = #t4;
+  }
+  return #result#get.call();
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
new file mode 100644
index 0000000..2a08564
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    self::Class::E? result;
+    core::bool #result#isSet = false;
+    function #result#get() → self::Class::E% {
+      if(!#result#isSet) {
+        #result#isSet = true;
+        result = this.{self::Class::field};
+      }
+      return result{self::Class::E%};
+    }
+    function #result#set(self::Class::E% #t1) → dynamic {
+      #result#isSet = true;
+      return result = #t1;
+    }
+    return #result#get.call();
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  core::int? result;
+  function #result#get() → core::int
+    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+  function #result#set(core::int #t3) → dynamic
+    return result = #t3;
+  return #result#get.call();
+}
+static method returnNullable(core::int? value) → core::int? {
+  core::int? result;
+  core::bool #result#isSet = false;
+  function #result#get() → core::int? {
+    if(!#result#isSet) {
+      #result#isSet = true;
+      result = value;
+    }
+    return result;
+  }
+  function #result#set(core::int? #t4) → dynamic {
+    #result#isSet = true;
+    return result = #t4;
+  }
+  return #result#get.call();
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
new file mode 100644
index 0000000..2a08564
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    self::Class::E? result;
+    core::bool #result#isSet = false;
+    function #result#get() → self::Class::E% {
+      if(!#result#isSet) {
+        #result#isSet = true;
+        result = this.{self::Class::field};
+      }
+      return result{self::Class::E%};
+    }
+    function #result#set(self::Class::E% #t1) → dynamic {
+      #result#isSet = true;
+      return result = #t1;
+    }
+    return #result#get.call();
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  core::int? result;
+  function #result#get() → core::int
+    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+  function #result#set(core::int #t3) → dynamic
+    return result = #t3;
+  return #result#get.call();
+}
+static method returnNullable(core::int? value) → core::int? {
+  core::int? result;
+  core::bool #result#isSet = false;
+  function #result#get() → core::int? {
+    if(!#result#isSet) {
+      #result#isSet = true;
+      result = value;
+    }
+    return result;
+  }
+  function #result#set(core::int? #t4) → dynamic {
+    #result#isSet = true;
+    return result = #t4;
+  }
+  return #result#get.call();
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
new file mode 100644
index 0000000..2a08564
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    self::Class::E? result;
+    core::bool #result#isSet = false;
+    function #result#get() → self::Class::E% {
+      if(!#result#isSet) {
+        #result#isSet = true;
+        result = this.{self::Class::field};
+      }
+      return result{self::Class::E%};
+    }
+    function #result#set(self::Class::E% #t1) → dynamic {
+      #result#isSet = true;
+      return result = #t1;
+    }
+    return #result#get.call();
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  core::int? result;
+  function #result#get() → core::int
+    return let final core::int? #t2 = result in #t2.==(null) ?{core::int} result = value : #t2{core::int};
+  function #result#set(core::int #t3) → dynamic
+    return result = #t3;
+  return #result#get.call();
+}
+static method returnNullable(core::int? value) → core::int? {
+  core::int? result;
+  core::bool #result#isSet = false;
+  function #result#get() → core::int? {
+    if(!#result#isSet) {
+      #result#isSet = true;
+      result = value;
+    }
+    return result;
+  }
+  function #result#set(core::int? #t4) → dynamic {
+    #result#isSet = true;
+    return result = #t4;
+  }
+  return #result#get.call();
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/call.dart b/pkg/front_end/testcases/nnbd/call.dart
new file mode 100644
index 0000000..48d12fb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  void Function()? field;
+  void Function()? get getter => null;
+}
+
+error() {
+  void Function()? f;
+  f();
+  f.call();
+  Class c = new Class();
+  c.field();
+  c.getter();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.outline.expect b/pkg/front_end/testcases/nnbd/call.dart.outline.expect
new file mode 100644
index 0000000..4b7665c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.outline.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field () →? void field;
+  synthetic constructor •() → self::Class
+    ;
+  get getter() → () →? void
+    ;
+}
+static method error() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/call.dart.strong.expect b/pkg/front_end/testcases/nnbd/call.dart.strong.expect
new file mode 100644
index 0000000..93617a2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.strong.expect
@@ -0,0 +1,48 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:13:5: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   f.call();
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field () →? void field = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get getter() → () →? void
+    return null;
+}
+static method error() → dynamic {
+  () →? void f;
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+  f();
+   ^" in let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  f();
+   ^" in f.call();
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:13:5: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  f.call();
+    ^" in f.call();
+  self::Class c = new self::Class::•();
+  c.{self::Class::field}();
+  c.{self::Class::getter}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/call.dart.strong.transformed.expect
new file mode 100644
index 0000000..93617a2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+// Try calling using ?.call instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:13:5: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+// Try calling using ?. instead.
+//   f.call();
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field () →? void field = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get getter() → () →? void
+    return null;
+}
+static method error() → dynamic {
+  () →? void f;
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+Try calling using ?.call instead.
+  f();
+   ^" in let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:12:4: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  f();
+   ^" in f.call();
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/call.dart:13:5: Error: Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+Try calling using ?. instead.
+  f.call();
+    ^" in f.call();
+  self::Class c = new self::Class::•();
+  c.{self::Class::field}();
+  c.{self::Class::getter}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.weak.expect b/pkg/front_end/testcases/nnbd/call.dart.weak.expect
new file mode 100644
index 0000000..88fb216
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.weak.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Warning: Method 'call' is called on 'void Function()?' which is potentially null.
+// Try calling using ?. instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Warning: Expression of type 'void Function()?' is used as a function, but it's potentially null.
+// Try calling using ?.call instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:13:5: Warning: Method 'call' is called on 'void Function()?' which is potentially null.
+// Try calling using ?. instead.
+//   f.call();
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field () →? void field = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get getter() → () →? void
+    return null;
+}
+static method error() → dynamic {
+  () →? void f;
+  f.call();
+  f.call();
+  self::Class c = new self::Class::•();
+  c.{self::Class::field}();
+  c.{self::Class::getter}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/call.dart.weak.transformed.expect
new file mode 100644
index 0000000..88fb216
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Warning: Method 'call' is called on 'void Function()?' which is potentially null.
+// Try calling using ?. instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:12:4: Warning: Expression of type 'void Function()?' is used as a function, but it's potentially null.
+// Try calling using ?.call instead.
+//   f();
+//    ^
+//
+// pkg/front_end/testcases/nnbd/call.dart:13:5: Warning: Method 'call' is called on 'void Function()?' which is potentially null.
+// Try calling using ?. instead.
+//   f.call();
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field () →? void field = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get getter() → () →? void
+    return null;
+}
+static method error() → dynamic {
+  () →? void f;
+  f.call();
+  f.call();
+  self::Class c = new self::Class::•();
+  c.{self::Class::field}();
+  c.{self::Class::getter}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart b/pkg/front_end/testcases/nnbd/forbidden_supers.dart
index 80fde61..d25e7ed 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart
@@ -5,17 +5,50 @@
 // This test checks for compile-time errors in cases when either Never or T? is
 // extended, implemented, or mixed in, where T is a type.
 
-class A {}
+class Aoo {}
 
-class B {}
+class Boo {}
 
-class C extends B with A? {}
-class C1 extends B with Never {}
+class Coo extends Boo with Aoo? {}
 
-class D extends A? {}
-class D1 extends Never {}
+class Doo extends Aoo? {}
 
-class E implements B? {}
-class E1 implements Never {}
+class Eoo implements Boo? {}
+
+class Foo extends Boo? with Aoo {}
+
+class Goo = Boo? with Aoo?;
+
+class Hoo extends Object with Aoo implements Boo? {}
+
+class Ioo = Object with Aoo implements Boo?;
+
+class Joo extends Boo with Never {}
+
+class Koo extends Never {}
+
+class Loo implements Never {}
+
+mixin Moo1 on Aoo? implements Boo? {}
+
+mixin Moo2 on Aoo?, Boo? {}
+
+mixin Moo3 implements Aoo?, Boo? {}
+
+mixin Moo4 on Aoo implements Never {}
+
+mixin Moo5 on Aoo, Never {}
+
+mixin Moo6 on Never {}
+
+mixin Moo7 implements Aoo, Never {}
+
+mixin Moo8 implements Never {}
+
+class Noo = Never with Aoo;
+class NooDynamic = dynamic with Aoo;
+class NooVoid = void with Aoo;
+
+class Ooo = Aoo with Never;
 
 main() {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.outline.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.outline.expect
index 14fa9bf..6f8ee32 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.outline.expect
@@ -2,73 +2,267 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be mixed in.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:12:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Coo extends Boo with Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:14:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// class Doo extends Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Eoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:18:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Foo extends Boo? with Aoo {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:22:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Hoo extends Object with Aoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:24:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Ioo = Object with Aoo implements Boo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Aoo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' can't be used here.
+// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' not found.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be mixed in.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be used as supertype.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be mixed in.
+// class Ooo = Aoo with Never;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used as supertype.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be used as supertype.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used as supertype.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used as supertype.
+// class Koo extends Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used in an 'extends' clause.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used as supertype.
+// class Loo implements Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used in an 'implements' clause.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used as supertype.
+// class Noo = Never with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:49:7: Error: The type 'dynamic' can't be used as supertype.
+// class NooDynamic = dynamic with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be used as supertype.
+// class Ooo = Aoo with Never;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Koo extends Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// class Loo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Noo = Never with Aoo;
 //       ^
 //
 import self as self;
 import "dart:core" as core;
 
-class A extends core::Object {
-  synthetic constructor •() → self::A
+class Aoo extends core::Object {
+  synthetic constructor •() → self::Aoo
     ;
 }
-class B extends core::Object {
-  synthetic constructor •() → self::B
+class Boo extends core::Object {
+  synthetic constructor •() → self::Boo
     ;
 }
-abstract class _C&B&A = self::B with self::A {
-  synthetic constructor •() → self::_C&B&A
-    : super self::B::•()
+abstract class _Coo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Coo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class C extends self::_C&B&A {
-  synthetic constructor •() → self::C
+class Coo extends self::_Coo&Boo&Aoo {
+  synthetic constructor •() → self::Coo
     ;
 }
-abstract class _C1&B&Never extends self::B {
-  synthetic constructor •() → self::_C1&B&Never
-    : super self::B::•()
+class Doo extends self::Aoo {
+  synthetic constructor •() → self::Doo
     ;
 }
-class C1 extends self::_C1&B&Never {
-  synthetic constructor •() → self::C1
+class Eoo extends core::Object implements self::Boo {
+  synthetic constructor •() → self::Eoo
     ;
 }
-class D extends self::A {
-  synthetic constructor •() → self::D
+abstract class _Foo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Foo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class D1 extends core::Object {
-  synthetic constructor •() → self::D1
+class Foo extends self::_Foo&Boo&Aoo {
+  synthetic constructor •() → self::Foo
     ;
 }
-class E extends core::Object implements self::B {
-  synthetic constructor •() → self::E
+class Goo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::Goo
+    : super self::Boo::•()
     ;
 }
-class E1 extends core::Object {
-  synthetic constructor •() → self::E1
+abstract class _Hoo&Object&Aoo = core::Object with self::Aoo {
+  const synthetic constructor •() → self::_Hoo&Object&Aoo
+    : super core::Object::•()
+    ;
+}
+class Hoo extends self::_Hoo&Object&Aoo implements self::Boo {
+  synthetic constructor •() → self::Hoo
+    ;
+}
+class Ioo = core::Object with self::Aoo implements self::Boo {
+  const synthetic constructor •() → self::Ioo
+    : super core::Object::•()
+    ;
+}
+abstract class _Joo&Boo&Never extends self::Boo {
+  synthetic constructor •() → self::_Joo&Boo&Never
+    : super self::Boo::•()
+    ;
+}
+class Joo extends self::_Joo&Boo&Never {
+  synthetic constructor •() → self::Joo
+    ;
+}
+class Koo extends core::Object {
+  synthetic constructor •() → self::Koo
+    ;
+}
+class Loo extends core::Object {
+  synthetic constructor •() → self::Loo
+    ;
+}
+abstract class Moo1 extends self::Aoo implements self::Boo {
+}
+abstract class _Moo2&Aoo&Boo extends core::Object implements self::Aoo, self::Boo {
+  synthetic constructor •() → self::_Moo2&Aoo&Boo
+    ;
+}
+abstract class Moo2 extends self::_Moo2&Aoo&Boo {
+}
+abstract class Moo3 extends core::Object implements self::Aoo, self::Boo {
+}
+abstract class Moo4 extends self::Aoo {
+}
+abstract class _Moo5&Aoo&Never extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::_Moo5&Aoo&Never
+    ;
+}
+abstract class Moo5 extends self::_Moo5&Aoo&Never {
+}
+abstract class Moo6 extends core::Object {
+}
+abstract class Moo7 extends core::Object implements self::Aoo {
+}
+abstract class Moo8 extends core::Object {
+}
+class Noo = core::Object with self::Aoo {
+  synthetic constructor •() → self::Noo
+    ;
+}
+class NooDynamic = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooDynamic
+    ;
+}
+class NooVoid = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooVoid
+    ;
+}
+class Ooo extends self::Aoo {
+  synthetic constructor •() → self::Ooo
+    : super self::Aoo::•()
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.expect
index a7be0e3..a48c33f 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.expect
@@ -2,81 +2,282 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be mixed in.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:12:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Coo extends Boo with Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:14:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// class Doo extends Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Eoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:18:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Foo extends Boo? with Aoo {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:22:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Hoo extends Object with Aoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:24:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Ioo = Object with Aoo implements Boo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Aoo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' can't be used here.
+// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' not found.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be mixed in.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be used as supertype.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be mixed in.
+// class Ooo = Aoo with Never;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used as supertype.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be used as supertype.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used as supertype.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used as supertype.
+// class Koo extends Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used in an 'extends' clause.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used as supertype.
+// class Loo implements Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used in an 'implements' clause.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used as supertype.
+// class Noo = Never with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:49:7: Error: The type 'dynamic' can't be used as supertype.
+// class NooDynamic = dynamic with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be used as supertype.
+// class Ooo = Aoo with Never;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Koo extends Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// class Loo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Noo = Never with Aoo;
 //       ^
 //
 import self as self;
 import "dart:core" as core;
 
-class A extends core::Object {
-  synthetic constructor •() → self::A
+class Aoo extends core::Object {
+  synthetic constructor •() → self::Aoo
     : super core::Object::•()
     ;
 }
-class B extends core::Object {
-  synthetic constructor •() → self::B
+class Boo extends core::Object {
+  synthetic constructor •() → self::Boo
     : super core::Object::•()
     ;
 }
-abstract class _C&B&A = self::B with self::A {
-  synthetic constructor •() → self::_C&B&A
-    : super self::B::•()
+abstract class _Coo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Coo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class C extends self::_C&B&A {
-  synthetic constructor •() → self::C
-    : super self::_C&B&A::•()
+class Coo extends self::_Coo&Boo&Aoo {
+  synthetic constructor •() → self::Coo
+    : super self::_Coo&Boo&Aoo::•()
     ;
 }
-abstract class _C1&B&Never extends self::B {
-  synthetic constructor •() → self::_C1&B&Never
-    : super self::B::•()
+class Doo extends self::Aoo {
+  synthetic constructor •() → self::Doo
+    : super self::Aoo::•()
     ;
 }
-class C1 extends self::_C1&B&Never {
-  synthetic constructor •() → self::C1
-    : super self::_C1&B&Never::•()
-    ;
-}
-class D extends self::A {
-  synthetic constructor •() → self::D
-    : super self::A::•()
-    ;
-}
-class D1 extends core::Object {
-  synthetic constructor •() → self::D1
+class Eoo extends core::Object implements self::Boo {
+  synthetic constructor •() → self::Eoo
     : super core::Object::•()
     ;
 }
-class E extends core::Object implements self::B {
-  synthetic constructor •() → self::E
+abstract class _Foo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Foo&Boo&Aoo
+    : super self::Boo::•()
+    ;
+}
+class Foo extends self::_Foo&Boo&Aoo {
+  synthetic constructor •() → self::Foo
+    : super self::_Foo&Boo&Aoo::•()
+    ;
+}
+class Goo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::Goo
+    : super self::Boo::•()
+    ;
+}
+abstract class _Hoo&Object&Aoo = core::Object with self::Aoo {
+  const synthetic constructor •() → self::_Hoo&Object&Aoo
     : super core::Object::•()
     ;
 }
-class E1 extends core::Object {
-  synthetic constructor •() → self::E1
+class Hoo extends self::_Hoo&Object&Aoo implements self::Boo {
+  synthetic constructor •() → self::Hoo
+    : super self::_Hoo&Object&Aoo::•()
+    ;
+}
+class Ioo = core::Object with self::Aoo implements self::Boo {
+  const synthetic constructor •() → self::Ioo
     : super core::Object::•()
     ;
 }
+abstract class _Joo&Boo&Never extends self::Boo {
+  synthetic constructor •() → self::_Joo&Boo&Never
+    : super self::Boo::•()
+    ;
+}
+class Joo extends self::_Joo&Boo&Never {
+  synthetic constructor •() → self::Joo
+    : super self::_Joo&Boo&Never::•()
+    ;
+}
+class Koo extends core::Object {
+  synthetic constructor •() → self::Koo
+    : super core::Object::•()
+    ;
+}
+class Loo extends core::Object {
+  synthetic constructor •() → self::Loo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo1 extends self::Aoo implements self::Boo {
+}
+abstract class _Moo2&Aoo&Boo extends core::Object implements self::Aoo, self::Boo {
+  synthetic constructor •() → self::_Moo2&Aoo&Boo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo2 extends self::_Moo2&Aoo&Boo {
+}
+abstract class Moo3 extends core::Object implements self::Aoo, self::Boo {
+}
+abstract class Moo4 extends self::Aoo {
+}
+abstract class _Moo5&Aoo&Never extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::_Moo5&Aoo&Never
+    : super core::Object::•()
+    ;
+}
+abstract class Moo5 extends self::_Moo5&Aoo&Never {
+}
+abstract class Moo6 extends core::Object {
+}
+abstract class Moo7 extends core::Object implements self::Aoo {
+}
+abstract class Moo8 extends core::Object {
+}
+class Noo = core::Object with self::Aoo {
+  synthetic constructor •() → self::Noo
+    : super core::Object::•()
+    ;
+}
+class NooDynamic = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooDynamic
+    : super core::Object::•()
+    ;
+}
+class NooVoid = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooVoid
+    : super core::Object::•()
+    ;
+}
+class Ooo extends self::Aoo {
+  synthetic constructor •() → self::Ooo
+    : super self::Aoo::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.transformed.expect
index de6ba93..e46d7ae 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.strong.transformed.expect
@@ -2,81 +2,282 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be mixed in.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:12:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Coo extends Boo with Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:14:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// class Doo extends Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Eoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:18:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Foo extends Boo? with Aoo {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Error: Can't mix 'Aoo' in because it's marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:22:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Hoo extends Object with Aoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:24:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// class Ioo = Object with Aoo implements Boo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Aoo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Error: Can't extend 'Boo' because it's marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Aoo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Error: Can't implement 'Boo' because it's marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' can't be used here.
+// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' not found.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be mixed in.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be used as supertype.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be mixed in.
+// class Ooo = Aoo with Never;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used as supertype.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be used as supertype.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used as supertype.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used as supertype.
+// class Koo extends Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used in an 'extends' clause.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used as supertype.
+// class Loo implements Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used in an 'implements' clause.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used as supertype.
+// class Noo = Never with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:49:7: Error: The type 'dynamic' can't be used as supertype.
+// class NooDynamic = dynamic with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be used as supertype.
+// class Ooo = Aoo with Never;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Koo extends Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// class Loo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Noo = Never with Aoo;
 //       ^
 //
 import self as self;
 import "dart:core" as core;
 
-class A extends core::Object {
-  synthetic constructor •() → self::A
+class Aoo extends core::Object {
+  synthetic constructor •() → self::Aoo
     : super core::Object::•()
     ;
 }
-class B extends core::Object {
-  synthetic constructor •() → self::B
+class Boo extends core::Object {
+  synthetic constructor •() → self::Boo
     : super core::Object::•()
     ;
 }
-abstract class _C&B&A extends self::B implements self::A {
-  synthetic constructor •() → self::_C&B&A
-    : super self::B::•()
+abstract class _Coo&Boo&Aoo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::_Coo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class C extends self::_C&B&A {
-  synthetic constructor •() → self::C
-    : super self::_C&B&A::•()
+class Coo extends self::_Coo&Boo&Aoo {
+  synthetic constructor •() → self::Coo
+    : super self::_Coo&Boo&Aoo::•()
     ;
 }
-abstract class _C1&B&Never extends self::B {
-  synthetic constructor •() → self::_C1&B&Never
-    : super self::B::•()
+class Doo extends self::Aoo {
+  synthetic constructor •() → self::Doo
+    : super self::Aoo::•()
     ;
 }
-class C1 extends self::_C1&B&Never {
-  synthetic constructor •() → self::C1
-    : super self::_C1&B&Never::•()
-    ;
-}
-class D extends self::A {
-  synthetic constructor •() → self::D
-    : super self::A::•()
-    ;
-}
-class D1 extends core::Object {
-  synthetic constructor •() → self::D1
+class Eoo extends core::Object implements self::Boo {
+  synthetic constructor •() → self::Eoo
     : super core::Object::•()
     ;
 }
-class E extends core::Object implements self::B {
-  synthetic constructor •() → self::E
+abstract class _Foo&Boo&Aoo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::_Foo&Boo&Aoo
+    : super self::Boo::•()
+    ;
+}
+class Foo extends self::_Foo&Boo&Aoo {
+  synthetic constructor •() → self::Foo
+    : super self::_Foo&Boo&Aoo::•()
+    ;
+}
+class Goo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::Goo
+    : super self::Boo::•()
+    ;
+}
+abstract class _Hoo&Object&Aoo extends core::Object implements self::Aoo {
+  const synthetic constructor •() → self::_Hoo&Object&Aoo
     : super core::Object::•()
     ;
 }
-class E1 extends core::Object {
-  synthetic constructor •() → self::E1
+class Hoo extends self::_Hoo&Object&Aoo implements self::Boo {
+  synthetic constructor •() → self::Hoo
+    : super self::_Hoo&Object&Aoo::•()
+    ;
+}
+class Ioo extends core::Object implements self::Boo, self::Aoo {
+  const synthetic constructor •() → self::Ioo
     : super core::Object::•()
     ;
 }
+abstract class _Joo&Boo&Never extends self::Boo {
+  synthetic constructor •() → self::_Joo&Boo&Never
+    : super self::Boo::•()
+    ;
+}
+class Joo extends self::_Joo&Boo&Never {
+  synthetic constructor •() → self::Joo
+    : super self::_Joo&Boo&Never::•()
+    ;
+}
+class Koo extends core::Object {
+  synthetic constructor •() → self::Koo
+    : super core::Object::•()
+    ;
+}
+class Loo extends core::Object {
+  synthetic constructor •() → self::Loo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo1 extends self::Aoo implements self::Boo {
+}
+abstract class _Moo2&Aoo&Boo extends core::Object implements self::Aoo, self::Boo {
+  synthetic constructor •() → self::_Moo2&Aoo&Boo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo2 extends self::_Moo2&Aoo&Boo {
+}
+abstract class Moo3 extends core::Object implements self::Aoo, self::Boo {
+}
+abstract class Moo4 extends self::Aoo {
+}
+abstract class _Moo5&Aoo&Never extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::_Moo5&Aoo&Never
+    : super core::Object::•()
+    ;
+}
+abstract class Moo5 extends self::_Moo5&Aoo&Never {
+}
+abstract class Moo6 extends core::Object {
+}
+abstract class Moo7 extends core::Object implements self::Aoo {
+}
+abstract class Moo8 extends core::Object {
+}
+class Noo extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::Noo
+    : super core::Object::•()
+    ;
+}
+class NooDynamic extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::NooDynamic
+    : super core::Object::•()
+    ;
+}
+class NooVoid extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::NooVoid
+    : super core::Object::•()
+    ;
+}
+class Ooo extends self::Aoo {
+  synthetic constructor •() → self::Ooo
+    : super self::Aoo::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.expect
index a7be0e3..e72e454 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.expect
@@ -2,81 +2,282 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be mixed in.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:12:7: Warning: Mixing in 'Aoo' marked with '?'.
+// class Coo extends Boo with Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:14:7: Warning: Extending 'Aoo' marked with '?'.
+// class Doo extends Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Warning: Implementing 'Boo' marked with '?'.
+// class Eoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:18:7: Warning: Extending 'Boo' marked with '?'.
+// class Foo extends Boo? with Aoo {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Warning: Extending 'Boo' marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Warning: Mixing in 'Aoo' marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:22:7: Warning: Implementing 'Boo' marked with '?'.
+// class Hoo extends Object with Aoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:24:7: Warning: Implementing 'Boo' marked with '?'.
+// class Ioo = Object with Aoo implements Boo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Warning: Extending 'Aoo' marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Warning: Implementing 'Boo' marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Warning: Extending 'Aoo' marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Warning: Extending 'Boo' marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Warning: Implementing 'Aoo' marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Warning: Implementing 'Boo' marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' can't be used here.
+// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' not found.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be mixed in.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be used as supertype.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be mixed in.
+// class Ooo = Aoo with Never;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used as supertype.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be used as supertype.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used as supertype.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used as supertype.
+// class Koo extends Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used in an 'extends' clause.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used as supertype.
+// class Loo implements Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used in an 'implements' clause.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used as supertype.
+// class Noo = Never with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:49:7: Error: The type 'dynamic' can't be used as supertype.
+// class NooDynamic = dynamic with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be used as supertype.
+// class Ooo = Aoo with Never;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Koo extends Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// class Loo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Noo = Never with Aoo;
 //       ^
 //
 import self as self;
 import "dart:core" as core;
 
-class A extends core::Object {
-  synthetic constructor •() → self::A
+class Aoo extends core::Object {
+  synthetic constructor •() → self::Aoo
     : super core::Object::•()
     ;
 }
-class B extends core::Object {
-  synthetic constructor •() → self::B
+class Boo extends core::Object {
+  synthetic constructor •() → self::Boo
     : super core::Object::•()
     ;
 }
-abstract class _C&B&A = self::B with self::A {
-  synthetic constructor •() → self::_C&B&A
-    : super self::B::•()
+abstract class _Coo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Coo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class C extends self::_C&B&A {
-  synthetic constructor •() → self::C
-    : super self::_C&B&A::•()
+class Coo extends self::_Coo&Boo&Aoo {
+  synthetic constructor •() → self::Coo
+    : super self::_Coo&Boo&Aoo::•()
     ;
 }
-abstract class _C1&B&Never extends self::B {
-  synthetic constructor •() → self::_C1&B&Never
-    : super self::B::•()
+class Doo extends self::Aoo {
+  synthetic constructor •() → self::Doo
+    : super self::Aoo::•()
     ;
 }
-class C1 extends self::_C1&B&Never {
-  synthetic constructor •() → self::C1
-    : super self::_C1&B&Never::•()
-    ;
-}
-class D extends self::A {
-  synthetic constructor •() → self::D
-    : super self::A::•()
-    ;
-}
-class D1 extends core::Object {
-  synthetic constructor •() → self::D1
+class Eoo extends core::Object implements self::Boo {
+  synthetic constructor •() → self::Eoo
     : super core::Object::•()
     ;
 }
-class E extends core::Object implements self::B {
-  synthetic constructor •() → self::E
+abstract class _Foo&Boo&Aoo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::_Foo&Boo&Aoo
+    : super self::Boo::•()
+    ;
+}
+class Foo extends self::_Foo&Boo&Aoo {
+  synthetic constructor •() → self::Foo
+    : super self::_Foo&Boo&Aoo::•()
+    ;
+}
+class Goo = self::Boo with self::Aoo {
+  synthetic constructor •() → self::Goo
+    : super self::Boo::•()
+    ;
+}
+abstract class _Hoo&Object&Aoo = core::Object with self::Aoo {
+  const synthetic constructor •() → self::_Hoo&Object&Aoo
     : super core::Object::•()
     ;
 }
-class E1 extends core::Object {
-  synthetic constructor •() → self::E1
+class Hoo extends self::_Hoo&Object&Aoo implements self::Boo {
+  synthetic constructor •() → self::Hoo
+    : super self::_Hoo&Object&Aoo::•()
+    ;
+}
+class Ioo = core::Object with self::Aoo implements self::Boo {
+  const synthetic constructor •() → self::Ioo
     : super core::Object::•()
     ;
 }
+abstract class _Joo&Boo&Never extends self::Boo {
+  synthetic constructor •() → self::_Joo&Boo&Never
+    : super self::Boo::•()
+    ;
+}
+class Joo extends self::_Joo&Boo&Never {
+  synthetic constructor •() → self::Joo
+    : super self::_Joo&Boo&Never::•()
+    ;
+}
+class Koo extends core::Object {
+  synthetic constructor •() → self::Koo
+    : super core::Object::•()
+    ;
+}
+class Loo extends core::Object {
+  synthetic constructor •() → self::Loo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo1 extends self::Aoo implements self::Boo {
+}
+abstract class _Moo2&Aoo&Boo extends core::Object implements self::Aoo, self::Boo {
+  synthetic constructor •() → self::_Moo2&Aoo&Boo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo2 extends self::_Moo2&Aoo&Boo {
+}
+abstract class Moo3 extends core::Object implements self::Aoo, self::Boo {
+}
+abstract class Moo4 extends self::Aoo {
+}
+abstract class _Moo5&Aoo&Never extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::_Moo5&Aoo&Never
+    : super core::Object::•()
+    ;
+}
+abstract class Moo5 extends self::_Moo5&Aoo&Never {
+}
+abstract class Moo6 extends core::Object {
+}
+abstract class Moo7 extends core::Object implements self::Aoo {
+}
+abstract class Moo8 extends core::Object {
+}
+class Noo = core::Object with self::Aoo {
+  synthetic constructor •() → self::Noo
+    : super core::Object::•()
+    ;
+}
+class NooDynamic = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooDynamic
+    : super core::Object::•()
+    ;
+}
+class NooVoid = core::Object with self::Aoo {
+  synthetic constructor •() → self::NooVoid
+    : super core::Object::•()
+    ;
+}
+class Ooo extends self::Aoo {
+  synthetic constructor •() → self::Ooo
+    : super self::Aoo::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.transformed.expect
index de6ba93..dffeb69b 100644
--- a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.weak.transformed.expect
@@ -2,81 +2,282 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be mixed in.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:12:7: Warning: Mixing in 'Aoo' marked with '?'.
+// class Coo extends Boo with Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:14:7: Warning: Extending 'Aoo' marked with '?'.
+// class Doo extends Aoo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Warning: Implementing 'Boo' marked with '?'.
+// class Eoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:18:7: Warning: Extending 'Boo' marked with '?'.
+// class Foo extends Boo? with Aoo {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Warning: Extending 'Boo' marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:20:7: Warning: Mixing in 'Aoo' marked with '?'.
+// class Goo = Boo? with Aoo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:22:7: Warning: Implementing 'Boo' marked with '?'.
+// class Hoo extends Object with Aoo implements Boo? {}
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:24:7: Warning: Implementing 'Boo' marked with '?'.
+// class Ioo = Object with Aoo implements Boo?;
+//       ^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Warning: Extending 'Aoo' marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:32:7: Warning: Implementing 'Boo' marked with '?'.
+// mixin Moo1 on Aoo? implements Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Warning: Extending 'Aoo' marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:34:7: Warning: Extending 'Boo' marked with '?'.
+// mixin Moo2 on Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Warning: Implementing 'Aoo' marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:36:7: Warning: Implementing 'Boo' marked with '?'.
+// mixin Moo3 implements Aoo?, Boo? {}
+//       ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' can't be used here.
+// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:50:17: Error: Type 'void' not found.
+// class NooVoid = void with Aoo;
+//                 ^^^^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be mixed in.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:13:7: Error: The type 'Never' can't be used as supertype.
-// class C1 extends B with Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be mixed in.
+// class Ooo = Aoo with Never;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used as supertype.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:26:7: Error: The type 'Never' can't be used as supertype.
+// class Joo extends Boo with Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used as supertype.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used as supertype.
+// class Koo extends Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:16:7: Error: The type 'Never' can't be used in an 'extends' clause.
-// class D1 extends Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used as supertype.
+// class Loo implements Never {}
 //       ^
 //
-// pkg/front_end/testcases/nnbd/forbidden_supers.dart:19:7: Error: The type 'Never' can't be used in an 'implements' clause.
-// class E1 implements Never {}
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used as supertype.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used as supertype.
+// class Noo = Never with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:49:7: Error: The type 'dynamic' can't be used as supertype.
+// class NooDynamic = dynamic with Aoo;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:52:7: Error: The type 'Never' can't be used as supertype.
+// class Ooo = Aoo with Never;
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:28:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Koo extends Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:30:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// class Loo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:38:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo4 on Aoo implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:40:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo5 on Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:42:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// mixin Moo6 on Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:44:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo7 implements Aoo, Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:46:7: Error: The type 'Never' can't be used in an 'implements' clause.
+// mixin Moo8 implements Never {}
+//       ^
+//
+// pkg/front_end/testcases/nnbd/forbidden_supers.dart:48:7: Error: The type 'Never' can't be used in an 'extends' clause.
+// class Noo = Never with Aoo;
 //       ^
 //
 import self as self;
 import "dart:core" as core;
 
-class A extends core::Object {
-  synthetic constructor •() → self::A
+class Aoo extends core::Object {
+  synthetic constructor •() → self::Aoo
     : super core::Object::•()
     ;
 }
-class B extends core::Object {
-  synthetic constructor •() → self::B
+class Boo extends core::Object {
+  synthetic constructor •() → self::Boo
     : super core::Object::•()
     ;
 }
-abstract class _C&B&A extends self::B implements self::A {
-  synthetic constructor •() → self::_C&B&A
-    : super self::B::•()
+abstract class _Coo&Boo&Aoo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::_Coo&Boo&Aoo
+    : super self::Boo::•()
     ;
 }
-class C extends self::_C&B&A {
-  synthetic constructor •() → self::C
-    : super self::_C&B&A::•()
+class Coo extends self::_Coo&Boo&Aoo {
+  synthetic constructor •() → self::Coo
+    : super self::_Coo&Boo&Aoo::•()
     ;
 }
-abstract class _C1&B&Never extends self::B {
-  synthetic constructor •() → self::_C1&B&Never
-    : super self::B::•()
+class Doo extends self::Aoo {
+  synthetic constructor •() → self::Doo
+    : super self::Aoo::•()
     ;
 }
-class C1 extends self::_C1&B&Never {
-  synthetic constructor •() → self::C1
-    : super self::_C1&B&Never::•()
-    ;
-}
-class D extends self::A {
-  synthetic constructor •() → self::D
-    : super self::A::•()
-    ;
-}
-class D1 extends core::Object {
-  synthetic constructor •() → self::D1
+class Eoo extends core::Object implements self::Boo {
+  synthetic constructor •() → self::Eoo
     : super core::Object::•()
     ;
 }
-class E extends core::Object implements self::B {
-  synthetic constructor •() → self::E
+abstract class _Foo&Boo&Aoo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::_Foo&Boo&Aoo
+    : super self::Boo::•()
+    ;
+}
+class Foo extends self::_Foo&Boo&Aoo {
+  synthetic constructor •() → self::Foo
+    : super self::_Foo&Boo&Aoo::•()
+    ;
+}
+class Goo extends self::Boo implements self::Aoo {
+  synthetic constructor •() → self::Goo
+    : super self::Boo::•()
+    ;
+}
+abstract class _Hoo&Object&Aoo extends core::Object implements self::Aoo {
+  const synthetic constructor •() → self::_Hoo&Object&Aoo
     : super core::Object::•()
     ;
 }
-class E1 extends core::Object {
-  synthetic constructor •() → self::E1
+class Hoo extends self::_Hoo&Object&Aoo implements self::Boo {
+  synthetic constructor •() → self::Hoo
+    : super self::_Hoo&Object&Aoo::•()
+    ;
+}
+class Ioo extends core::Object implements self::Boo, self::Aoo {
+  const synthetic constructor •() → self::Ioo
     : super core::Object::•()
     ;
 }
+abstract class _Joo&Boo&Never extends self::Boo {
+  synthetic constructor •() → self::_Joo&Boo&Never
+    : super self::Boo::•()
+    ;
+}
+class Joo extends self::_Joo&Boo&Never {
+  synthetic constructor •() → self::Joo
+    : super self::_Joo&Boo&Never::•()
+    ;
+}
+class Koo extends core::Object {
+  synthetic constructor •() → self::Koo
+    : super core::Object::•()
+    ;
+}
+class Loo extends core::Object {
+  synthetic constructor •() → self::Loo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo1 extends self::Aoo implements self::Boo {
+}
+abstract class _Moo2&Aoo&Boo extends core::Object implements self::Aoo, self::Boo {
+  synthetic constructor •() → self::_Moo2&Aoo&Boo
+    : super core::Object::•()
+    ;
+}
+abstract class Moo2 extends self::_Moo2&Aoo&Boo {
+}
+abstract class Moo3 extends core::Object implements self::Aoo, self::Boo {
+}
+abstract class Moo4 extends self::Aoo {
+}
+abstract class _Moo5&Aoo&Never extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::_Moo5&Aoo&Never
+    : super core::Object::•()
+    ;
+}
+abstract class Moo5 extends self::_Moo5&Aoo&Never {
+}
+abstract class Moo6 extends core::Object {
+}
+abstract class Moo7 extends core::Object implements self::Aoo {
+}
+abstract class Moo8 extends core::Object {
+}
+class Noo extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::Noo
+    : super core::Object::•()
+    ;
+}
+class NooDynamic extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::NooDynamic
+    : super core::Object::•()
+    ;
+}
+class NooVoid extends core::Object implements self::Aoo {
+  synthetic constructor •() → self::NooVoid
+    : super core::Object::•()
+    ;
+}
+class Ooo extends self::Aoo {
+  synthetic constructor •() → self::Ooo
+    : super self::Aoo::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart b/pkg/front_end/testcases/nnbd/generic_override.dart
new file mode 100644
index 0000000..f898600
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, 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.
+
+abstract class Class1 {
+  void method1a<T>();
+  void method1b<T>();
+  void method1c<T>();
+  void method2a<T extends Object?>();
+  void method2b<T extends Object?>();
+  void method2c<T extends Object?>();
+  void method3a<T extends dynamic>();
+  void method3b<T extends dynamic>();
+  void method3c<T extends dynamic>();
+
+  void method4a<T extends Object>();
+  void method4b<T extends Object>();
+  void method4c<T extends Object?>();
+
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1>();
+  void method5c<T extends Class1?>();
+}
+
+abstract class Class2 extends Class1 {
+  void method1a<T>();
+  void method1b<T extends Object?>();
+  void method1c<T extends dynamic>();
+  void method2a<T>();
+  void method2b<T extends Object?>();
+  void method2c<T extends dynamic>();
+  void method3a<T>();
+  void method3b<T extends Object?>();
+  void method3c<T extends dynamic>();
+
+  void method4a<T extends Object>();
+  void method4b<T extends Object?>(); // error
+  void method4c<T extends Object>(); // error
+
+  void method5a<T extends Class1>();
+  void method5b<T extends Class1?>(); // error
+  void method5c<T extends Class1>(); // error
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
new file mode 100644
index 0000000..acb7609
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.outline.expect
@@ -0,0 +1,79 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+//  - 'Object' is from 'dart:core'.
+//   void method4c<T extends Object>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+//   void method4c<T extends Object?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5c<T extends Class1>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+//   void method5c<T extends Class1?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5b<T extends Class1?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+//   void method5b<T extends Class1>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+//  - 'Object' is from 'dart:core'.
+//   void method4b<T extends Object?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+//   void method4b<T extends Object>();
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = dynamic>() → void;
+  abstract method method1c<T extends core::Object? = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = core::Object?>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends core::Object? = core::Object?>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object = core::Object>() → void;
+  abstract method method4c<T extends core::Object? = core::Object?>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5c<T extends self::Class1? = self::Class1?>() → void;
+}
+abstract class Class2 extends self::Class1 {
+  synthetic constructor •() → self::Class2
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
new file mode 100644
index 0000000..dfb0fb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.expect
@@ -0,0 +1,80 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+//  - 'Object' is from 'dart:core'.
+//   void method4c<T extends Object>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+//   void method4c<T extends Object?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5c<T extends Class1>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+//   void method5c<T extends Class1?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5b<T extends Class1?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+//   void method5b<T extends Class1>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+//  - 'Object' is from 'dart:core'.
+//   void method4b<T extends Object?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+//   void method4b<T extends Object>();
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = dynamic>() → void;
+  abstract method method1c<T extends core::Object? = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = core::Object?>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends core::Object? = core::Object?>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object = core::Object>() → void;
+  abstract method method4c<T extends core::Object? = core::Object?>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5c<T extends self::Class1? = self::Class1?>() → void;
+}
+abstract class Class2 extends self::Class1 {
+  synthetic constructor •() → self::Class2
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
new file mode 100644
index 0000000..dfb0fb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.strong.transformed.expect
@@ -0,0 +1,80 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+//  - 'Object' is from 'dart:core'.
+//   void method4c<T extends Object>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+//   void method4c<T extends Object?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5c<T extends Class1>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+//   void method5c<T extends Class1?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5b<T extends Class1?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+//   void method5b<T extends Class1>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+//  - 'Object' is from 'dart:core'.
+//   void method4b<T extends Object?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+//   void method4b<T extends Object>();
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = dynamic>() → void;
+  abstract method method1c<T extends core::Object? = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = core::Object?>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends core::Object? = core::Object?>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object = core::Object>() → void;
+  abstract method method4c<T extends core::Object? = core::Object?>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5c<T extends self::Class1? = self::Class1?>() → void;
+}
+abstract class Class2 extends self::Class1 {
+  synthetic constructor •() → self::Class2
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
new file mode 100644
index 0000000..dfb0fb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.expect
@@ -0,0 +1,80 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+//  - 'Object' is from 'dart:core'.
+//   void method4c<T extends Object>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+//   void method4c<T extends Object?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5c<T extends Class1>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+//   void method5c<T extends Class1?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5b<T extends Class1?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+//   void method5b<T extends Class1>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+//  - 'Object' is from 'dart:core'.
+//   void method4b<T extends Object?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+//   void method4b<T extends Object>();
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = dynamic>() → void;
+  abstract method method1c<T extends core::Object? = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = core::Object?>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends core::Object? = core::Object?>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object = core::Object>() → void;
+  abstract method method4c<T extends core::Object? = core::Object?>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5c<T extends self::Class1? = self::Class1?>() → void;
+}
+abstract class Class2 extends self::Class1 {
+  synthetic constructor •() → self::Class2
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
new file mode 100644
index 0000000..dfb0fb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.weak.transformed.expect
@@ -0,0 +1,80 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:38:8: Error: Declared bound 'Object' of type variable 'T' of 'Class2.method4c' doesn't match the bound 'Object?' on overridden method 'Class1.method4c'.
+//  - 'Object' is from 'dart:core'.
+//   void method4c<T extends Object>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:18:8: Context: This is the overridden method ('method4c').
+//   void method4c<T extends Object?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:42:8: Error: Declared bound 'Class1' of type variable 'T' of 'Class2.method5c' doesn't match the bound 'Class1?' on overridden method 'Class1.method5c'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5c<T extends Class1>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:22:8: Context: This is the overridden method ('method5c').
+//   void method5c<T extends Class1?>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:41:8: Error: Declared bound 'Class1?' of type variable 'T' of 'Class2.method5b' doesn't match the bound 'Class1' on overridden method 'Class1.method5b'.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/generic_override.dart'.
+//   void method5b<T extends Class1?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:21:8: Context: This is the overridden method ('method5b').
+//   void method5b<T extends Class1>();
+//        ^
+//
+// pkg/front_end/testcases/nnbd/generic_override.dart:37:8: Error: Declared bound 'Object?' of type variable 'T' of 'Class2.method4b' doesn't match the bound 'Object' on overridden method 'Class1.method4b'.
+//  - 'Object' is from 'dart:core'.
+//   void method4b<T extends Object?>(); // error
+//        ^
+// pkg/front_end/testcases/nnbd/generic_override.dart:17:8: Context: This is the overridden method ('method4b').
+//   void method4b<T extends Object>();
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = dynamic>() → void;
+  abstract method method1c<T extends core::Object? = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = core::Object?>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends core::Object? = core::Object?>() → void;
+  abstract method method3a<T extends dynamic = dynamic>() → void;
+  abstract method method3b<T extends dynamic = dynamic>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object = core::Object>() → void;
+  abstract method method4c<T extends core::Object? = core::Object?>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5c<T extends self::Class1? = self::Class1?>() → void;
+}
+abstract class Class2 extends self::Class1 {
+  synthetic constructor •() → self::Class2
+    : super self::Class1::•()
+    ;
+  abstract method method1a<T extends core::Object? = dynamic>() → void;
+  abstract method method1b<T extends core::Object? = core::Object?>() → void;
+  abstract method method1c<T extends dynamic = dynamic>() → void;
+  abstract method method2a<T extends core::Object? = dynamic>() → void;
+  abstract method method2b<T extends core::Object? = core::Object?>() → void;
+  abstract method method2c<T extends dynamic = dynamic>() → void;
+  abstract method method3a<T extends core::Object? = dynamic>() → void;
+  abstract method method3b<T extends core::Object? = core::Object?>() → void;
+  abstract method method3c<T extends dynamic = dynamic>() → void;
+  abstract method method4a<T extends core::Object = core::Object>() → void;
+  abstract method method4b<T extends core::Object? = core::Object?>() → void;
+  abstract method method4c<T extends core::Object = core::Object>() → void;
+  abstract method method5a<T extends self::Class1 = self::Class1>() → void;
+  abstract method method5b<T extends self::Class1? = self::Class1?>() → void;
+  abstract method method5c<T extends self::Class1 = self::Class1>() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
index ba69d39..37919d9 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.expect
@@ -63,7 +63,7 @@
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
 }
 static method test7(self::A7? a) → dynamic {
-  core::String s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
-  core::String s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
+  core::String? s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String?} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
+  core::String? s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String?} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
index ba69d39..37919d9 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.strong.transformed.expect
@@ -63,7 +63,7 @@
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
 }
 static method test7(self::A7? a) → dynamic {
-  core::String s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
-  core::String s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
+  core::String? s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String?} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
+  core::String? s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String?} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
index ba69d39..37919d9 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.expect
@@ -63,7 +63,7 @@
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
 }
 static method test7(self::A7? a) → dynamic {
-  core::String s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
-  core::String s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
+  core::String? s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String?} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
+  core::String? s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String?} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
index ba69d39..37919d9 100644
--- a/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.weak.transformed.expect
@@ -63,7 +63,7 @@
   core::String s = let final core::double #t15 = 3.14 in let final core::int #t16 = 0 in let final core::String? #t17 = self::E6|[](#t15, #t16) in #t17.{core::String::==}(null) ?{core::String} let final core::String #t18 = "bar" in let final void #t19 = self::E6|[]=(#t15, #t16, #t18) in #t18 : #t17{core::String};
 }
 static method test7(self::A7? a) → dynamic {
-  core::String s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
-  core::String s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
+  core::String? s = let final self::A7? #t20 = a in #t20.{core::Object::==}(null) ?{core::String?} null : let final core::String #t21 = #t20.{self::A7::foo} in #t21.{core::String::==}(null) ?{core::String} #t20.{self::A7::foo} = "bar" : #t21;
+  core::String? s2 = let final self::A7? #t22 = a in #t22.{core::Object::==}(null) ?{core::String?} null : let final core::String? #t23 = #t22.{self::A7::bar} in #t23.{core::String::==}(null) ?{core::String} #t22.{self::A7::bar} = "bar" : #t23{core::String};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart b/pkg/front_end/testcases/nnbd/issue40093.dart
new file mode 100644
index 0000000..a3cd00e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, 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.
+
+error() {
+  for (late int i = 0; i < 10; ++i) {
+    print(i);
+  }
+  for (late int i in <int>[]) {
+    print(i);
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.outline.expect
new file mode 100644
index 0000000..755fbee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method error() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.expect
new file mode 100644
index 0000000..2d29b22
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  for (core::int i in <core::int>[]) {
+    core::print(i);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect
new file mode 100644
index 0000000..e732a36
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  {
+    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      core::int i = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::print(i);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.expect
new file mode 100644
index 0000000..2d29b22
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  for (core::int i in <core::int>[]) {
+    core::print(i);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect
new file mode 100644
index 0000000..e732a36
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.weak.transformed.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:6:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i = 0; i < 10; ++i) {
+//        ^^^^
+//
+// pkg/front_end/testcases/nnbd/issue40093.dart:9:8: Error: Can't have modifier 'late' here.
+// Try removing 'late'.
+//   for (late int i in <int>[]) {
+//        ^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method error() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::print(i);
+  }
+  {
+    core::Iterator<core::int*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::int*>*>(<core::int>[]).{core::Iterable::iterator};
+    for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
+      core::int i = :sync-for-iterator.{core::Iterator::current};
+      {
+        core::print(i);
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
index 723db80..182f45e 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
@@ -97,20 +97,20 @@
     on dynamic catch(final dynamic late, final core::StackTrace e) {
     }
   }
-  for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print("baz");
   }
-  for (late core::String s in <core::String>["baz"]) {
+  for (core::String s in <core::String>["baz"]) {
     core::print(s);
   }
   block {
     final core::List<core::int> #t1 = <core::int>[];
-    for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
   } =>#t1;
 }
 static method hest() → dynamic async {
-  await for (late core::String s in asy::Stream::fromIterable<core::String>(<core::String*>["hest"])) {
+  await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String*>["hest"])) {
     core::print(s);
   }
   return "hest";
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index 0973de4..b079c14 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -98,15 +98,13 @@
     on dynamic catch(final dynamic late, final core::StackTrace e) {
     }
   }
-  for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print("baz");
   }
   {
     core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      function #s#initializer() → core::String
-        return :sync-for-iterator.{core::Iterator::current};
-      late core::String s = #s#initializer.call();
+      core::String s = :sync-for-iterator.{core::Iterator::current};
       {
         core::print(s);
       }
@@ -114,7 +112,7 @@
   }
   block {
     final core::List<core::int> #t1 = <core::int>[];
-    for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
   } =>#t1;
 }
@@ -144,9 +142,7 @@
               dynamic #t2 = asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool*>(:result)) {
-                function #s#initializer() → core::String
-                  return :for-iterator.{asy::_StreamIterator::current};
-                late core::String s = #s#initializer.call();
+                core::String s = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::print(s);
                 }
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
index 723db80..182f45e 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
@@ -97,20 +97,20 @@
     on dynamic catch(final dynamic late, final core::StackTrace e) {
     }
   }
-  for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print("baz");
   }
-  for (late core::String s in <core::String>["baz"]) {
+  for (core::String s in <core::String>["baz"]) {
     core::print(s);
   }
   block {
     final core::List<core::int> #t1 = <core::int>[];
-    for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
   } =>#t1;
 }
 static method hest() → dynamic async {
-  await for (late core::String s in asy::Stream::fromIterable<core::String>(<core::String*>["hest"])) {
+  await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String*>["hest"])) {
     core::print(s);
   }
   return "hest";
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index 0973de4..b079c14 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -98,15 +98,13 @@
     on dynamic catch(final dynamic late, final core::StackTrace e) {
     }
   }
-  for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
     core::print("baz");
   }
   {
     core::Iterator<core::String*>* :sync-for-iterator = _in::unsafeCast<core::Iterable<core::String*>*>(<core::String>["baz"]).{core::Iterable::iterator};
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
-      function #s#initializer() → core::String
-        return :sync-for-iterator.{core::Iterator::current};
-      late core::String s = #s#initializer.call();
+      core::String s = :sync-for-iterator.{core::Iterator::current};
       {
         core::print(s);
       }
@@ -114,7 +112,7 @@
   }
   block {
     final core::List<core::int> #t1 = <core::int>[];
-    for (late core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
   } =>#t1;
 }
@@ -144,9 +142,7 @@
               dynamic #t2 = asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(_in::unsafeCast<core::bool*>(:result)) {
-                function #s#initializer() → core::String
-                  return :for-iterator.{asy::_StreamIterator::current};
-                late core::String s = #s#initializer.call();
+                core::String s = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::print(s);
                 }
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart
index cd4a076..028e049 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart
@@ -79,9 +79,9 @@
 
   int method3a(int a, int b) => 0;
 
-  int method3b(int a, [int b]) => 0;
+  int method3b(int a, [int b = 42]) => 0;
 
-  int method3c([int a, int b]) => 0;
+  int method3c([int a = 42, int b = 42]) => 0;
 
   int? method4a(int? a, int? b) => 0;
 
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.outline.expect
index ea1d831..50ad3f4 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.outline.expect
@@ -94,9 +94,9 @@
     ;
   method method3a(core::int a, core::int b) → core::int
     ;
-  method method3b(core::int a, [core::int b]) → core::int
+  method method3b(core::int a, [core::int b = 42]) → core::int
     ;
-  method method3c([core::int a, core::int b]) → core::int
+  method method3c([core::int a = 42, core::int b = 42]) → core::int
     ;
   method method4a(core::int? a, core::int? b) → core::int?
     ;
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.expect
index 0f04f45..20453f0 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.expect
@@ -98,9 +98,9 @@
     return 0;
   method method3a(core::int a, core::int b) → core::int
     return 0;
-  method method3b(core::int a, [core::int b = #C1]) → core::int
+  method method3b(core::int a, [core::int b = #C3]) → core::int
     return 0;
-  method method3c([core::int a = #C1, core::int b = #C1]) → core::int
+  method method3c([core::int a = #C3, core::int b = #C3]) → core::int
     return 0;
   method method4a(core::int? a, core::int? b) → core::int?
     return 0;
@@ -226,4 +226,5 @@
 constants  {
   #C1 = null
   #C2 = 0
+  #C3 = 42
 }
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.transformed.expect
index 0f04f45..20453f0 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.strong.transformed.expect
@@ -98,9 +98,9 @@
     return 0;
   method method3a(core::int a, core::int b) → core::int
     return 0;
-  method method3b(core::int a, [core::int b = #C1]) → core::int
+  method method3b(core::int a, [core::int b = #C3]) → core::int
     return 0;
-  method method3c([core::int a = #C1, core::int b = #C1]) → core::int
+  method method3c([core::int a = #C3, core::int b = #C3]) → core::int
     return 0;
   method method4a(core::int? a, core::int? b) → core::int?
     return 0;
@@ -226,4 +226,5 @@
 constants  {
   #C1 = null
   #C2 = 0
+  #C3 = 42
 }
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.expect
index 0f04f45..20453f0 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.expect
@@ -98,9 +98,9 @@
     return 0;
   method method3a(core::int a, core::int b) → core::int
     return 0;
-  method method3b(core::int a, [core::int b = #C1]) → core::int
+  method method3b(core::int a, [core::int b = #C3]) → core::int
     return 0;
-  method method3c([core::int a = #C1, core::int b = #C1]) → core::int
+  method method3c([core::int a = #C3, core::int b = #C3]) → core::int
     return 0;
   method method4a(core::int? a, core::int? b) → core::int?
     return 0;
@@ -226,4 +226,5 @@
 constants  {
   #C1 = null
   #C2 = 0
+  #C3 = 42
 }
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.transformed.expect
index 0f04f45..20453f0 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.weak.transformed.expect
@@ -98,9 +98,9 @@
     return 0;
   method method3a(core::int a, core::int b) → core::int
     return 0;
-  method method3b(core::int a, [core::int b = #C1]) → core::int
+  method method3b(core::int a, [core::int b = #C3]) → core::int
     return 0;
-  method method3c([core::int a = #C1, core::int b = #C1]) → core::int
+  method method3c([core::int a = #C3, core::int b = #C3]) → core::int
     return 0;
   method method4a(core::int? a, core::int? b) → core::int?
     return 0;
@@ -226,4 +226,5 @@
 constants  {
   #C1 = null
   #C2 = 0
+  #C3 = 42
 }
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect
index 83a9a17..a1fe8bf 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -115,13 +101,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -130,13 +109,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect
index 050c5f8..84b205c4 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -160,13 +146,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -175,13 +154,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.weak.expect
index 050c5f8..84b205c4 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.weak.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -160,13 +146,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -175,13 +154,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect
index 51f5591..5dc40b0 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -114,13 +100,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -129,13 +108,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect
index fe57a7b..846f621 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -159,13 +145,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -174,13 +153,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.weak.expect
index fe57a7b..846f621 100644
--- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.weak.expect
@@ -18,13 +18,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: Declared type variables of 'SubInOut.nullableBad' doesn't match those on overridden method 'SuperIn.nullableBad'.
-//   T nullableBad<T>(T t) => null;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:10:8: Context: This is the overridden method ('nullableBad').
-//   int? nullableBad<T>(T t) => 1;
-//        ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:26:5: Error: The return type of the method 'SubInOut.nullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nullableBad'.
 // Change to a subtype of 'int'.
 //   T nullableBad<T>(T t) => null;
@@ -33,13 +26,6 @@
 //   int? nullableBad<T>(T t) => 1;
 //        ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: Declared type variables of 'SubInOut.nonNullableBad' doesn't match those on overridden method 'SuperIn.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:11:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:27:5: Error: The return type of the method 'SubInOut.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperIn.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
@@ -159,13 +145,6 @@
 //   int nonNullableBad<T>(T t) => 2;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: Declared type variables of 'SubOutIn.nullableBad' doesn't match those on overridden method 'SuperOut.nullableBad'.
-//   T? nullableBad<T>(T t) => null;
-//      ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:12:7: Context: This is the overridden method ('nullableBad').
-//   int nullableBad<T>(T t) => 1;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:24:6: Error: The return type of the method 'SubOutIn.nullableBad' is 'T?', which does not match the return type, 'int', of the overridden method, 'SuperOut.nullableBad'.
 // Change to a subtype of 'int'.
 //   T? nullableBad<T>(T t) => null;
@@ -174,13 +153,6 @@
 //   int nullableBad<T>(T t) => 1;
 //       ^
 //
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: Declared type variables of 'SubOutIn.nonNullableBad' doesn't match those on overridden method 'SuperOut.nonNullableBad'.
-//   T nonNullableBad<T>(T t) => t;
-//     ^
-// pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart:13:7: Context: This is the overridden method ('nonNullableBad').
-//   int nonNullableBad<T>(T t) => 2;
-//       ^
-//
 // pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart:25:5: Error: The return type of the method 'SubOutIn.nonNullableBad' is 'T', which does not match the return type, 'int', of the overridden method, 'SuperOut.nonNullableBad'.
 // Change to a subtype of 'int'.
 //   T nonNullableBad<T>(T t) => t;
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart b/pkg/front_end/testcases/nnbd/null_access.dart
new file mode 100644
index 0000000..35b7f16
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  int nonNullableField = 0;
+  int? nullableField;
+  int operator [](int key) => key;
+  void operator []=(int key, int value) {}
+  Class get nonNullableClass => this;
+  Class call() => this;
+}
+
+main() {}
+
+errors(Class? nullableClass, Class nonNullableClass, int? nullableInt,
+    int nonNullableInt) {
+  -nullableInt; // error
+  nullableInt + 2; // error
+  nullableClass[nonNullableInt]; // error
+  nullableClass[nonNullableInt] = nonNullableInt; // error
+  nullableClass[nonNullableInt] += nonNullableInt; // error
+  nullableClass[nonNullableInt] ??= nonNullableInt; // error
+
+  nullableClass?.nonNullableClass[nonNullableInt]; // ok
+  nullableClass?.nonNullableClass[nonNullableInt] = nonNullableInt; // ok
+  nullableClass?.nonNullableClass[nonNullableInt] += nonNullableInt; // ok
+  nullableClass?.nonNullableClass[nonNullableInt] ??= nonNullableInt; // ok
+
+  nullableClass.nonNullableField; // error
+  nullableClass.nonNullableField = 2; // error
+  nullableClass.nonNullableField += 2; // error
+
+  nullableClass?.nonNullableField; // ok
+  nullableClass?.nonNullableField = 2; // ok
+  nullableClass?.nonNullableField += 2; // ok
+
+  nullableClass?.nonNullableClass.nonNullableField; // ok
+  nullableClass?.nonNullableClass.nonNullableField = 2; // ok
+
+  nonNullableClass.nullableField += 2; // error
+  nullableClass?.nullableField += 2; // error
+
+  nullableClass?.nonNullableField ??= 0; // ok
+  nullableClass?.nullableField ??= 0; // ok
+
+  nullableClass?.nonNullableClass.nonNullableField ??= 0; // ok
+  nullableClass?.nonNullableClass.nullableField ??= 0; // ok
+
+  nullableClass(); // error
+  nonNullableClass(); // ok
+  nonNullableClass?.nonNullableClass(); // ok
+  nonNullableClass?.nonNullableClass.nonNullableClass(); // ok
+}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_access.dart.outline.expect
new file mode 100644
index 0000000..a5ae9e3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int nonNullableField;
+  field core::int? nullableField;
+  synthetic constructor •() → self::Class
+    ;
+  operator [](core::int key) → core::int
+    ;
+  operator []=(core::int key, core::int value) → void
+    ;
+  get nonNullableClass() → self::Class
+    ;
+  method call() → self::Class
+    ;
+}
+static method main() → dynamic
+  ;
+static method errors(self::Class? nullableClass, self::Class nonNullableClass, core::int? nullableInt, core::int nonNullableInt) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_access.dart.strong.expect
new file mode 100644
index 0000000..642146a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.strong.expect
@@ -0,0 +1,178 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:18:3: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   -nullableInt; // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:19:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nullableInt + 2; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:20:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt]; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:21:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] = nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:30:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:31:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField = 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField += 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:41:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nonNullableClass.nullableField += 2; // error
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:42:32: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nullableClass?.nullableField += 2; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?. instead.
+//   nullableClass(); // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?.call instead.
+//   nullableClass(); // error
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int nonNullableField = 0;
+  field core::int? nullableField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+  get nonNullableClass() → self::Class
+    return this;
+  method call() → self::Class
+    return this;
+}
+static method main() → dynamic {}
+static method errors(self::Class? nullableClass, self::Class nonNullableClass, core::int? nullableInt, core::int nonNullableInt) → dynamic {
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:18:3: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  -nullableInt; // error
+  ^" in nullableInt.{core::int::unary-}();
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:19:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nullableInt + 2; // error
+              ^" in nullableInt.{core::num::+}(2);
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:20:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt]; // error
+               ^" in nullableClass.{self::Class::[]}(nonNullableInt);
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:21:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] = nonNullableInt; // error
+               ^" in nullableClass.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t5 = nullableClass in let final core::int #t6 = nonNullableInt in let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] += nonNullableInt; // error
+               ^" in #t5.{self::Class::[]=}(#t6, (let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] += nonNullableInt; // error
+               ^" in #t5.{self::Class::[]}(#t6)).{core::num::+}(nonNullableInt));
+  let final self::Class? #t9 = nullableClass in let final core::int #t10 = nonNullableInt in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] ??= nonNullableInt; // error
+               ^" in #t9.{self::Class::[]}(#t10)).{core::num::==}(null) ?{core::int} let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] ??= nonNullableInt; // error
+               ^" in #t9.{self::Class::[]=}(#t10, nonNullableInt) : null;
+  let final self::Class? #t13 = nullableClass in #t13.{core::Object::==}(null) ?{core::int?} null : #t13{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]}(nonNullableInt);
+  let final self::Class? #t14 = nullableClass in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t15 = nullableClass in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::nonNullableClass} in let final core::int #t17 = nonNullableInt in #t16.{self::Class::[]=}(#t17, #t16.{self::Class::[]}(#t17).{core::num::+}(nonNullableInt));
+  let final self::Class? #t18 = nullableClass in #t18.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t19 = #t18{self::Class}.{self::Class::nonNullableClass} in let final core::int #t20 = nonNullableInt in #t19.{self::Class::[]}(#t20).{core::num::==}(null) ?{core::int} #t19.{self::Class::[]=}(#t20, nonNullableInt) : null;
+  let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:30:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField; // error
+                ^^^^^^^^^^^^^^^^" in nullableClass.{self::Class::nonNullableField};
+  let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:31:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField = 2; // error
+                ^^^^^^^^^^^^^^^^" in nullableClass.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t23 = nullableClass in let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField += 2; // error
+                ^^^^^^^^^^^^^^^^" in #t23.{self::Class::nonNullableField} = (let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField += 2; // error
+                ^^^^^^^^^^^^^^^^" in #t23.{self::Class::nonNullableField}).{core::num::+}(2);
+  let final self::Class? #t26 = nullableClass in #t26.{core::Object::==}(null) ?{core::int?} null : #t26{self::Class}.{self::Class::nonNullableField};
+  let final self::Class? #t27 = nullableClass in #t27.{core::Object::==}(null) ?{core::int?} null : #t27{self::Class}.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t28 = nullableClass in #t28.{core::Object::==}(null) ?{core::int?} null : #t28.{self::Class::nonNullableField} = #t28.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t29 = nullableClass in #t29.{core::Object::==}(null) ?{core::int?} null : #t29{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField};
+  let final self::Class? #t30 = nullableClass in #t30.{core::Object::==}(null) ?{core::int?} null : #t30{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField} = 2;
+  let final self::Class #t31 = nonNullableClass in #t31.{self::Class::nullableField} = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:41:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nonNullableClass.nullableField += 2; // error
+                                 ^" in #t31.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t33 = nullableClass in #t33.{core::Object::==}(null) ?{core::int?} null : #t33.{self::Class::nullableField} = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:42:32: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nullableClass?.nullableField += 2; // error
+                               ^" in #t33.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t35 = nullableClass in #t35.{core::Object::==}(null) ?{core::int?} null : #t35.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t35.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t36 = nullableClass in #t36.{core::Object::==}(null) ?{core::int?} null : #t36.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t36.{self::Class::nullableField} = 0 : null;
+  let final self::Class? #t37 = nullableClass in #t37.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t38 = #t37{self::Class}.{self::Class::nonNullableClass} in #t38{self::Class}.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t38{self::Class}.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t39 = nullableClass in #t39.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t40 = #t39{self::Class}.{self::Class::nonNullableClass} in #t40{self::Class}.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t40{self::Class}.{self::Class::nullableField} = 0 : null;
+  let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try calling using ?.call instead.
+  nullableClass(); // error
+               ^" in let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try calling using ?. instead.
+  nullableClass(); // error
+               ^" in nullableClass.{self::Class::call}();
+  nonNullableClass.{self::Class::call}();
+  let final self::Class #t43 = nonNullableClass in #t43.{core::Object::==}(null) ?{self::Class?} null : #t43.{self::Class::nonNullableClass}();
+  let final self::Class #t44 = nonNullableClass in #t44.{core::Object::==}(null) ?{self::Class?} null : #t44.{self::Class::nonNullableClass}.{self::Class::nonNullableClass}();
+}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..642146a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.strong.transformed.expect
@@ -0,0 +1,178 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:18:3: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+//   -nullableInt; // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:19:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nullableInt + 2; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:20:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt]; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:21:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] = nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:30:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:31:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField = 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField += 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:41:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nonNullableClass.nullableField += 2; // error
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:42:32: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   nullableClass?.nullableField += 2; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?. instead.
+//   nullableClass(); // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?.call instead.
+//   nullableClass(); // error
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int nonNullableField = 0;
+  field core::int? nullableField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+  get nonNullableClass() → self::Class
+    return this;
+  method call() → self::Class
+    return this;
+}
+static method main() → dynamic {}
+static method errors(self::Class? nullableClass, self::Class nonNullableClass, core::int? nullableInt, core::int nonNullableInt) → dynamic {
+  let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:18:3: Error: Operator 'unary-' cannot be called on 'int?' because it is potentially null.
+  -nullableInt; // error
+  ^" in nullableInt.{core::int::unary-}();
+  let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:19:15: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nullableInt + 2; // error
+              ^" in nullableInt.{core::num::+}(2);
+  let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:20:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt]; // error
+               ^" in nullableClass.{self::Class::[]}(nonNullableInt);
+  let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:21:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] = nonNullableInt; // error
+               ^" in nullableClass.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t5 = nullableClass in let final core::int #t6 = nonNullableInt in let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] += nonNullableInt; // error
+               ^" in #t5.{self::Class::[]=}(#t6, (let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:22:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] += nonNullableInt; // error
+               ^" in #t5.{self::Class::[]}(#t6)).{core::num::+}(nonNullableInt));
+  let final self::Class? #t9 = nullableClass in let final core::int #t10 = nonNullableInt in (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] ??= nonNullableInt; // error
+               ^" in #t9.{self::Class::[]}(#t10)).{core::num::==}(null) ?{core::int} let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:23:16: Error: Operator '[]=' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+  nullableClass[nonNullableInt] ??= nonNullableInt; // error
+               ^" in #t9.{self::Class::[]=}(#t10, nonNullableInt) : null;
+  let final self::Class? #t13 = nullableClass in #t13.{core::Object::==}(null) ?{core::int?} null : #t13{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]}(nonNullableInt);
+  let final self::Class? #t14 = nullableClass in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t15 = nullableClass in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::nonNullableClass} in let final core::int #t17 = nonNullableInt in #t16.{self::Class::[]=}(#t17, #t16.{self::Class::[]}(#t17).{core::num::+}(nonNullableInt));
+  let final self::Class? #t18 = nullableClass in #t18.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t19 = #t18{self::Class}.{self::Class::nonNullableClass} in let final core::int #t20 = nonNullableInt in #t19.{self::Class::[]}(#t20).{core::num::==}(null) ?{core::int} #t19.{self::Class::[]=}(#t20, nonNullableInt) : null;
+  let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:30:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField; // error
+                ^^^^^^^^^^^^^^^^" in nullableClass.{self::Class::nonNullableField};
+  let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:31:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField = 2; // error
+                ^^^^^^^^^^^^^^^^" in nullableClass.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t23 = nullableClass in let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField += 2; // error
+                ^^^^^^^^^^^^^^^^" in #t23.{self::Class::nonNullableField} = (let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:32:17: Error: Property 'nonNullableField' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try accessing using ?. instead.
+  nullableClass.nonNullableField += 2; // error
+                ^^^^^^^^^^^^^^^^" in #t23.{self::Class::nonNullableField}).{core::num::+}(2);
+  let final self::Class? #t26 = nullableClass in #t26.{core::Object::==}(null) ?{core::int?} null : #t26{self::Class}.{self::Class::nonNullableField};
+  let final self::Class? #t27 = nullableClass in #t27.{core::Object::==}(null) ?{core::int?} null : #t27{self::Class}.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t28 = nullableClass in #t28.{core::Object::==}(null) ?{core::int?} null : #t28.{self::Class::nonNullableField} = #t28.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t29 = nullableClass in #t29.{core::Object::==}(null) ?{core::int?} null : #t29{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField};
+  let final self::Class? #t30 = nullableClass in #t30.{core::Object::==}(null) ?{core::int?} null : #t30{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField} = 2;
+  let final self::Class #t31 = nonNullableClass in #t31.{self::Class::nullableField} = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:41:34: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nonNullableClass.nullableField += 2; // error
+                                 ^" in #t31.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t33 = nullableClass in #t33.{core::Object::==}(null) ?{core::int?} null : #t33.{self::Class::nullableField} = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:42:32: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  nullableClass?.nullableField += 2; // error
+                               ^" in #t33.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t35 = nullableClass in #t35.{core::Object::==}(null) ?{core::int?} null : #t35.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t35.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t36 = nullableClass in #t36.{core::Object::==}(null) ?{core::int?} null : #t36.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t36.{self::Class::nullableField} = 0 : null;
+  let final self::Class? #t37 = nullableClass in #t37.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t38 = #t37{self::Class}.{self::Class::nonNullableClass} in #t38{self::Class}.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t38{self::Class}.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t39 = nullableClass in #t39.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t40 = #t39{self::Class}.{self::Class::nonNullableClass} in #t40{self::Class}.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t40{self::Class}.{self::Class::nullableField} = 0 : null;
+  let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try calling using ?.call instead.
+  nullableClass(); // error
+               ^" in let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/nnbd/null_access.dart:50:16: Error: Method 'call' cannot be called on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+Try calling using ?. instead.
+  nullableClass(); // error
+               ^" in nullableClass.{self::Class::call}();
+  nonNullableClass.{self::Class::call}();
+  let final self::Class #t43 = nonNullableClass in #t43.{core::Object::==}(null) ?{self::Class?} null : #t43.{self::Class::nonNullableClass}();
+  let final self::Class #t44 = nonNullableClass in #t44.{core::Object::==}(null) ?{self::Class?} null : #t44.{self::Class::nonNullableClass}.{self::Class::nonNullableClass}();
+}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_access.dart.weak.expect
new file mode 100644
index 0000000..e4fc4d9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.weak.expect
@@ -0,0 +1,128 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:18:3: Warning: Operator 'unary-' is called on 'int?' which is potentially null.
+//   -nullableInt; // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:19:15: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nullableInt + 2; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:20:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt]; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:21:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] = nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:30:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:31:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField = 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:32:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField += 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:41:34: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nonNullableClass.nullableField += 2; // error
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:42:32: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nullableClass?.nullableField += 2; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Warning: Method 'call' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?. instead.
+//   nullableClass(); // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Warning: Expression of type 'Class?' is used as a function, but it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?.call instead.
+//   nullableClass(); // error
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int nonNullableField = 0;
+  field core::int? nullableField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+  get nonNullableClass() → self::Class
+    return this;
+  method call() → self::Class
+    return this;
+}
+static method main() → dynamic {}
+static method errors(self::Class? nullableClass, self::Class nonNullableClass, core::int? nullableInt, core::int nonNullableInt) → dynamic {
+  nullableInt.{core::int::unary-}();
+  nullableInt.{core::num::+}(2);
+  nullableClass.{self::Class::[]}(nonNullableInt);
+  nullableClass.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t1 = nullableClass in let final core::int #t2 = nonNullableInt in #t1.{self::Class::[]=}(#t2, #t1.{self::Class::[]}(#t2).{core::num::+}(nonNullableInt));
+  let final self::Class? #t3 = nullableClass in let final core::int #t4 = nonNullableInt in #t3.{self::Class::[]}(#t4).{core::num::==}(null) ?{core::int} #t3.{self::Class::[]=}(#t4, nonNullableInt) : null;
+  let final self::Class? #t5 = nullableClass in #t5.{core::Object::==}(null) ?{core::int?} null : #t5{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]}(nonNullableInt);
+  let final self::Class? #t6 = nullableClass in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t7 = nullableClass in #t7.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t8 = #t7{self::Class}.{self::Class::nonNullableClass} in let final core::int #t9 = nonNullableInt in #t8.{self::Class::[]=}(#t9, #t8.{self::Class::[]}(#t9).{core::num::+}(nonNullableInt));
+  let final self::Class? #t10 = nullableClass in #t10.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t11 = #t10{self::Class}.{self::Class::nonNullableClass} in let final core::int #t12 = nonNullableInt in #t11.{self::Class::[]}(#t12).{core::num::==}(null) ?{core::int} #t11.{self::Class::[]=}(#t12, nonNullableInt) : null;
+  nullableClass.{self::Class::nonNullableField};
+  nullableClass.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t13 = nullableClass in #t13.{self::Class::nonNullableField} = #t13.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t14 = nullableClass in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::nonNullableField};
+  let final self::Class? #t15 = nullableClass in #t15.{core::Object::==}(null) ?{core::int?} null : #t15{self::Class}.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t16 = nullableClass in #t16.{core::Object::==}(null) ?{core::int?} null : #t16.{self::Class::nonNullableField} = #t16.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t17 = nullableClass in #t17.{core::Object::==}(null) ?{core::int?} null : #t17{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField};
+  let final self::Class? #t18 = nullableClass in #t18.{core::Object::==}(null) ?{core::int?} null : #t18{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField} = 2;
+  let final self::Class #t19 = nonNullableClass in #t19.{self::Class::nullableField} = #t19.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t20 = nullableClass in #t20.{core::Object::==}(null) ?{core::int?} null : #t20.{self::Class::nullableField} = #t20.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t21 = nullableClass in #t21.{core::Object::==}(null) ?{core::int?} null : #t21.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t21.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t22 = nullableClass in #t22.{core::Object::==}(null) ?{core::int?} null : #t22.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t22.{self::Class::nullableField} = 0 : null;
+  let final self::Class? #t23 = nullableClass in #t23.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t24 = #t23{self::Class}.{self::Class::nonNullableClass} in #t24{self::Class}.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t24{self::Class}.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t25 = nullableClass in #t25.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t26 = #t25{self::Class}.{self::Class::nonNullableClass} in #t26{self::Class}.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t26{self::Class}.{self::Class::nullableField} = 0 : null;
+  nullableClass.{self::Class::call}();
+  nonNullableClass.{self::Class::call}();
+  let final self::Class #t27 = nonNullableClass in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::nonNullableClass}();
+  let final self::Class #t28 = nonNullableClass in #t28.{core::Object::==}(null) ?{self::Class?} null : #t28.{self::Class::nonNullableClass}.{self::Class::nonNullableClass}();
+}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_access.dart.weak.transformed.expect
new file mode 100644
index 0000000..e4fc4d9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.weak.transformed.expect
@@ -0,0 +1,128 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:18:3: Warning: Operator 'unary-' is called on 'int?' which is potentially null.
+//   -nullableInt; // error
+//   ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:19:15: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nullableInt + 2; // error
+//               ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:20:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt]; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:21:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] = nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:22:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] += nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Warning: Operator '[]' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:23:16: Warning: Operator '[]=' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+//   nullableClass[nonNullableInt] ??= nonNullableInt; // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:30:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:31:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField = 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:32:17: Warning: Property 'nonNullableField' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try accessing using ?. instead.
+//   nullableClass.nonNullableField += 2; // error
+//                 ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:41:34: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nonNullableClass.nullableField += 2; // error
+//                                  ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:42:32: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   nullableClass?.nullableField += 2; // error
+//                                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Warning: Method 'call' is called on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?. instead.
+//   nullableClass(); // error
+//                ^
+//
+// pkg/front_end/testcases/nnbd/null_access.dart:50:16: Warning: Expression of type 'Class?' is used as a function, but it's potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/null_access.dart'.
+// Try calling using ?.call instead.
+//   nullableClass(); // error
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int nonNullableField = 0;
+  field core::int? nullableField = null;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+  get nonNullableClass() → self::Class
+    return this;
+  method call() → self::Class
+    return this;
+}
+static method main() → dynamic {}
+static method errors(self::Class? nullableClass, self::Class nonNullableClass, core::int? nullableInt, core::int nonNullableInt) → dynamic {
+  nullableInt.{core::int::unary-}();
+  nullableInt.{core::num::+}(2);
+  nullableClass.{self::Class::[]}(nonNullableInt);
+  nullableClass.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t1 = nullableClass in let final core::int #t2 = nonNullableInt in #t1.{self::Class::[]=}(#t2, #t1.{self::Class::[]}(#t2).{core::num::+}(nonNullableInt));
+  let final self::Class? #t3 = nullableClass in let final core::int #t4 = nonNullableInt in #t3.{self::Class::[]}(#t4).{core::num::==}(null) ?{core::int} #t3.{self::Class::[]=}(#t4, nonNullableInt) : null;
+  let final self::Class? #t5 = nullableClass in #t5.{core::Object::==}(null) ?{core::int?} null : #t5{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]}(nonNullableInt);
+  let final self::Class? #t6 = nullableClass in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{self::Class}.{self::Class::nonNullableClass}.{self::Class::[]=}(nonNullableInt, nonNullableInt);
+  let final self::Class? #t7 = nullableClass in #t7.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t8 = #t7{self::Class}.{self::Class::nonNullableClass} in let final core::int #t9 = nonNullableInt in #t8.{self::Class::[]=}(#t9, #t8.{self::Class::[]}(#t9).{core::num::+}(nonNullableInt));
+  let final self::Class? #t10 = nullableClass in #t10.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t11 = #t10{self::Class}.{self::Class::nonNullableClass} in let final core::int #t12 = nonNullableInt in #t11.{self::Class::[]}(#t12).{core::num::==}(null) ?{core::int} #t11.{self::Class::[]=}(#t12, nonNullableInt) : null;
+  nullableClass.{self::Class::nonNullableField};
+  nullableClass.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t13 = nullableClass in #t13.{self::Class::nonNullableField} = #t13.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t14 = nullableClass in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::nonNullableField};
+  let final self::Class? #t15 = nullableClass in #t15.{core::Object::==}(null) ?{core::int?} null : #t15{self::Class}.{self::Class::nonNullableField} = 2;
+  let final self::Class? #t16 = nullableClass in #t16.{core::Object::==}(null) ?{core::int?} null : #t16.{self::Class::nonNullableField} = #t16.{self::Class::nonNullableField}.{core::num::+}(2);
+  let final self::Class? #t17 = nullableClass in #t17.{core::Object::==}(null) ?{core::int?} null : #t17{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField};
+  let final self::Class? #t18 = nullableClass in #t18.{core::Object::==}(null) ?{core::int?} null : #t18{self::Class}.{self::Class::nonNullableClass}.{self::Class::nonNullableField} = 2;
+  let final self::Class #t19 = nonNullableClass in #t19.{self::Class::nullableField} = #t19.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t20 = nullableClass in #t20.{core::Object::==}(null) ?{core::int?} null : #t20.{self::Class::nullableField} = #t20.{self::Class::nullableField}.{core::num::+}(2);
+  let final self::Class? #t21 = nullableClass in #t21.{core::Object::==}(null) ?{core::int?} null : #t21.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t21.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t22 = nullableClass in #t22.{core::Object::==}(null) ?{core::int?} null : #t22.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t22.{self::Class::nullableField} = 0 : null;
+  let final self::Class? #t23 = nullableClass in #t23.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t24 = #t23{self::Class}.{self::Class::nonNullableClass} in #t24{self::Class}.{self::Class::nonNullableField}.{core::num::==}(null) ?{core::int} #t24{self::Class}.{self::Class::nonNullableField} = 0 : null;
+  let final self::Class? #t25 = nullableClass in #t25.{core::Object::==}(null) ?{core::int?} null : let final self::Class? #t26 = #t25{self::Class}.{self::Class::nonNullableClass} in #t26{self::Class}.{self::Class::nullableField}.{core::num::==}(null) ?{core::int} #t26{self::Class}.{self::Class::nullableField} = 0 : null;
+  nullableClass.{self::Class::call}();
+  nonNullableClass.{self::Class::call}();
+  let final self::Class #t27 = nonNullableClass in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::nonNullableClass}();
+  let final self::Class #t28 = nonNullableClass in #t28.{core::Object::==}(null) ?{self::Class?} null : #t28.{self::Class::nonNullableClass}.{self::Class::nonNullableClass}();
+}
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.expect
index dbbbc73..f74ed66 100644
--- a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.expect
@@ -14,7 +14,7 @@
 }
 static method main() → dynamic {
   self::Class? c = new self::Class::•();
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class?} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.transformed.expect
index dbbbc73..f74ed66 100644
--- a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
 }
 static method main() → dynamic {
   self::Class? c = new self::Class::•();
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class?} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.expect
index dbbbc73..f74ed66 100644
--- a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.expect
@@ -14,7 +14,7 @@
 }
 static method main() → dynamic {
   self::Class? c = new self::Class::•();
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class?} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.transformed.expect
index dbbbc73..f74ed66 100644
--- a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.weak.transformed.expect
@@ -14,7 +14,7 @@
 }
 static method main() → dynamic {
   self::Class? c = new self::Class::•();
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t2 = #t1{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t2.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t3 = #t2{self::Class}.{self::Class::getter1}.{self::Class::getter2} in #t3.{core::Object::==}(null) ?{self::Class?} null : #t3{self::Class}.{self::Class::field} = c{self::Class};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart b/pkg/front_end/testcases/nnbd/null_shorting.dart
index 14c7e38..c1f8a44 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart
@@ -2,187 +2,250 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-class Class {
-  Class? field;
-  Class method() => property;
+class Class1 {
+  Class1? get property => null;
 
-  Class? operator [](Class? key) => field;
-  void operator []=(Class? key, Class? value) {
-    field = value;
+  void set property(Class1? value) {}
+
+  Class1 get property1 => new Class1();
+
+  Class2 get property2 => new Class2();
+
+  Class1? get nullable1 => property1;
+
+  void set nullable1(Class1? value) {
+    property = value;
   }
 
-  Class? operator +(int value) => field;
+  Class1 nonNullable1Method() => nonNullable1;
 
-  Class? operator -() => field;
+  Class1? operator [](Class1? key) => nullable1;
 
-  Class get property => this;
+  void operator []=(Class1? key, Class1? value) {
+    property = value;
+  }
+
+  Class1? operator +(int value) => nullable1;
+
+  Class1? operator -() => nullable1;
+
+  Class1 get nonNullable1 => property1;
+
+  Class2 get nonNullable2 => property2;
+}
+
+class Class2 {
+  Class2 get property => this;
+
+  void set property(Class2 value) {}
+
+  Class2 nonNullable2Method() => nonNullable2;
+
+  Class2 operator [](Class2? key) => property;
+
+  void operator []=(Class2? key, Class2? value) => property;
+
+  Class2 operator +(int value) => property;
+
+  Class2 operator -() => property;
+
+  Class2 get nonNullable2 => property;
+
+  void set nonNullable2(Class2 value) {
+    property = value;
+  }
+}
+
+class Class3 {
+  Class2? get property => null;
+
+  Class2? operator [](Class3? key) => property;
 }
 
 main() {
   propertyAccess(null);
-  indexAccess(null);
-  operatorAccess(null);
+  indexAccess(null, null, null);
+  operatorAccess(null, null);
   ifNull(null);
 }
 
-void propertyAccess(Class? c) {
-  c?.field;
-  c?.field = new Class();
-  c = c?.field = new Class();
-  c?.method();
+void propertyAccess(Class1? n1) {
+  Class1? nullable1 = n1;
 
-  c?.property.field;
-  c?.field?.field;
-  c?.property.field?.field;
-  c?.property.field = new Class();
-  c?.field?.field = new Class();
-  c?.property.field?.field = new Class();
-  (c?.field)?.field;
-  throws(() => (c?.field = new Class()).field);
-  throws(() => (c?.method()).field);
-  c = c?.property.field = new Class();
-  c = c?.field?.field = new Class();
-  c = c?.property.field?.field = new Class();
-  c?.field?.method();
-  c?.field = new Class().field;
-  c = c?.field = new Class().field;
-  c?.field = new Class().field = new Class();
-  c = c?.field = new Class().field = new Class();
-  c?.field = new Class().method();
-  c = c?.field = new Class().method();
-  c?.method().field;
-  c?.method().field = new Class();
-  c?.method().method();
+  n1?.nullable1;
+  n1?.nullable1 = new Class1();
+  nullable1 = n1?.nullable1 = new Class1();
+  n1?.nonNullable1Method();
 
-  c?.property.property.field;
-  c?.property.property.field = new Class();
-  c = c?.property.property.field = new Class();
-  c?.property.field?.method();
-  c?.field = new Class().property.field;
-  c = c?.field = new Class().property.field;
-  c?.field = new Class().property.field = new Class();
-  c = c?.field = new Class().property.field = new Class();
-  c?.field = new Class().property.method();
-  c = c?.field = new Class().property.method();
-  c?.method().property.field;
-  c?.method().property.field = new Class();
-  c?.method().property.method();
+  n1?.nonNullable1.nullable1;
+  n1?.nullable1?.nullable1;
+  n1?.nonNullable1.nullable1?.nullable1;
+  n1?.nonNullable1.nullable1 = new Class1();
+  n1?.nullable1?.nullable1 = new Class1();
+  n1?.nonNullable1.nullable1?.nullable1 = new Class1();
+  (n1?.nullable1)?.nullable1;
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1();
+  nullable1 = n1?.nullable1?.nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nullable1?.nullable1 = new Class1();
+  n1?.nullable1?.nonNullable1Method();
+  n1?.nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nullable1;
+  n1?.nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1Method();
+  n1?.nonNullable1Method().nullable1;
+  n1?.nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1Method();
 
-  c?.property.field = new Class().field;
-  c = c?.property.field = new Class().field;
-  c?.property.field = new Class().field = new Class();
-  c = c?.property.field = new Class().field = new Class();
-  c?.property.field = new Class().method();
-  c = c?.property.field = new Class().method();
-  c?.field = new Class().field = new Class().field;
-  c = c?.field = new Class().field = new Class().field;
-  c?.field = new Class().field = new Class().field = new Class();
-  c = c?.field = new Class().field = new Class().field = new Class();
-  c?.field = new Class().field = new Class().method();
-  c = c?.field = new Class().field = new Class().method();
-  c?.method().field = new Class().field;
-  c = c?.method().field = new Class().field;
-  c?.method().field = new Class().field = new Class();
-  c = c?.method().field = new Class().field = new Class();
-  c?.method().field = new Class().method();
-  c = c?.method().field = new Class().method();
+  n1?.nonNullable1.nonNullable1.nullable1;
+  n1?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  n1?.nonNullable1.nullable1?.nonNullable1Method();
+  n1?.nullable1 = new Class1().nonNullable1.nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1.nullable1;
+  n1?.nullable1 = new Class1().nonNullable1.nullable1 = new Class1();
+  nullable1 =
+      n1?.nullable1 = new Class1().nonNullable1.nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1.nonNullable1Method();
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1.nonNullable1Method();
+  n1?.nonNullable1Method().nonNullable1.nullable1;
+  n1?.nonNullable1Method().nonNullable1.nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1.nonNullable1Method();
 
-  c?.property.method().field;
-  c?.property.method().field = new Class();
-  c = c?.property.method().field = new Class();
-  c?.property.method().method();
-  c?.field = new Class().method().field;
-  c = c?.field = new Class().method().field;
-  c?.field = new Class().method().field = new Class();
-  c = c?.field = new Class().method().field = new Class();
-  c?.field = new Class().method().method();
-  c = c?.field = new Class().method().method();
-  c?.method().method().field;
-  c?.method().method().field = new Class();
-  c?.method().method().method();
+  n1?.nonNullable1.nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1().nullable1;
+  n1?.nonNullable1.nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 =
+      n1?.nonNullable1.nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nonNullable1.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1().nonNullable1Method();
+  n1?.nullable1 = new Class1().nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nullable1 = new Class1().nullable1;
+  n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nonNullable1Method();
+  n1?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  n1?.nonNullable1Method().nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1Method().nullable1 =
+      new Class1().nullable1 = new Class1();
+  n1?.nonNullable1Method().nullable1 = new Class1().nonNullable1Method();
+  nullable1 =
+      n1?.nonNullable1Method().nullable1 = new Class1().nonNullable1Method();
 
-  c?.method()?.method();
+  n1?.nonNullable1.nonNullable1Method().nullable1;
+  n1?.nonNullable1.nonNullable1Method().nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1.nonNullable1Method().nonNullable1Method();
+  n1?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  n1?.nullable1 = new Class1().nonNullable1Method().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 =
+      new Class1().nonNullable1Method().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1Method().nonNullable1Method();
+  nullable1 =
+      n1?.nullable1 = new Class1().nonNullable1Method().nonNullable1Method();
+  n1?.nonNullable1Method().nonNullable1Method().nullable1;
+  n1?.nonNullable1Method().nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1Method().nonNullable1Method();
+
+  n1?.nonNullable1Method()?.nonNullable1Method();
 }
 
-void indexAccess(Class? c) {
-  c?.[c];
-  c?.[c] = new Class();
-  c?.[c]?.method();
-  c?.field[c];
-  c?.field[c] = new Class();
-  c = c?.field[c] = new Class();
-  c?.field[c]?.method();
-  c?.field[c] += 0;
-  c = c?.field[c] += 0;
-  c?.[c] ??= c;
-  c = c?.[c] ??= c;
-  c?.[c] += 0;
-  c = c?.[c] += 0;
-  c?.[c] += 0;
-  c = c?.[c] += 0;
-  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
-  //  update.
-  c?.[c]++;
-  c = c?.[c]++;
-  ++c?.[c];
-  c = ++c?.[c];
-  c?.field[c]++;
-  c = c?.field[c]++;
-  ++c?.field[c];
-  c = ++c?.field[c];
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {
+  Class1? nullable1 = n1;
+  Class2? nullable2 = n2;
+  Class3? nullable3 = n3;
 
-  c?.field[c][c];
-  c?.field[c][c] = new Class();
-  c = c?.field[c][c] = new Class();
-  c?.field[c][c]?.method();
-  c?.field[c][c] += 0;
-  c = c?.field[c][c] += 0;
+  n1?.[nullable1];
+  n1?.[nullable1] = new Class1();
+  n1?.[nullable1]?.nonNullable1Method();
+  n1?.nonNullable1[nullable1];
+  n1?.nonNullable1[nullable1] = new Class1();
+  nullable1 = n1?.nonNullable1[nullable1] = new Class1();
+  n1?.nonNullable1[nullable1]?.nonNullable1Method();
+  n1?.nonNullable2[nullable2] += 0;
+  nullable2 = n1?.nonNullable2[nullable2] += 0;
+  n1?.[nullable1] ??= nullable1;
+  nullable1 = n1?.[nullable1] ??= nullable1;
+  n2?.[nullable2] += 0;
+  nullable2 = n2?.[nullable2] += 0;
+  n2?.[nullable2] += 0;
+  nullable2 = n2?.[nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  c?.field[c][c]++;
-  c = c?.field[c][c]++;
-  ++c?.field[c][c];
-  c = ++c?.field[c][c];
+  n2?.[nullable2]++;
+  nullable2 = n2?.[nullable2]++;
+  ++n2?.[nullable2];
+  nullable2 = ++n2?.[nullable2];
+  n1?.nonNullable2[nullable2]++;
+  nullable2 = n1?.nonNullable2[nullable2]++;
+  ++n1?.nonNullable2[nullable2];
+  nullable2 = ++n1?.nonNullable2[nullable2];
 
-  c?.[c]?.[c];
-  c?.[c]?.[c] = new Class();
-  c = c?.[c]?.[c] = new Class();
-  c?.[c]?.[c]?.method();
-  c = c?.[c]?.[c]?.method();
-  c?.[c]?.[c] ??= c;
-  c = c?.[c]?.[c] ??= c;
-  c?.[c]?.[c] += 0;
-  c = c?.[c]?.[c] += 0;
+  n1?.nonNullable2[nullable2][nullable2];
+  n1?.nonNullable2[nullable2][nullable2] = new Class2();
+  nullable2 = n1?.nonNullable2[nullable2][nullable2] = new Class2();
+  n1?.nonNullable2[nullable2][nullable2]?.nonNullable2Method();
+  n1?.nonNullable2[nullable2][nullable2] += 0;
+  nullable2 = n1?.nonNullable2[nullable2][nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  c?.[c]?.[c]++;
-  c = c?.[c]?.[c]++;
-  ++c?.[c]?.[c];
-  c = ++c?.[c]?.[c];
+  n1?.nonNullable2[nullable2][nullable2]++;
+  nullable2 = n1?.nonNullable2[nullable2][nullable2]++;
+  ++n1?.nonNullable2[nullable2][nullable2];
+  nullable2 = ++n1?.nonNullable2[nullable2][nullable2];
+
+  n1?.[nullable1]?.[nullable1];
+  n1?.[nullable1]?.[nullable1] = new Class1();
+  nullable1 = n1?.[nullable1]?.[nullable1] = new Class1();
+  n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  nullable1 = n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  n1?.[nullable1]?.[nullable1] ??= nullable1;
+  nullable1 = n1?.[nullable1]?.[nullable1] ??= nullable1;
+  n3?.[nullable3]?.[nullable2] += 0;
+  nullable2 = n3?.[nullable3]?.[nullable2] += 0;
+  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
+  //  update.
+  n3?.[nullable3]?.[nullable2]++;
+  nullable2 = n3?.[nullable3]?.[nullable2]++;
+  ++n3?.[nullable3]?.[nullable2];
+  nullable2 = ++n3?.[nullable3]?.[nullable2];
 }
 
-void operatorAccess(Class? c) {
-  throws(() => c?.field + 0);
-  throws(() => -c?.field);
-  c?.field += 0;
-  c = c?.field += 0;
-  c?.property.field += 0;
-  c = c?.property.field += 0;
+void operatorAccess(Class1? n1, Class2? n2) {
+  Class2? nullable2 = n2;
+
+  throws(() => n1?.nonNullable1 + 0);
+  throws(() => -n1?.nonNullable1);
+  n2?.nonNullable2 += 0;
+  nullable2 = n2?.nonNullable2 += 0;
+  n2?.nonNullable2.nonNullable2 += 0;
+  nullable2 = n2?.nonNullable2.nonNullable2 += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  c?.field++;
-  c = c?.field++;
-  ++c?.field;
-  c = ++c?.field;
+  n2?.nonNullable2++;
+  nullable2 = n2?.nonNullable2++;
+  ++n2?.nonNullable2;
+  nullable2 = ++n2?.nonNullable2;
 }
 
-void ifNull(Class? c) {
-  c?.field ??= c;
-  c = c?.field ??= c;
-  c?.property.field ??= c;
-  c = c?.property.field ??= c;
-  c?.field[c] ??= c;
-  c = c?.field[c] ??= c;
+void ifNull(Class1? n1) {
+  Class1? nullable1 = n1;
+
+  n1?.nullable1 ??= n1;
+  n1 = n1?.nullable1 ??= n1;
+  n1?.nonNullable1.nullable1 ??= n1;
+  n1 = n1?.nonNullable1.nullable1 ??= n1;
+  n1?.nonNullable1[n1] ??= n1;
+  n1 = n1?.nonNullable1[n1] ??= n1;
 }
 
 void throws(void Function() f) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect
index 2ee176f..6eb9d37 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect
@@ -2,32 +2,75 @@
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? field;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     ;
-  method method() → self::Class
+  get property() → self::Class1?
     ;
-  operator [](self::Class? key) → self::Class?
+  set property(self::Class1? value) → void
     ;
-  operator []=(self::Class? key, self::Class? value) → void
+  get property1() → self::Class1
     ;
-  operator +(core::int value) → self::Class?
+  get property2() → self::Class2
     ;
-  operator unary-() → self::Class?
+  get nullable1() → self::Class1?
     ;
-  get property() → self::Class
+  set nullable1(self::Class1? value) → void
+    ;
+  method nonNullable1Method() → self::Class1
+    ;
+  operator [](self::Class1? key) → self::Class1?
+    ;
+  operator []=(self::Class1? key, self::Class1? value) → void
+    ;
+  operator +(core::int value) → self::Class1?
+    ;
+  operator unary-() → self::Class1?
+    ;
+  get nonNullable1() → self::Class1
+    ;
+  get nonNullable2() → self::Class2
+    ;
+}
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    ;
+  get property() → self::Class2
+    ;
+  set property(self::Class2 value) → void
+    ;
+  method nonNullable2Method() → self::Class2
+    ;
+  operator [](self::Class2? key) → self::Class2
+    ;
+  operator []=(self::Class2? key, self::Class2? value) → void
+    ;
+  operator +(core::int value) → self::Class2
+    ;
+  operator unary-() → self::Class2
+    ;
+  get nonNullable2() → self::Class2
+    ;
+  set nonNullable2(self::Class2 value) → void
+    ;
+}
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    ;
+  get property() → self::Class2?
+    ;
+  operator [](self::Class3? key) → self::Class2?
     ;
 }
 static method main() → dynamic
   ;
-static method propertyAccess(self::Class? c) → void
+static method propertyAccess(self::Class1? n1) → void
   ;
-static method indexAccess(self::Class? c) → void
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void
   ;
-static method operatorAccess(self::Class? c) → void
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void
   ;
-static method ifNull(self::Class? c) → void
+static method ifNull(self::Class1? n1) → void
   ;
 static method throws(() → void f) → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect
index f3fc966..5e1627d 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect
@@ -1,172 +1,262 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
-  method method() → self::Class
-    return this.{self::Class::property};
-  operator [](self::Class? key) → self::Class?
-    return this.{self::Class::field};
-  operator []=(self::Class? key, self::Class? value) → void {
-    this.{self::Class::field} = value;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
+  get nullable1() → self::Class1?
+    return this.{self::Class1::property1};
+  set nullable1(self::Class1? value) → void {
+    this.{self::Class1::property} = value;
   }
-  operator +(core::int value) → self::Class?
-    return this.{self::Class::field};
-  operator unary-() → self::Class?
-    return this.{self::Class::field};
-  get property() → self::Class
+  method nonNullable1Method() → self::Class1
+    return this.{self::Class1::nonNullable1};
+  operator [](self::Class1? key) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator []=(self::Class1? key, self::Class1? value) → void {
+    this.{self::Class1::property} = value;
+  }
+  operator +(core::int value) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator unary-() → self::Class1?
+    return this.{self::Class1::nullable1};
+  get nonNullable1() → self::Class1
+    return this.{self::Class1::property1};
+  get nonNullable2() → self::Class2
+    return this.{self::Class1::property2};
+}
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
     return this;
+  set property(self::Class2 value) → void {}
+  method nonNullable2Method() → self::Class2
+    return this.{self::Class2::nonNullable2};
+  operator [](self::Class2? key) → self::Class2
+    return this.{self::Class2::property};
+  operator []=(self::Class2? key, self::Class2? value) → void
+    return this.{self::Class2::property};
+  operator +(core::int value) → self::Class2
+    return this.{self::Class2::property};
+  operator unary-() → self::Class2
+    return this.{self::Class2::property};
+  get nonNullable2() → self::Class2
+    return this.{self::Class2::property};
+  set nonNullable2(self::Class2 value) → void {
+    this.{self::Class2::property} = value;
+  }
+}
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
+  operator [](self::Class3? key) → self::Class2?
+    return this.{self::Class3::property};
 }
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : #t1{self::Class}.{self::Class::field};
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : #t2{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t4 = c{self::Class} in #t4.{core::Object::==}(null) ?{self::Class} null : #t4.{self::Class::method}();
-  let final self::Class #t5 = c{self::Class} in #t5.{core::Object::==}(null) ?{self::Class?} null : #t5.{self::Class::property}.{self::Class::field};
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t7 = #t6.{self::Class::field} in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::field};
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = #t8.{self::Class::property}.{self::Class::field} in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::field};
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class} null : #t10.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t11 = c{self::Class} in #t11.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t12 = #t11.{self::Class::field} in #t12.{core::Object::==}(null) ?{self::Class} null : #t12{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = #t13.{self::Class::property}.{self::Class::field} in #t14.{core::Object::==}(null) ?{self::Class} null : #t14{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class? #t15 = let final self::Class #t16 = c{self::Class} in #t16.{core::Object::==}(null) ?{self::Class?} null : #t16.{self::Class::field} in #t15.{core::Object::==}(null) ?{self::Class?} null : #t15{self::Class}.{self::Class::field};
-  self::throws(() → self::Class? => (let final self::Class? #t17 = c in #t17.{core::Object::==}(null) ?{self::Class} null : #t17{self::Class}.{self::Class::field} = new self::Class::•()).{self::Class::field});
-  self::throws(() → self::Class? => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{self::Class} null : #t18{self::Class}.{self::Class::method}()).{self::Class::field});
-  c = let final self::Class #t19 = c{self::Class} in #t19.{core::Object::==}(null) ?{self::Class} null : #t19.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t20 = c{self::Class} in #t20.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t21 = #t20.{self::Class::field} in #t21.{core::Object::==}(null) ?{self::Class} null : #t21{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t22 = c{self::Class} in #t22.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t23 = #t22.{self::Class::property}.{self::Class::field} in #t23.{core::Object::==}(null) ?{self::Class} null : #t23{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t24 = c{self::Class} in #t24.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t25 = #t24.{self::Class::field} in #t25.{core::Object::==}(null) ?{self::Class} null : #t25{self::Class}.{self::Class::method}();
-  let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class?} null : #t26.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t27 = c{self::Class} in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t28 = c in #t28.{core::Object::==}(null) ?{self::Class} null : #t28{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t29 = c in #t29.{core::Object::==}(null) ?{self::Class} null : #t29{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : #t30.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t31 = c{self::Class} in #t31.{core::Object::==}(null) ?{self::Class} null : #t31.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t32 = c{self::Class} in #t32.{core::Object::==}(null) ?{self::Class?} null : #t32.{self::Class::method}().{self::Class::field};
-  let final self::Class #t33 = c{self::Class} in #t33.{core::Object::==}(null) ?{self::Class} null : #t33.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : #t34.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : #t35.{self::Class::property}.{self::Class::property}.{self::Class::field};
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class} null : #t36.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class} null : #t37.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t38 = c{self::Class} in #t38.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t39 = #t38.{self::Class::property}.{self::Class::field} in #t39.{core::Object::==}(null) ?{self::Class} null : #t39{self::Class}.{self::Class::method}();
-  let final self::Class #t40 = c{self::Class} in #t40.{core::Object::==}(null) ?{self::Class?} null : #t40.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  c = let final self::Class #t41 = c{self::Class} in #t41.{core::Object::==}(null) ?{self::Class?} null : #t41.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : #t42{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : #t43{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t44 = c{self::Class} in #t44.{core::Object::==}(null) ?{self::Class} null : #t44.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  c = let final self::Class #t45 = c{self::Class} in #t45.{core::Object::==}(null) ?{self::Class} null : #t45.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t46 = c{self::Class} in #t46.{core::Object::==}(null) ?{self::Class?} null : #t46.{self::Class::method}().{self::Class::property}.{self::Class::field};
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : #t47.{self::Class::method}().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : #t48.{self::Class::method}().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class?} null : #t49.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t50 = c{self::Class} in #t50.{core::Object::==}(null) ?{self::Class?} null : #t50.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t51 = c in #t51.{core::Object::==}(null) ?{self::Class} null : #t51{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t52 = c in #t52.{core::Object::==}(null) ?{self::Class} null : #t52{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : #t53.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : #t54.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : #t55.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class?} null : #t56.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t57 = c in #t57.{core::Object::==}(null) ?{self::Class} null : #t57{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t58 = c in #t58.{core::Object::==}(null) ?{self::Class} null : #t58{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : #t59.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : #t60.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : #t61.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : #t62.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t63 = c in #t63.{core::Object::==}(null) ?{self::Class} null : #t63{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : #t64{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t65 = c{self::Class} in #t65.{core::Object::==}(null) ?{self::Class} null : #t65.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t66 = c{self::Class} in #t66.{core::Object::==}(null) ?{self::Class} null : #t66.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t67 = c{self::Class} in #t67.{core::Object::==}(null) ?{self::Class?} null : #t67.{self::Class::property}.{self::Class::method}().{self::Class::field};
-  let final self::Class #t68 = c{self::Class} in #t68.{core::Object::==}(null) ?{self::Class} null : #t68.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t69 = c{self::Class} in #t69.{core::Object::==}(null) ?{self::Class} null : #t69.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t70 = c{self::Class} in #t70.{core::Object::==}(null) ?{self::Class} null : #t70.{self::Class::property}.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t71 = c{self::Class} in #t71.{core::Object::==}(null) ?{self::Class?} null : #t71.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  c = let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class?} null : #t72.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  let final self::Class? #t73 = c in #t73.{core::Object::==}(null) ?{self::Class} null : #t73{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t74 = c in #t74.{core::Object::==}(null) ?{self::Class} null : #t74{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t75 = c{self::Class} in #t75.{core::Object::==}(null) ?{self::Class} null : #t75.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  c = let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class} null : #t76.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : #t77.{self::Class::method}().{self::Class::method}().{self::Class::field};
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : #t78.{self::Class::method}().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : #t79.{self::Class::method}().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t81 = #t80.{self::Class::method}() in #t81.{core::Object::==}(null) ?{self::Class} null : #t81.{self::Class::method}();
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : #t1{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : #t2{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : #t3{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t4 = n1 in #t4.{core::Object::==}(null) ?{self::Class1?} null : #t4{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t5 = n1 in #t5.{core::Object::==}(null) ?{self::Class1?} null : #t5{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t7 = #t6{self::Class1}.{self::Class1::nullable1} in #t7.{core::Object::==}(null) ?{self::Class1?} null : #t7{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = #t8{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t9.{core::Object::==}(null) ?{self::Class1?} null : #t9{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : #t10{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t11 = n1 in #t11.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t12 = #t11{self::Class1}.{self::Class1::nullable1} in #t12.{core::Object::==}(null) ?{self::Class1?} null : #t12{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = #t13{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t14.{core::Object::==}(null) ?{self::Class1?} null : #t14{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t15 = let final self::Class1? #t16 = n1 in #t16.{core::Object::==}(null) ?{self::Class1?} null : #t16{self::Class1}.{self::Class1::nullable1} in #t15.{core::Object::==}(null) ?{self::Class1?} null : #t15{self::Class1}.{self::Class1::nullable1};
+  self::throws(() → self::Class1? => let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+                                              ^^^^^^^^^" in (let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : #t18{self::Class1}.{self::Class1::nullable1} = new self::Class1::•()).{self::Class1::nullable1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+                                          ^^^^^^^^^" in (let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : #t20{self::Class1}.{self::Class1::nonNullable1Method}()).{self::Class1::nullable1});
+  nullable1 = let final self::Class1? #t21 = n1 in #t21.{core::Object::==}(null) ?{self::Class1?} null : #t21{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t23 = #t22{self::Class1}.{self::Class1::nullable1} in #t23.{core::Object::==}(null) ?{self::Class1?} null : #t23{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t25 = #t24{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t25.{core::Object::==}(null) ?{self::Class1?} null : #t25{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = #t26{self::Class1}.{self::Class1::nullable1} in #t27.{core::Object::==}(null) ?{self::Class1?} null : #t27{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : #t28{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t29 = n1 in #t29.{core::Object::==}(null) ?{self::Class1?} null : #t29{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : #t30{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t31 = n1 in #t31.{core::Object::==}(null) ?{self::Class1?} null : #t31{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : #t32{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t33 = n1 in #t33.{core::Object::==}(null) ?{self::Class1?} null : #t33{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : #t34{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t35 = n1 in #t35.{core::Object::==}(null) ?{self::Class1?} null : #t35{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : #t36{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : #t37{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : #t38{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : #t39{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t41 = #t40{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t41.{core::Object::==}(null) ?{self::Class1?} null : #t41{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : #t42{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : #t43{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t44 = n1 in #t44.{core::Object::==}(null) ?{self::Class1?} null : #t44{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : #t45{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t46 = n1 in #t46.{core::Object::==}(null) ?{self::Class1?} null : #t46{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t47 = n1 in #t47.{core::Object::==}(null) ?{self::Class1?} null : #t47{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : #t48{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : #t49{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : #t50{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : #t51{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : #t52{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : #t53{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : #t54{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : #t55{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : #t56{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : #t57{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : #t58{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : #t59{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : #t60{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t61 = n1 in #t61.{core::Object::==}(null) ?{self::Class1?} null : #t61{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : #t62{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : #t63{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : #t64{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : #t65{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : #t66{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t67 = n1 in #t67.{core::Object::==}(null) ?{self::Class1?} null : #t67{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : #t68{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : #t69{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t70 = n1 in #t70.{core::Object::==}(null) ?{self::Class1?} null : #t70{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : #t71{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t72 = n1 in #t72.{core::Object::==}(null) ?{self::Class1?} null : #t72{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t73 = n1 in #t73.{core::Object::==}(null) ?{self::Class1?} null : #t73{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : #t74{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : #t75{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : #t76{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : #t77{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : #t78{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : #t79{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : #t80{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : #t81{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = #t82{self::Class1}.{self::Class1::nonNullable1Method}() in #t83.{core::Object::==}(null) ?{self::Class1?} null : #t83{self::Class1}.{self::Class1::nonNullable1Method}();
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t82 = c in #t82.{core::Object::==}(null) ?{self::Class?} null : #t82{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : #t83{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  let final self::Class? #t84 = c in #t84.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t85 = #t84{self::Class}.{self::Class::[]}(c{self::Class}) in #t85.{core::Object::==}(null) ?{self::Class} null : #t85{self::Class}.{self::Class::method}();
-  let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class?} null : #t86{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t87 = c in #t87.{core::Object::==}(null) ?{self::Class} null : #t87{self::Class}.{self::Class::field}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t89 = #t88{self::Class}.{self::Class::field} in let final self::Class #t90 = c{self::Class} in let final self::Class #t91 = new self::Class::•() in let final void #t92 = #t89.{self::Class::[]=}(#t90, #t91) in #t91;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t94 = #t93.{self::Class::field}.{self::Class::[]}(c{self::Class}) in #t94.{core::Object::==}(null) ?{self::Class} null : #t94{self::Class}.{self::Class::method}();
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t96 = #t95.{self::Class::field} in let final self::Class #t97 = c{self::Class} in #t96.{self::Class::[]=}(#t97, #t96.{self::Class::[]}(#t97).{self::Class::+}(0));
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = #t98.{self::Class::field} in let final self::Class #t100 = c{self::Class} in let final self::Class? #t101 = #t99.{self::Class::[]}(#t100).{self::Class::+}(0) in let final void #t102 = #t99.{self::Class::[]=}(#t100, #t101) in #t101;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t104 = c{self::Class} in #t103{self::Class}.{self::Class::[]}(#t104).{core::Object::==}(null) ?{self::Class} #t103{self::Class}.{self::Class::[]=}(#t104, c{self::Class}) : null;
-  c = let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t106 = c{self::Class} in let final self::Class? #t107 = #t105{self::Class}.{self::Class::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class} let final self::Class #t108 = c{self::Class} in let final void #t109 = #t105{self::Class}.{self::Class::[]=}(#t106, #t108) in #t108 : #t107{self::Class};
-  let final self::Class #t110 = c{self::Class} in #t110.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t111 = c{self::Class} in #t110.{self::Class::[]=}(#t111, #t110.{self::Class::[]}(#t111).{self::Class::+}(0));
-  c = let final self::Class #t112 = c{self::Class} in #t112.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t113 = c{self::Class} in let final self::Class? #t114 = #t112.{self::Class::[]}(#t113).{self::Class::+}(0) in let final void #t115 = #t112.{self::Class::[]=}(#t113, #t114) in #t114;
-  let final self::Class? #t116 = c in #t116.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t117 = c{self::Class} in #t116{self::Class}.{self::Class::[]=}(#t117, #t116{self::Class}.{self::Class::[]}(#t117).{self::Class::+}(0));
-  c = let final self::Class? #t118 = c in #t118.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t119 = c{self::Class} in let final self::Class? #t120 = #t118{self::Class}.{self::Class::[]}(#t119).{self::Class::+}(0) in let final void #t121 = #t118{self::Class}.{self::Class::[]=}(#t119, #t120) in #t120;
-  let final self::Class? #t122 = c in #t122.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t123 = c{self::Class} in #t122{self::Class}.{self::Class::[]=}(#t123, #t122{self::Class}.{self::Class::[]}(#t123).{self::Class::+}(1));
-  c = let final self::Class? #t124 = c in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t125 = c{self::Class} in let final self::Class? #t126 = #t124{self::Class}.{self::Class::[]}(#t125) in let final void #t127 = #t124{self::Class}.{self::Class::[]=}(#t125, #t126.{self::Class::+}(1)) in #t126;
-  let final self::Class? #t128 = c in #t128.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t129 = c{self::Class} in let final self::Class? #t130 = #t128{self::Class}.{self::Class::[]}(#t129).{self::Class::+}(1) in let final void #t131 = #t128{self::Class}.{self::Class::[]=}(#t129, #t130) in #t130;
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t133 = c{self::Class} in let final self::Class? #t134 = #t132{self::Class}.{self::Class::[]}(#t133).{self::Class::+}(1) in let final void #t135 = #t132{self::Class}.{self::Class::[]=}(#t133, #t134) in #t134;
-  let final self::Class? #t136 = c in #t136.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t137 = #t136{self::Class}.{self::Class::field} in let final self::Class #t138 = c{self::Class} in #t137.{self::Class::[]=}(#t138, #t137.{self::Class::[]}(#t138).{self::Class::+}(1));
-  c = let final self::Class? #t139 = c in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = #t139{self::Class}.{self::Class::field} in let final self::Class #t141 = c{self::Class} in let final self::Class? #t142 = #t140.{self::Class::[]}(#t141) in let final void #t143 = #t140.{self::Class::[]=}(#t141, #t142.{self::Class::+}(1)) in #t142;
-  let final self::Class? #t144 = c in #t144.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t145 = #t144{self::Class}.{self::Class::field} in let final self::Class #t146 = c{self::Class} in let final self::Class? #t147 = #t145.{self::Class::[]}(#t146).{self::Class::+}(1) in let final void #t148 = #t145.{self::Class::[]=}(#t146, #t147) in #t147;
-  c = let final self::Class? #t149 = c in #t149.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t150 = #t149{self::Class}.{self::Class::field} in let final self::Class #t151 = c{self::Class} in let final self::Class? #t152 = #t150.{self::Class::[]}(#t151).{self::Class::+}(1) in let final void #t153 = #t150.{self::Class::[]=}(#t151, #t152) in #t152;
-  let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class?} null : #t154{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class});
-  let final self::Class? #t155 = c in #t155.{core::Object::==}(null) ?{self::Class} null : #t155{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t157 = #t156{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t158 = c{self::Class} in let final self::Class #t159 = new self::Class::•() in let final void #t160 = #t157.{self::Class::[]=}(#t158, #t159) in #t159;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t162 = #t161.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class}) in #t162.{core::Object::==}(null) ?{self::Class} null : #t162{self::Class}.{self::Class::method}();
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t164 = #t163.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t165 = c{self::Class} in #t164.{self::Class::[]=}(#t165, #t164.{self::Class::[]}(#t165).{self::Class::+}(0));
-  c = let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t167 = #t166.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t168 = c{self::Class} in let final self::Class? #t169 = #t167.{self::Class::[]}(#t168).{self::Class::+}(0) in let final void #t170 = #t167.{self::Class::[]=}(#t168, #t169) in #t169;
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t172 = #t171{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t173 = c{self::Class} in #t172.{self::Class::[]=}(#t173, #t172.{self::Class::[]}(#t173).{self::Class::+}(1));
-  c = let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t175 = #t174{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t176 = c{self::Class} in let final self::Class? #t177 = #t175.{self::Class::[]}(#t176) in let final void #t178 = #t175.{self::Class::[]=}(#t176, #t177.{self::Class::+}(1)) in #t177;
-  let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t180 = #t179{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class? #t182 = #t180.{self::Class::[]}(#t181).{self::Class::+}(1) in let final void #t183 = #t180.{self::Class::[]=}(#t181, #t182) in #t182;
-  c = let final self::Class? #t184 = c in #t184.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t185 = #t184{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t186 = c{self::Class} in let final self::Class? #t187 = #t185.{self::Class::[]}(#t186).{self::Class::+}(1) in let final void #t188 = #t185.{self::Class::[]=}(#t186, #t187) in #t187;
-  let final self::Class? #t189 = c in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = #t189{self::Class}.{self::Class::[]}(c{self::Class}) in #t190.{core::Object::==}(null) ?{self::Class?} null : #t190{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t192 = #t191{self::Class}.{self::Class::[]}(c{self::Class}) in #t192.{core::Object::==}(null) ?{self::Class} null : #t192{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t194 = #t193{self::Class}.{self::Class::[]}(c{self::Class}) in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in let final self::Class #t196 = new self::Class::•() in let final void #t197 = #t194{self::Class}.{self::Class::[]=}(#t195, #t196) in #t196;
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t199 = #t198.{self::Class::[]}(c{self::Class}) in #t199.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t200 = #t199{self::Class}.{self::Class::[]}(c{self::Class}) in #t200.{core::Object::==}(null) ?{self::Class} null : #t200{self::Class}.{self::Class::method}();
-  c = let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t202 = #t201.{self::Class::[]}(c{self::Class}) in #t202.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t203 = #t202{self::Class}.{self::Class::[]}(c{self::Class}) in #t203.{core::Object::==}(null) ?{self::Class} null : #t203{self::Class}.{self::Class::method}();
-  let final self::Class #t204 = c{self::Class} in #t204.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t205 = #t204.{self::Class::[]}(c{self::Class}) in #t205.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t206 = c{self::Class} in #t205{self::Class}.{self::Class::[]}(#t206).{core::Object::==}(null) ?{self::Class} #t205{self::Class}.{self::Class::[]=}(#t206, c{self::Class}) : null;
-  c = let final self::Class #t207 = c{self::Class} in #t207.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t208 = #t207.{self::Class::[]}(c{self::Class}) in #t208.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t209 = c{self::Class} in let final self::Class? #t210 = #t208{self::Class}.{self::Class::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class} let final self::Class #t211 = c{self::Class} in let final void #t212 = #t208{self::Class}.{self::Class::[]=}(#t209, #t211) in #t211 : #t210{self::Class};
-  let final self::Class #t213 = c{self::Class} in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t214 = #t213.{self::Class::[]}(c{self::Class}) in #t214.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t215 = c{self::Class} in #t214{self::Class}.{self::Class::[]=}(#t215, #t214{self::Class}.{self::Class::[]}(#t215).{self::Class::+}(0));
-  c = let final self::Class #t216 = c{self::Class} in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t217 = #t216.{self::Class::[]}(c{self::Class}) in #t217.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t218 = c{self::Class} in let final self::Class? #t219 = #t217{self::Class}.{self::Class::[]}(#t218).{self::Class::+}(0) in let final void #t220 = #t217{self::Class}.{self::Class::[]=}(#t218, #t219) in #t219;
-  let final self::Class? #t221 = c in #t221.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t222 = #t221{self::Class}.{self::Class::[]}(c{self::Class}) in #t222.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t223 = c{self::Class} in #t222{self::Class}.{self::Class::[]=}(#t223, #t222{self::Class}.{self::Class::[]}(#t223).{self::Class::+}(1));
-  c = let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = #t224{self::Class}.{self::Class::[]}(c{self::Class}) in #t225.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t226 = c{self::Class} in let final self::Class? #t227 = #t225{self::Class}.{self::Class::[]}(#t226) in let final void #t228 = #t225{self::Class}.{self::Class::[]=}(#t226, #t227.{self::Class::+}(1)) in #t227;
-  let final self::Class? #t229 = c in #t229.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t230 = #t229{self::Class}.{self::Class::[]}(c{self::Class}) in #t230.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t231 = c{self::Class} in let final self::Class? #t232 = #t230{self::Class}.{self::Class::[]}(#t231).{self::Class::+}(1) in let final void #t233 = #t230{self::Class}.{self::Class::[]=}(#t231, #t232) in #t232;
-  c = let final self::Class? #t234 = c in #t234.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t235 = #t234{self::Class}.{self::Class::[]}(c{self::Class}) in #t235.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t236 = c{self::Class} in let final self::Class? #t237 = #t235{self::Class}.{self::Class::[]}(#t236).{self::Class::+}(1) in let final void #t238 = #t235{self::Class}.{self::Class::[]=}(#t236, #t237) in #t237;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : #t84{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : #t85{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  let final self::Class1? #t86 = n1 in #t86.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t87 = #t86{self::Class1}.{self::Class1::[]}(nullable1) in #t87.{core::Object::==}(null) ?{self::Class1?} null : #t87{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : #t88{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t89 = n1 in #t89.{core::Object::==}(null) ?{self::Class1?} null : #t89{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = #t90{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t92 = nullable1 in let final self::Class1 #t93 = new self::Class1::•() in let final void #t94 = #t91.{self::Class1::[]=}(#t92, #t93) in #t93;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t96 = #t95{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1) in #t96.{core::Object::==}(null) ?{self::Class1?} null : #t96{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t98 = #t97{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t99 = nullable2 in #t98.{self::Class2::[]=}(#t99, #t98.{self::Class2::[]}(#t99).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t101 = #t100{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t102 = nullable2 in let final self::Class2 #t103 = #t101.{self::Class2::[]}(#t102).{self::Class2::+}(0) in let final void #t104 = #t101.{self::Class2::[]=}(#t102, #t103) in #t103;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t106 = nullable1 in #t105{self::Class1}.{self::Class1::[]}(#t106).{core::Object::==}(null) ?{self::Class1?} #t105{self::Class1}.{self::Class1::[]=}(#t106, nullable1) : null;
+  nullable1 = let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t108 = nullable1 in let final self::Class1? #t109 = #t107{self::Class1}.{self::Class1::[]}(#t108) in #t109.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t110 = nullable1 in let final void #t111 = #t107{self::Class1}.{self::Class1::[]=}(#t108, #t110) in #t110 : #t109{self::Class1};
+  let final self::Class2? #t112 = n2 in #t112.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t113 = nullable2 in #t112{self::Class2}.{self::Class2::[]=}(#t113, #t112{self::Class2}.{self::Class2::[]}(#t113).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t114 = n2 in #t114.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t115 = nullable2 in let final self::Class2 #t116 = #t114{self::Class2}.{self::Class2::[]}(#t115).{self::Class2::+}(0) in let final void #t117 = #t114{self::Class2}.{self::Class2::[]=}(#t115, #t116) in #t116;
+  let final self::Class2? #t118 = n2 in #t118.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t119 = nullable2 in #t118{self::Class2}.{self::Class2::[]=}(#t119, #t118{self::Class2}.{self::Class2::[]}(#t119).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t120 = n2 in #t120.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t121 = nullable2 in let final self::Class2 #t122 = #t120{self::Class2}.{self::Class2::[]}(#t121).{self::Class2::+}(0) in let final void #t123 = #t120{self::Class2}.{self::Class2::[]=}(#t121, #t122) in #t122;
+  let final self::Class2? #t124 = n2 in #t124.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t125 = nullable2 in #t124{self::Class2}.{self::Class2::[]=}(#t125, #t124{self::Class2}.{self::Class2::[]}(#t125).{self::Class2::+}(1));
+  nullable2 = let final self::Class2? #t126 = n2 in #t126.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t127 = nullable2 in let final self::Class2 #t128 = #t126{self::Class2}.{self::Class2::[]}(#t127) in let final void #t129 = #t126{self::Class2}.{self::Class2::[]=}(#t127, #t128.{self::Class2::+}(1)) in #t128;
+  let final self::Class2? #t130 = n2 in #t130.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t131 = nullable2 in let final self::Class2 #t132 = #t130{self::Class2}.{self::Class2::[]}(#t131).{self::Class2::+}(1) in let final void #t133 = #t130{self::Class2}.{self::Class2::[]=}(#t131, #t132) in #t132;
+  nullable2 = let final self::Class2? #t134 = n2 in #t134.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t135 = nullable2 in let final self::Class2 #t136 = #t134{self::Class2}.{self::Class2::[]}(#t135).{self::Class2::+}(1) in let final void #t137 = #t134{self::Class2}.{self::Class2::[]=}(#t135, #t136) in #t136;
+  let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t139 = #t138{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t140 = nullable2 in #t139.{self::Class2::[]=}(#t140, #t139.{self::Class2::[]}(#t140).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t142 = #t141{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t143 = nullable2 in let final self::Class2 #t144 = #t142.{self::Class2::[]}(#t143) in let final void #t145 = #t142.{self::Class2::[]=}(#t143, #t144.{self::Class2::+}(1)) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t147 = #t146{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t148 = nullable2 in let final self::Class2 #t149 = #t147.{self::Class2::[]}(#t148).{self::Class2::+}(1) in let final void #t150 = #t147.{self::Class2::[]=}(#t148, #t149) in #t149;
+  nullable2 = let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t152 = #t151{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t153 = nullable2 in let final self::Class2 #t154 = #t152.{self::Class2::[]}(#t153).{self::Class2::+}(1) in let final void #t155 = #t152.{self::Class2::[]=}(#t153, #t154) in #t154;
+  let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class2?} null : #t156{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2);
+  let final self::Class1? #t157 = n1 in #t157.{core::Object::==}(null) ?{self::Class2?} null : #t157{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]=}(nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t158 = n1 in #t158.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t159 = #t158{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t160 = nullable2 in let final self::Class2 #t161 = new self::Class2::•() in let final void #t162 = #t159.{self::Class2::[]=}(#t160, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t164 = #t163{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2) in #t164.{core::Object::==}(null) ?{self::Class2?} null : #t164{self::Class2}.{self::Class2::nonNullable2Method}();
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t166 = #t165{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t167 = nullable2 in #t166.{self::Class2::[]=}(#t167, #t166.{self::Class2::[]}(#t167).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t169 = #t168{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t170 = nullable2 in let final self::Class2 #t171 = #t169.{self::Class2::[]}(#t170).{self::Class2::+}(0) in let final void #t172 = #t169.{self::Class2::[]=}(#t170, #t171) in #t171;
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t174 = #t173{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t175 = nullable2 in #t174.{self::Class2::[]=}(#t175, #t174.{self::Class2::[]}(#t175).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t177 = #t176{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t178 = nullable2 in let final self::Class2 #t179 = #t177.{self::Class2::[]}(#t178) in let final void #t180 = #t177.{self::Class2::[]=}(#t178, #t179.{self::Class2::+}(1)) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = #t181{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t183 = nullable2 in let final self::Class2 #t184 = #t182.{self::Class2::[]}(#t183).{self::Class2::+}(1) in let final void #t185 = #t182.{self::Class2::[]=}(#t183, #t184) in #t184;
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = #t186{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = #t187.{self::Class2::[]}(#t188).{self::Class2::+}(1) in let final void #t190 = #t187.{self::Class2::[]=}(#t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = #t191{self::Class1}.{self::Class1::[]}(nullable1) in #t192.{core::Object::==}(null) ?{self::Class1?} null : #t192{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = #t193{self::Class1}.{self::Class1::[]}(nullable1) in #t194.{core::Object::==}(null) ?{self::Class1?} null : #t194{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t195 = n1 in #t195.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t196 = #t195{self::Class1}.{self::Class1::[]}(nullable1) in #t196.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t197 = nullable1 in let final self::Class1 #t198 = new self::Class1::•() in let final void #t199 = #t196{self::Class1}.{self::Class1::[]=}(#t197, #t198) in #t198;
+  let final self::Class1? #t200 = n1 in #t200.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t201 = #t200{self::Class1}.{self::Class1::[]}(nullable1) in #t201.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t202 = #t201{self::Class1}.{self::Class1::[]}(nullable1) in #t202.{core::Object::==}(null) ?{self::Class1?} null : #t202{self::Class1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t203 = n1 in #t203.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t204 = #t203{self::Class1}.{self::Class1::[]}(nullable1) in #t204.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t205 = #t204{self::Class1}.{self::Class1::[]}(nullable1) in #t205.{core::Object::==}(null) ?{self::Class1?} null : #t205{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t206 = n1 in #t206.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t207 = #t206{self::Class1}.{self::Class1::[]}(nullable1) in #t207.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t208 = nullable1 in #t207{self::Class1}.{self::Class1::[]}(#t208).{core::Object::==}(null) ?{self::Class1?} #t207{self::Class1}.{self::Class1::[]=}(#t208, nullable1) : null;
+  nullable1 = let final self::Class1? #t209 = n1 in #t209.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t210 = #t209{self::Class1}.{self::Class1::[]}(nullable1) in #t210.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t211 = nullable1 in let final self::Class1? #t212 = #t210{self::Class1}.{self::Class1::[]}(#t211) in #t212.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t213 = nullable1 in let final void #t214 = #t210{self::Class1}.{self::Class1::[]=}(#t211, #t213) in #t213 : #t212{self::Class1};
+  let final self::Class3? #t215 = n3 in #t215.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t216 = #t215{self::Class3}.{self::Class3::[]}(nullable3) in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in #t216{self::Class2}.{self::Class2::[]=}(#t217, #t216{self::Class2}.{self::Class2::[]}(#t217).{self::Class2::+}(0));
+  nullable2 = let final self::Class3? #t218 = n3 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = #t218{self::Class3}.{self::Class3::[]}(nullable3) in #t219.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t220 = nullable2 in let final self::Class2 #t221 = #t219{self::Class2}.{self::Class2::[]}(#t220).{self::Class2::+}(0) in let final void #t222 = #t219{self::Class2}.{self::Class2::[]=}(#t220, #t221) in #t221;
+  let final self::Class3? #t223 = n3 in #t223.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t224 = #t223{self::Class3}.{self::Class3::[]}(nullable3) in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t225 = nullable2 in #t224{self::Class2}.{self::Class2::[]=}(#t225, #t224{self::Class2}.{self::Class2::[]}(#t225).{self::Class2::+}(1));
+  nullable2 = let final self::Class3? #t226 = n3 in #t226.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t227 = #t226{self::Class3}.{self::Class3::[]}(nullable3) in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t228 = nullable2 in let final self::Class2 #t229 = #t227{self::Class2}.{self::Class2::[]}(#t228) in let final void #t230 = #t227{self::Class2}.{self::Class2::[]=}(#t228, #t229.{self::Class2::+}(1)) in #t229;
+  let final self::Class3? #t231 = n3 in #t231.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t232 = #t231{self::Class3}.{self::Class3::[]}(nullable3) in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t233 = nullable2 in let final self::Class2 #t234 = #t232{self::Class2}.{self::Class2::[]}(#t233).{self::Class2::+}(1) in let final void #t235 = #t232{self::Class2}.{self::Class2::[]=}(#t233, #t234) in #t234;
+  nullable2 = let final self::Class3? #t236 = n3 in #t236.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t237 = #t236{self::Class3}.{self::Class3::[]}(nullable3) in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t238 = nullable2 in let final self::Class2 #t239 = #t237{self::Class2}.{self::Class2::[]}(#t238).{self::Class2::+}(1) in let final void #t240 = #t237{self::Class2}.{self::Class2::[]=}(#t238, #t239) in #t239;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => (let final self::Class? #t239 = c in #t239.{core::Object::==}(null) ?{self::Class?} null : #t239{self::Class}.{self::Class::field}).{self::Class::+}(0));
-  self::throws(() → self::Class? => (let final self::Class? #t240 = c in #t240.{core::Object::==}(null) ?{self::Class?} null : #t240{self::Class}.{self::Class::field}).{self::Class::unary-}());
-  let final self::Class? #t241 = c in #t241.{core::Object::==}(null) ?{self::Class?} null : #t241.{self::Class::field} = #t241.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t243 = #t242.{self::Class::field}.{self::Class::+}(0) in let final void #t244 = #t242.{self::Class::field} = #t243 in #t243;
-  let final self::Class? #t245 = c in #t245.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t246 = #t245{self::Class}.{self::Class::property} in #t246.{self::Class::field} = #t246.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t247 = c in #t247.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t248 = #t247{self::Class}.{self::Class::property} in #t248.{self::Class::field} = #t248.{self::Class::field}.{self::Class::+}(0);
-  let final self::Class? #t249 = c in #t249.{core::Object::==}(null) ?{self::Class?} null : #t249.{self::Class::field} = #t249.{self::Class::field}.{self::Class::+}(1);
-  c = let final self::Class? #t250 = c in #t250.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t251 = #t250.{self::Class::field} in let final void #t252 = #t250.{self::Class::field} = #t251.{self::Class::+}(1) in #t251;
-  let final self::Class? #t253 = c in #t253.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t254 = #t253.{self::Class::field}.{self::Class::+}(1) in let final void #t255 = #t253.{self::Class::field} = #t254 in #t254;
-  c = let final self::Class? #t256 = c in #t256.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t257 = #t256.{self::Class::field}.{self::Class::+}(1) in let final void #t258 = #t256.{self::Class::field} = #t257 in #t257;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t241 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+  throws(() => n1?.nonNullable1 + 0);
+                                ^" in (let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class1?} null : #t242{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::+}(0));
+  self::throws(() → self::Class1? => let final<BottomType> #t243 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+  throws(() => -n1?.nonNullable1);
+               ^" in (let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class1?} null : #t244{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::unary-}());
+  let final self::Class2? #t245 = n2 in #t245.{core::Object::==}(null) ?{self::Class2?} null : #t245.{self::Class2::nonNullable2} = #t245.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t246 = n2 in #t246.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t247 = #t246.{self::Class2::nonNullable2}.{self::Class2::+}(0) in let final void #t248 = #t246.{self::Class2::nonNullable2} = #t247 in #t247;
+  let final self::Class2? #t249 = n2 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = #t249{self::Class2}.{self::Class2::nonNullable2} in #t250.{self::Class2::nonNullable2} = #t250.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t251 = n2 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = #t251{self::Class2}.{self::Class2::nonNullable2} in #t252.{self::Class2::nonNullable2} = #t252.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  let final self::Class2? #t253 = n2 in #t253.{core::Object::==}(null) ?{self::Class2?} null : #t253.{self::Class2::nonNullable2} = #t253.{self::Class2::nonNullable2}.{self::Class2::+}(1);
+  nullable2 = let final self::Class2? #t254 = n2 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = #t254.{self::Class2::nonNullable2} in let final void #t256 = #t254.{self::Class2::nonNullable2} = #t255.{self::Class2::+}(1) in #t255;
+  let final self::Class2? #t257 = n2 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = #t257.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t259 = #t257.{self::Class2::nonNullable2} = #t258 in #t258;
+  nullable2 = let final self::Class2? #t260 = n2 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = #t260.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t262 = #t260.{self::Class2::nonNullable2} = #t261 in #t261;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class} null : #t259.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t259.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class? #t260 = c in #t260.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t261 = #t260.{self::Class::field} in #t261.{core::Object::==}(null) ?{self::Class} #t260.{self::Class::field} = c{self::Class} : #t261{self::Class};
-  let final self::Class #t262 = c{self::Class} in #t262.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t263 = #t262.{self::Class::property} in #t263.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t263.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class #t264 = c{self::Class} in #t264.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t265 = #t264.{self::Class::property} in let final self::Class? #t266 = #t265.{self::Class::field} in #t266.{core::Object::==}(null) ?{self::Class} #t265.{self::Class::field} = c{self::Class} : #t266{self::Class};
-  let final self::Class #t267 = c{self::Class} in #t267.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t268 = #t267.{self::Class::field} in let final self::Class #t269 = c{self::Class} in #t268.{self::Class::[]}(#t269).{core::Object::==}(null) ?{self::Class} #t268.{self::Class::[]=}(#t269, c{self::Class}) : null;
-  c = let final self::Class #t270 = c{self::Class} in #t270.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t271 = #t270.{self::Class::field} in let final self::Class #t272 = c{self::Class} in let final self::Class? #t273 = #t271.{self::Class::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class} let final self::Class #t274 = c{self::Class} in let final void #t275 = #t271.{self::Class::[]=}(#t272, #t274) in #t274 : #t273{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t263 = n1 in #t263.{core::Object::==}(null) ?{self::Class1?} null : #t263.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t263.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t264 = n1 in #t264.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t265 = #t264.{self::Class1::nullable1} in #t265.{core::Object::==}(null) ?{self::Class1} #t264.{self::Class1::nullable1} = n1{self::Class1} : #t265{self::Class1};
+  let final self::Class1? #t266 = n1 in #t266.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t267 = #t266{self::Class1}.{self::Class1::nonNullable1} in #t267{self::Class1}.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t267{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t268 = n1 in #t268.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t269 = #t268{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t270 = #t269{self::Class1}.{self::Class1::nullable1} in #t270.{core::Object::==}(null) ?{self::Class1} #t269{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : #t270{self::Class1};
+  let final self::Class1? #t271 = n1 in #t271.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t272 = #t271{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t273 = n1{self::Class1} in #t272.{self::Class1::[]}(#t273).{core::Object::==}(null) ?{self::Class1} #t272.{self::Class1::[]=}(#t273, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t274 = n1 in #t274.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t275 = #t274{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t276 = n1{self::Class1} in let final self::Class1? #t277 = #t275.{self::Class1::[]}(#t276) in #t277.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t278 = n1{self::Class1} in let final void #t279 = #t275.{self::Class1::[]=}(#t276, #t278) in #t278 : #t277{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect
index f3fc966..5e1627d 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect
@@ -1,172 +1,262 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
-  method method() → self::Class
-    return this.{self::Class::property};
-  operator [](self::Class? key) → self::Class?
-    return this.{self::Class::field};
-  operator []=(self::Class? key, self::Class? value) → void {
-    this.{self::Class::field} = value;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
+  get nullable1() → self::Class1?
+    return this.{self::Class1::property1};
+  set nullable1(self::Class1? value) → void {
+    this.{self::Class1::property} = value;
   }
-  operator +(core::int value) → self::Class?
-    return this.{self::Class::field};
-  operator unary-() → self::Class?
-    return this.{self::Class::field};
-  get property() → self::Class
+  method nonNullable1Method() → self::Class1
+    return this.{self::Class1::nonNullable1};
+  operator [](self::Class1? key) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator []=(self::Class1? key, self::Class1? value) → void {
+    this.{self::Class1::property} = value;
+  }
+  operator +(core::int value) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator unary-() → self::Class1?
+    return this.{self::Class1::nullable1};
+  get nonNullable1() → self::Class1
+    return this.{self::Class1::property1};
+  get nonNullable2() → self::Class2
+    return this.{self::Class1::property2};
+}
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
     return this;
+  set property(self::Class2 value) → void {}
+  method nonNullable2Method() → self::Class2
+    return this.{self::Class2::nonNullable2};
+  operator [](self::Class2? key) → self::Class2
+    return this.{self::Class2::property};
+  operator []=(self::Class2? key, self::Class2? value) → void
+    return this.{self::Class2::property};
+  operator +(core::int value) → self::Class2
+    return this.{self::Class2::property};
+  operator unary-() → self::Class2
+    return this.{self::Class2::property};
+  get nonNullable2() → self::Class2
+    return this.{self::Class2::property};
+  set nonNullable2(self::Class2 value) → void {
+    this.{self::Class2::property} = value;
+  }
+}
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
+  operator [](self::Class3? key) → self::Class2?
+    return this.{self::Class3::property};
 }
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : #t1{self::Class}.{self::Class::field};
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : #t2{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t4 = c{self::Class} in #t4.{core::Object::==}(null) ?{self::Class} null : #t4.{self::Class::method}();
-  let final self::Class #t5 = c{self::Class} in #t5.{core::Object::==}(null) ?{self::Class?} null : #t5.{self::Class::property}.{self::Class::field};
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t7 = #t6.{self::Class::field} in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::field};
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = #t8.{self::Class::property}.{self::Class::field} in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::field};
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class} null : #t10.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t11 = c{self::Class} in #t11.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t12 = #t11.{self::Class::field} in #t12.{core::Object::==}(null) ?{self::Class} null : #t12{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = #t13.{self::Class::property}.{self::Class::field} in #t14.{core::Object::==}(null) ?{self::Class} null : #t14{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class? #t15 = let final self::Class #t16 = c{self::Class} in #t16.{core::Object::==}(null) ?{self::Class?} null : #t16.{self::Class::field} in #t15.{core::Object::==}(null) ?{self::Class?} null : #t15{self::Class}.{self::Class::field};
-  self::throws(() → self::Class? => (let final self::Class? #t17 = c in #t17.{core::Object::==}(null) ?{self::Class} null : #t17{self::Class}.{self::Class::field} = new self::Class::•()).{self::Class::field});
-  self::throws(() → self::Class? => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{self::Class} null : #t18{self::Class}.{self::Class::method}()).{self::Class::field});
-  c = let final self::Class #t19 = c{self::Class} in #t19.{core::Object::==}(null) ?{self::Class} null : #t19.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t20 = c{self::Class} in #t20.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t21 = #t20.{self::Class::field} in #t21.{core::Object::==}(null) ?{self::Class} null : #t21{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t22 = c{self::Class} in #t22.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t23 = #t22.{self::Class::property}.{self::Class::field} in #t23.{core::Object::==}(null) ?{self::Class} null : #t23{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t24 = c{self::Class} in #t24.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t25 = #t24.{self::Class::field} in #t25.{core::Object::==}(null) ?{self::Class} null : #t25{self::Class}.{self::Class::method}();
-  let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class?} null : #t26.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t27 = c{self::Class} in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t28 = c in #t28.{core::Object::==}(null) ?{self::Class} null : #t28{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t29 = c in #t29.{core::Object::==}(null) ?{self::Class} null : #t29{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : #t30.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t31 = c{self::Class} in #t31.{core::Object::==}(null) ?{self::Class} null : #t31.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t32 = c{self::Class} in #t32.{core::Object::==}(null) ?{self::Class?} null : #t32.{self::Class::method}().{self::Class::field};
-  let final self::Class #t33 = c{self::Class} in #t33.{core::Object::==}(null) ?{self::Class} null : #t33.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : #t34.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : #t35.{self::Class::property}.{self::Class::property}.{self::Class::field};
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class} null : #t36.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class} null : #t37.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t38 = c{self::Class} in #t38.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t39 = #t38.{self::Class::property}.{self::Class::field} in #t39.{core::Object::==}(null) ?{self::Class} null : #t39{self::Class}.{self::Class::method}();
-  let final self::Class #t40 = c{self::Class} in #t40.{core::Object::==}(null) ?{self::Class?} null : #t40.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  c = let final self::Class #t41 = c{self::Class} in #t41.{core::Object::==}(null) ?{self::Class?} null : #t41.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : #t42{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : #t43{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t44 = c{self::Class} in #t44.{core::Object::==}(null) ?{self::Class} null : #t44.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  c = let final self::Class #t45 = c{self::Class} in #t45.{core::Object::==}(null) ?{self::Class} null : #t45.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t46 = c{self::Class} in #t46.{core::Object::==}(null) ?{self::Class?} null : #t46.{self::Class::method}().{self::Class::property}.{self::Class::field};
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : #t47.{self::Class::method}().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : #t48.{self::Class::method}().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class?} null : #t49.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t50 = c{self::Class} in #t50.{core::Object::==}(null) ?{self::Class?} null : #t50.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t51 = c in #t51.{core::Object::==}(null) ?{self::Class} null : #t51{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t52 = c in #t52.{core::Object::==}(null) ?{self::Class} null : #t52{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : #t53.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : #t54.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : #t55.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class?} null : #t56.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t57 = c in #t57.{core::Object::==}(null) ?{self::Class} null : #t57{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t58 = c in #t58.{core::Object::==}(null) ?{self::Class} null : #t58{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : #t59.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : #t60.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : #t61.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : #t62.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t63 = c in #t63.{core::Object::==}(null) ?{self::Class} null : #t63{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : #t64{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t65 = c{self::Class} in #t65.{core::Object::==}(null) ?{self::Class} null : #t65.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t66 = c{self::Class} in #t66.{core::Object::==}(null) ?{self::Class} null : #t66.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t67 = c{self::Class} in #t67.{core::Object::==}(null) ?{self::Class?} null : #t67.{self::Class::property}.{self::Class::method}().{self::Class::field};
-  let final self::Class #t68 = c{self::Class} in #t68.{core::Object::==}(null) ?{self::Class} null : #t68.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t69 = c{self::Class} in #t69.{core::Object::==}(null) ?{self::Class} null : #t69.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t70 = c{self::Class} in #t70.{core::Object::==}(null) ?{self::Class} null : #t70.{self::Class::property}.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t71 = c{self::Class} in #t71.{core::Object::==}(null) ?{self::Class?} null : #t71.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  c = let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class?} null : #t72.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  let final self::Class? #t73 = c in #t73.{core::Object::==}(null) ?{self::Class} null : #t73{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t74 = c in #t74.{core::Object::==}(null) ?{self::Class} null : #t74{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t75 = c{self::Class} in #t75.{core::Object::==}(null) ?{self::Class} null : #t75.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  c = let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class} null : #t76.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : #t77.{self::Class::method}().{self::Class::method}().{self::Class::field};
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : #t78.{self::Class::method}().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : #t79.{self::Class::method}().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t81 = #t80.{self::Class::method}() in #t81.{core::Object::==}(null) ?{self::Class} null : #t81.{self::Class::method}();
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : #t1{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : #t2{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : #t3{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t4 = n1 in #t4.{core::Object::==}(null) ?{self::Class1?} null : #t4{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t5 = n1 in #t5.{core::Object::==}(null) ?{self::Class1?} null : #t5{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t7 = #t6{self::Class1}.{self::Class1::nullable1} in #t7.{core::Object::==}(null) ?{self::Class1?} null : #t7{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = #t8{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t9.{core::Object::==}(null) ?{self::Class1?} null : #t9{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : #t10{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t11 = n1 in #t11.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t12 = #t11{self::Class1}.{self::Class1::nullable1} in #t12.{core::Object::==}(null) ?{self::Class1?} null : #t12{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = #t13{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t14.{core::Object::==}(null) ?{self::Class1?} null : #t14{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t15 = let final self::Class1? #t16 = n1 in #t16.{core::Object::==}(null) ?{self::Class1?} null : #t16{self::Class1}.{self::Class1::nullable1} in #t15.{core::Object::==}(null) ?{self::Class1?} null : #t15{self::Class1}.{self::Class1::nullable1};
+  self::throws(() → self::Class1? => let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+                                              ^^^^^^^^^" in (let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : #t18{self::Class1}.{self::Class1::nullable1} = new self::Class1::•()).{self::Class1::nullable1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+                                          ^^^^^^^^^" in (let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : #t20{self::Class1}.{self::Class1::nonNullable1Method}()).{self::Class1::nullable1});
+  nullable1 = let final self::Class1? #t21 = n1 in #t21.{core::Object::==}(null) ?{self::Class1?} null : #t21{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t23 = #t22{self::Class1}.{self::Class1::nullable1} in #t23.{core::Object::==}(null) ?{self::Class1?} null : #t23{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t25 = #t24{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t25.{core::Object::==}(null) ?{self::Class1?} null : #t25{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = #t26{self::Class1}.{self::Class1::nullable1} in #t27.{core::Object::==}(null) ?{self::Class1?} null : #t27{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : #t28{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t29 = n1 in #t29.{core::Object::==}(null) ?{self::Class1?} null : #t29{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : #t30{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t31 = n1 in #t31.{core::Object::==}(null) ?{self::Class1?} null : #t31{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : #t32{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t33 = n1 in #t33.{core::Object::==}(null) ?{self::Class1?} null : #t33{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : #t34{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t35 = n1 in #t35.{core::Object::==}(null) ?{self::Class1?} null : #t35{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : #t36{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : #t37{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : #t38{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : #t39{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t41 = #t40{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t41.{core::Object::==}(null) ?{self::Class1?} null : #t41{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : #t42{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : #t43{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t44 = n1 in #t44.{core::Object::==}(null) ?{self::Class1?} null : #t44{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : #t45{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t46 = n1 in #t46.{core::Object::==}(null) ?{self::Class1?} null : #t46{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t47 = n1 in #t47.{core::Object::==}(null) ?{self::Class1?} null : #t47{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : #t48{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : #t49{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : #t50{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : #t51{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : #t52{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : #t53{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : #t54{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : #t55{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : #t56{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : #t57{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : #t58{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : #t59{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : #t60{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t61 = n1 in #t61.{core::Object::==}(null) ?{self::Class1?} null : #t61{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : #t62{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : #t63{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : #t64{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : #t65{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : #t66{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t67 = n1 in #t67.{core::Object::==}(null) ?{self::Class1?} null : #t67{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : #t68{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : #t69{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t70 = n1 in #t70.{core::Object::==}(null) ?{self::Class1?} null : #t70{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : #t71{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t72 = n1 in #t72.{core::Object::==}(null) ?{self::Class1?} null : #t72{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t73 = n1 in #t73.{core::Object::==}(null) ?{self::Class1?} null : #t73{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : #t74{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : #t75{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : #t76{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : #t77{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : #t78{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : #t79{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : #t80{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : #t81{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = #t82{self::Class1}.{self::Class1::nonNullable1Method}() in #t83.{core::Object::==}(null) ?{self::Class1?} null : #t83{self::Class1}.{self::Class1::nonNullable1Method}();
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t82 = c in #t82.{core::Object::==}(null) ?{self::Class?} null : #t82{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : #t83{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  let final self::Class? #t84 = c in #t84.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t85 = #t84{self::Class}.{self::Class::[]}(c{self::Class}) in #t85.{core::Object::==}(null) ?{self::Class} null : #t85{self::Class}.{self::Class::method}();
-  let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class?} null : #t86{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t87 = c in #t87.{core::Object::==}(null) ?{self::Class} null : #t87{self::Class}.{self::Class::field}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t89 = #t88{self::Class}.{self::Class::field} in let final self::Class #t90 = c{self::Class} in let final self::Class #t91 = new self::Class::•() in let final void #t92 = #t89.{self::Class::[]=}(#t90, #t91) in #t91;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t94 = #t93.{self::Class::field}.{self::Class::[]}(c{self::Class}) in #t94.{core::Object::==}(null) ?{self::Class} null : #t94{self::Class}.{self::Class::method}();
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t96 = #t95.{self::Class::field} in let final self::Class #t97 = c{self::Class} in #t96.{self::Class::[]=}(#t97, #t96.{self::Class::[]}(#t97).{self::Class::+}(0));
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = #t98.{self::Class::field} in let final self::Class #t100 = c{self::Class} in let final self::Class? #t101 = #t99.{self::Class::[]}(#t100).{self::Class::+}(0) in let final void #t102 = #t99.{self::Class::[]=}(#t100, #t101) in #t101;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t104 = c{self::Class} in #t103{self::Class}.{self::Class::[]}(#t104).{core::Object::==}(null) ?{self::Class} #t103{self::Class}.{self::Class::[]=}(#t104, c{self::Class}) : null;
-  c = let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t106 = c{self::Class} in let final self::Class? #t107 = #t105{self::Class}.{self::Class::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class} let final self::Class #t108 = c{self::Class} in let final void #t109 = #t105{self::Class}.{self::Class::[]=}(#t106, #t108) in #t108 : #t107{self::Class};
-  let final self::Class #t110 = c{self::Class} in #t110.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t111 = c{self::Class} in #t110.{self::Class::[]=}(#t111, #t110.{self::Class::[]}(#t111).{self::Class::+}(0));
-  c = let final self::Class #t112 = c{self::Class} in #t112.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t113 = c{self::Class} in let final self::Class? #t114 = #t112.{self::Class::[]}(#t113).{self::Class::+}(0) in let final void #t115 = #t112.{self::Class::[]=}(#t113, #t114) in #t114;
-  let final self::Class? #t116 = c in #t116.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t117 = c{self::Class} in #t116{self::Class}.{self::Class::[]=}(#t117, #t116{self::Class}.{self::Class::[]}(#t117).{self::Class::+}(0));
-  c = let final self::Class? #t118 = c in #t118.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t119 = c{self::Class} in let final self::Class? #t120 = #t118{self::Class}.{self::Class::[]}(#t119).{self::Class::+}(0) in let final void #t121 = #t118{self::Class}.{self::Class::[]=}(#t119, #t120) in #t120;
-  let final self::Class? #t122 = c in #t122.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t123 = c{self::Class} in #t122{self::Class}.{self::Class::[]=}(#t123, #t122{self::Class}.{self::Class::[]}(#t123).{self::Class::+}(1));
-  c = let final self::Class? #t124 = c in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t125 = c{self::Class} in let final self::Class? #t126 = #t124{self::Class}.{self::Class::[]}(#t125) in let final void #t127 = #t124{self::Class}.{self::Class::[]=}(#t125, #t126.{self::Class::+}(1)) in #t126;
-  let final self::Class? #t128 = c in #t128.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t129 = c{self::Class} in let final self::Class? #t130 = #t128{self::Class}.{self::Class::[]}(#t129).{self::Class::+}(1) in let final void #t131 = #t128{self::Class}.{self::Class::[]=}(#t129, #t130) in #t130;
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t133 = c{self::Class} in let final self::Class? #t134 = #t132{self::Class}.{self::Class::[]}(#t133).{self::Class::+}(1) in let final void #t135 = #t132{self::Class}.{self::Class::[]=}(#t133, #t134) in #t134;
-  let final self::Class? #t136 = c in #t136.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t137 = #t136{self::Class}.{self::Class::field} in let final self::Class #t138 = c{self::Class} in #t137.{self::Class::[]=}(#t138, #t137.{self::Class::[]}(#t138).{self::Class::+}(1));
-  c = let final self::Class? #t139 = c in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = #t139{self::Class}.{self::Class::field} in let final self::Class #t141 = c{self::Class} in let final self::Class? #t142 = #t140.{self::Class::[]}(#t141) in let final void #t143 = #t140.{self::Class::[]=}(#t141, #t142.{self::Class::+}(1)) in #t142;
-  let final self::Class? #t144 = c in #t144.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t145 = #t144{self::Class}.{self::Class::field} in let final self::Class #t146 = c{self::Class} in let final self::Class? #t147 = #t145.{self::Class::[]}(#t146).{self::Class::+}(1) in let final void #t148 = #t145.{self::Class::[]=}(#t146, #t147) in #t147;
-  c = let final self::Class? #t149 = c in #t149.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t150 = #t149{self::Class}.{self::Class::field} in let final self::Class #t151 = c{self::Class} in let final self::Class? #t152 = #t150.{self::Class::[]}(#t151).{self::Class::+}(1) in let final void #t153 = #t150.{self::Class::[]=}(#t151, #t152) in #t152;
-  let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class?} null : #t154{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class});
-  let final self::Class? #t155 = c in #t155.{core::Object::==}(null) ?{self::Class} null : #t155{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t157 = #t156{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t158 = c{self::Class} in let final self::Class #t159 = new self::Class::•() in let final void #t160 = #t157.{self::Class::[]=}(#t158, #t159) in #t159;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t162 = #t161.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class}) in #t162.{core::Object::==}(null) ?{self::Class} null : #t162{self::Class}.{self::Class::method}();
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t164 = #t163.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t165 = c{self::Class} in #t164.{self::Class::[]=}(#t165, #t164.{self::Class::[]}(#t165).{self::Class::+}(0));
-  c = let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t167 = #t166.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t168 = c{self::Class} in let final self::Class? #t169 = #t167.{self::Class::[]}(#t168).{self::Class::+}(0) in let final void #t170 = #t167.{self::Class::[]=}(#t168, #t169) in #t169;
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t172 = #t171{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t173 = c{self::Class} in #t172.{self::Class::[]=}(#t173, #t172.{self::Class::[]}(#t173).{self::Class::+}(1));
-  c = let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t175 = #t174{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t176 = c{self::Class} in let final self::Class? #t177 = #t175.{self::Class::[]}(#t176) in let final void #t178 = #t175.{self::Class::[]=}(#t176, #t177.{self::Class::+}(1)) in #t177;
-  let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t180 = #t179{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class? #t182 = #t180.{self::Class::[]}(#t181).{self::Class::+}(1) in let final void #t183 = #t180.{self::Class::[]=}(#t181, #t182) in #t182;
-  c = let final self::Class? #t184 = c in #t184.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t185 = #t184{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t186 = c{self::Class} in let final self::Class? #t187 = #t185.{self::Class::[]}(#t186).{self::Class::+}(1) in let final void #t188 = #t185.{self::Class::[]=}(#t186, #t187) in #t187;
-  let final self::Class? #t189 = c in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = #t189{self::Class}.{self::Class::[]}(c{self::Class}) in #t190.{core::Object::==}(null) ?{self::Class?} null : #t190{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t192 = #t191{self::Class}.{self::Class::[]}(c{self::Class}) in #t192.{core::Object::==}(null) ?{self::Class} null : #t192{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t194 = #t193{self::Class}.{self::Class::[]}(c{self::Class}) in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in let final self::Class #t196 = new self::Class::•() in let final void #t197 = #t194{self::Class}.{self::Class::[]=}(#t195, #t196) in #t196;
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t199 = #t198.{self::Class::[]}(c{self::Class}) in #t199.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t200 = #t199{self::Class}.{self::Class::[]}(c{self::Class}) in #t200.{core::Object::==}(null) ?{self::Class} null : #t200{self::Class}.{self::Class::method}();
-  c = let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t202 = #t201.{self::Class::[]}(c{self::Class}) in #t202.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t203 = #t202{self::Class}.{self::Class::[]}(c{self::Class}) in #t203.{core::Object::==}(null) ?{self::Class} null : #t203{self::Class}.{self::Class::method}();
-  let final self::Class #t204 = c{self::Class} in #t204.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t205 = #t204.{self::Class::[]}(c{self::Class}) in #t205.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t206 = c{self::Class} in #t205{self::Class}.{self::Class::[]}(#t206).{core::Object::==}(null) ?{self::Class} #t205{self::Class}.{self::Class::[]=}(#t206, c{self::Class}) : null;
-  c = let final self::Class #t207 = c{self::Class} in #t207.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t208 = #t207.{self::Class::[]}(c{self::Class}) in #t208.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t209 = c{self::Class} in let final self::Class? #t210 = #t208{self::Class}.{self::Class::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class} let final self::Class #t211 = c{self::Class} in let final void #t212 = #t208{self::Class}.{self::Class::[]=}(#t209, #t211) in #t211 : #t210{self::Class};
-  let final self::Class #t213 = c{self::Class} in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t214 = #t213.{self::Class::[]}(c{self::Class}) in #t214.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t215 = c{self::Class} in #t214{self::Class}.{self::Class::[]=}(#t215, #t214{self::Class}.{self::Class::[]}(#t215).{self::Class::+}(0));
-  c = let final self::Class #t216 = c{self::Class} in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t217 = #t216.{self::Class::[]}(c{self::Class}) in #t217.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t218 = c{self::Class} in let final self::Class? #t219 = #t217{self::Class}.{self::Class::[]}(#t218).{self::Class::+}(0) in let final void #t220 = #t217{self::Class}.{self::Class::[]=}(#t218, #t219) in #t219;
-  let final self::Class? #t221 = c in #t221.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t222 = #t221{self::Class}.{self::Class::[]}(c{self::Class}) in #t222.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t223 = c{self::Class} in #t222{self::Class}.{self::Class::[]=}(#t223, #t222{self::Class}.{self::Class::[]}(#t223).{self::Class::+}(1));
-  c = let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = #t224{self::Class}.{self::Class::[]}(c{self::Class}) in #t225.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t226 = c{self::Class} in let final self::Class? #t227 = #t225{self::Class}.{self::Class::[]}(#t226) in let final void #t228 = #t225{self::Class}.{self::Class::[]=}(#t226, #t227.{self::Class::+}(1)) in #t227;
-  let final self::Class? #t229 = c in #t229.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t230 = #t229{self::Class}.{self::Class::[]}(c{self::Class}) in #t230.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t231 = c{self::Class} in let final self::Class? #t232 = #t230{self::Class}.{self::Class::[]}(#t231).{self::Class::+}(1) in let final void #t233 = #t230{self::Class}.{self::Class::[]=}(#t231, #t232) in #t232;
-  c = let final self::Class? #t234 = c in #t234.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t235 = #t234{self::Class}.{self::Class::[]}(c{self::Class}) in #t235.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t236 = c{self::Class} in let final self::Class? #t237 = #t235{self::Class}.{self::Class::[]}(#t236).{self::Class::+}(1) in let final void #t238 = #t235{self::Class}.{self::Class::[]=}(#t236, #t237) in #t237;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : #t84{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : #t85{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  let final self::Class1? #t86 = n1 in #t86.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t87 = #t86{self::Class1}.{self::Class1::[]}(nullable1) in #t87.{core::Object::==}(null) ?{self::Class1?} null : #t87{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : #t88{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t89 = n1 in #t89.{core::Object::==}(null) ?{self::Class1?} null : #t89{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = #t90{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t92 = nullable1 in let final self::Class1 #t93 = new self::Class1::•() in let final void #t94 = #t91.{self::Class1::[]=}(#t92, #t93) in #t93;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t96 = #t95{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1) in #t96.{core::Object::==}(null) ?{self::Class1?} null : #t96{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t98 = #t97{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t99 = nullable2 in #t98.{self::Class2::[]=}(#t99, #t98.{self::Class2::[]}(#t99).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t101 = #t100{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t102 = nullable2 in let final self::Class2 #t103 = #t101.{self::Class2::[]}(#t102).{self::Class2::+}(0) in let final void #t104 = #t101.{self::Class2::[]=}(#t102, #t103) in #t103;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t106 = nullable1 in #t105{self::Class1}.{self::Class1::[]}(#t106).{core::Object::==}(null) ?{self::Class1?} #t105{self::Class1}.{self::Class1::[]=}(#t106, nullable1) : null;
+  nullable1 = let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t108 = nullable1 in let final self::Class1? #t109 = #t107{self::Class1}.{self::Class1::[]}(#t108) in #t109.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t110 = nullable1 in let final void #t111 = #t107{self::Class1}.{self::Class1::[]=}(#t108, #t110) in #t110 : #t109{self::Class1};
+  let final self::Class2? #t112 = n2 in #t112.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t113 = nullable2 in #t112{self::Class2}.{self::Class2::[]=}(#t113, #t112{self::Class2}.{self::Class2::[]}(#t113).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t114 = n2 in #t114.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t115 = nullable2 in let final self::Class2 #t116 = #t114{self::Class2}.{self::Class2::[]}(#t115).{self::Class2::+}(0) in let final void #t117 = #t114{self::Class2}.{self::Class2::[]=}(#t115, #t116) in #t116;
+  let final self::Class2? #t118 = n2 in #t118.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t119 = nullable2 in #t118{self::Class2}.{self::Class2::[]=}(#t119, #t118{self::Class2}.{self::Class2::[]}(#t119).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t120 = n2 in #t120.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t121 = nullable2 in let final self::Class2 #t122 = #t120{self::Class2}.{self::Class2::[]}(#t121).{self::Class2::+}(0) in let final void #t123 = #t120{self::Class2}.{self::Class2::[]=}(#t121, #t122) in #t122;
+  let final self::Class2? #t124 = n2 in #t124.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t125 = nullable2 in #t124{self::Class2}.{self::Class2::[]=}(#t125, #t124{self::Class2}.{self::Class2::[]}(#t125).{self::Class2::+}(1));
+  nullable2 = let final self::Class2? #t126 = n2 in #t126.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t127 = nullable2 in let final self::Class2 #t128 = #t126{self::Class2}.{self::Class2::[]}(#t127) in let final void #t129 = #t126{self::Class2}.{self::Class2::[]=}(#t127, #t128.{self::Class2::+}(1)) in #t128;
+  let final self::Class2? #t130 = n2 in #t130.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t131 = nullable2 in let final self::Class2 #t132 = #t130{self::Class2}.{self::Class2::[]}(#t131).{self::Class2::+}(1) in let final void #t133 = #t130{self::Class2}.{self::Class2::[]=}(#t131, #t132) in #t132;
+  nullable2 = let final self::Class2? #t134 = n2 in #t134.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t135 = nullable2 in let final self::Class2 #t136 = #t134{self::Class2}.{self::Class2::[]}(#t135).{self::Class2::+}(1) in let final void #t137 = #t134{self::Class2}.{self::Class2::[]=}(#t135, #t136) in #t136;
+  let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t139 = #t138{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t140 = nullable2 in #t139.{self::Class2::[]=}(#t140, #t139.{self::Class2::[]}(#t140).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t142 = #t141{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t143 = nullable2 in let final self::Class2 #t144 = #t142.{self::Class2::[]}(#t143) in let final void #t145 = #t142.{self::Class2::[]=}(#t143, #t144.{self::Class2::+}(1)) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t147 = #t146{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t148 = nullable2 in let final self::Class2 #t149 = #t147.{self::Class2::[]}(#t148).{self::Class2::+}(1) in let final void #t150 = #t147.{self::Class2::[]=}(#t148, #t149) in #t149;
+  nullable2 = let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t152 = #t151{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t153 = nullable2 in let final self::Class2 #t154 = #t152.{self::Class2::[]}(#t153).{self::Class2::+}(1) in let final void #t155 = #t152.{self::Class2::[]=}(#t153, #t154) in #t154;
+  let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class2?} null : #t156{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2);
+  let final self::Class1? #t157 = n1 in #t157.{core::Object::==}(null) ?{self::Class2?} null : #t157{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]=}(nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t158 = n1 in #t158.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t159 = #t158{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t160 = nullable2 in let final self::Class2 #t161 = new self::Class2::•() in let final void #t162 = #t159.{self::Class2::[]=}(#t160, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t164 = #t163{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2) in #t164.{core::Object::==}(null) ?{self::Class2?} null : #t164{self::Class2}.{self::Class2::nonNullable2Method}();
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t166 = #t165{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t167 = nullable2 in #t166.{self::Class2::[]=}(#t167, #t166.{self::Class2::[]}(#t167).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t169 = #t168{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t170 = nullable2 in let final self::Class2 #t171 = #t169.{self::Class2::[]}(#t170).{self::Class2::+}(0) in let final void #t172 = #t169.{self::Class2::[]=}(#t170, #t171) in #t171;
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t174 = #t173{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t175 = nullable2 in #t174.{self::Class2::[]=}(#t175, #t174.{self::Class2::[]}(#t175).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t177 = #t176{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t178 = nullable2 in let final self::Class2 #t179 = #t177.{self::Class2::[]}(#t178) in let final void #t180 = #t177.{self::Class2::[]=}(#t178, #t179.{self::Class2::+}(1)) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = #t181{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t183 = nullable2 in let final self::Class2 #t184 = #t182.{self::Class2::[]}(#t183).{self::Class2::+}(1) in let final void #t185 = #t182.{self::Class2::[]=}(#t183, #t184) in #t184;
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = #t186{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = #t187.{self::Class2::[]}(#t188).{self::Class2::+}(1) in let final void #t190 = #t187.{self::Class2::[]=}(#t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = #t191{self::Class1}.{self::Class1::[]}(nullable1) in #t192.{core::Object::==}(null) ?{self::Class1?} null : #t192{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = #t193{self::Class1}.{self::Class1::[]}(nullable1) in #t194.{core::Object::==}(null) ?{self::Class1?} null : #t194{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t195 = n1 in #t195.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t196 = #t195{self::Class1}.{self::Class1::[]}(nullable1) in #t196.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t197 = nullable1 in let final self::Class1 #t198 = new self::Class1::•() in let final void #t199 = #t196{self::Class1}.{self::Class1::[]=}(#t197, #t198) in #t198;
+  let final self::Class1? #t200 = n1 in #t200.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t201 = #t200{self::Class1}.{self::Class1::[]}(nullable1) in #t201.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t202 = #t201{self::Class1}.{self::Class1::[]}(nullable1) in #t202.{core::Object::==}(null) ?{self::Class1?} null : #t202{self::Class1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t203 = n1 in #t203.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t204 = #t203{self::Class1}.{self::Class1::[]}(nullable1) in #t204.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t205 = #t204{self::Class1}.{self::Class1::[]}(nullable1) in #t205.{core::Object::==}(null) ?{self::Class1?} null : #t205{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t206 = n1 in #t206.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t207 = #t206{self::Class1}.{self::Class1::[]}(nullable1) in #t207.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t208 = nullable1 in #t207{self::Class1}.{self::Class1::[]}(#t208).{core::Object::==}(null) ?{self::Class1?} #t207{self::Class1}.{self::Class1::[]=}(#t208, nullable1) : null;
+  nullable1 = let final self::Class1? #t209 = n1 in #t209.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t210 = #t209{self::Class1}.{self::Class1::[]}(nullable1) in #t210.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t211 = nullable1 in let final self::Class1? #t212 = #t210{self::Class1}.{self::Class1::[]}(#t211) in #t212.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t213 = nullable1 in let final void #t214 = #t210{self::Class1}.{self::Class1::[]=}(#t211, #t213) in #t213 : #t212{self::Class1};
+  let final self::Class3? #t215 = n3 in #t215.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t216 = #t215{self::Class3}.{self::Class3::[]}(nullable3) in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in #t216{self::Class2}.{self::Class2::[]=}(#t217, #t216{self::Class2}.{self::Class2::[]}(#t217).{self::Class2::+}(0));
+  nullable2 = let final self::Class3? #t218 = n3 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = #t218{self::Class3}.{self::Class3::[]}(nullable3) in #t219.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t220 = nullable2 in let final self::Class2 #t221 = #t219{self::Class2}.{self::Class2::[]}(#t220).{self::Class2::+}(0) in let final void #t222 = #t219{self::Class2}.{self::Class2::[]=}(#t220, #t221) in #t221;
+  let final self::Class3? #t223 = n3 in #t223.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t224 = #t223{self::Class3}.{self::Class3::[]}(nullable3) in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t225 = nullable2 in #t224{self::Class2}.{self::Class2::[]=}(#t225, #t224{self::Class2}.{self::Class2::[]}(#t225).{self::Class2::+}(1));
+  nullable2 = let final self::Class3? #t226 = n3 in #t226.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t227 = #t226{self::Class3}.{self::Class3::[]}(nullable3) in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t228 = nullable2 in let final self::Class2 #t229 = #t227{self::Class2}.{self::Class2::[]}(#t228) in let final void #t230 = #t227{self::Class2}.{self::Class2::[]=}(#t228, #t229.{self::Class2::+}(1)) in #t229;
+  let final self::Class3? #t231 = n3 in #t231.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t232 = #t231{self::Class3}.{self::Class3::[]}(nullable3) in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t233 = nullable2 in let final self::Class2 #t234 = #t232{self::Class2}.{self::Class2::[]}(#t233).{self::Class2::+}(1) in let final void #t235 = #t232{self::Class2}.{self::Class2::[]=}(#t233, #t234) in #t234;
+  nullable2 = let final self::Class3? #t236 = n3 in #t236.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t237 = #t236{self::Class3}.{self::Class3::[]}(nullable3) in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t238 = nullable2 in let final self::Class2 #t239 = #t237{self::Class2}.{self::Class2::[]}(#t238).{self::Class2::+}(1) in let final void #t240 = #t237{self::Class2}.{self::Class2::[]=}(#t238, #t239) in #t239;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => (let final self::Class? #t239 = c in #t239.{core::Object::==}(null) ?{self::Class?} null : #t239{self::Class}.{self::Class::field}).{self::Class::+}(0));
-  self::throws(() → self::Class? => (let final self::Class? #t240 = c in #t240.{core::Object::==}(null) ?{self::Class?} null : #t240{self::Class}.{self::Class::field}).{self::Class::unary-}());
-  let final self::Class? #t241 = c in #t241.{core::Object::==}(null) ?{self::Class?} null : #t241.{self::Class::field} = #t241.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t243 = #t242.{self::Class::field}.{self::Class::+}(0) in let final void #t244 = #t242.{self::Class::field} = #t243 in #t243;
-  let final self::Class? #t245 = c in #t245.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t246 = #t245{self::Class}.{self::Class::property} in #t246.{self::Class::field} = #t246.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t247 = c in #t247.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t248 = #t247{self::Class}.{self::Class::property} in #t248.{self::Class::field} = #t248.{self::Class::field}.{self::Class::+}(0);
-  let final self::Class? #t249 = c in #t249.{core::Object::==}(null) ?{self::Class?} null : #t249.{self::Class::field} = #t249.{self::Class::field}.{self::Class::+}(1);
-  c = let final self::Class? #t250 = c in #t250.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t251 = #t250.{self::Class::field} in let final void #t252 = #t250.{self::Class::field} = #t251.{self::Class::+}(1) in #t251;
-  let final self::Class? #t253 = c in #t253.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t254 = #t253.{self::Class::field}.{self::Class::+}(1) in let final void #t255 = #t253.{self::Class::field} = #t254 in #t254;
-  c = let final self::Class? #t256 = c in #t256.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t257 = #t256.{self::Class::field}.{self::Class::+}(1) in let final void #t258 = #t256.{self::Class::field} = #t257 in #t257;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t241 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+  throws(() => n1?.nonNullable1 + 0);
+                                ^" in (let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class1?} null : #t242{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::+}(0));
+  self::throws(() → self::Class1? => let final<BottomType> #t243 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+  throws(() => -n1?.nonNullable1);
+               ^" in (let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class1?} null : #t244{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::unary-}());
+  let final self::Class2? #t245 = n2 in #t245.{core::Object::==}(null) ?{self::Class2?} null : #t245.{self::Class2::nonNullable2} = #t245.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t246 = n2 in #t246.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t247 = #t246.{self::Class2::nonNullable2}.{self::Class2::+}(0) in let final void #t248 = #t246.{self::Class2::nonNullable2} = #t247 in #t247;
+  let final self::Class2? #t249 = n2 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = #t249{self::Class2}.{self::Class2::nonNullable2} in #t250.{self::Class2::nonNullable2} = #t250.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t251 = n2 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = #t251{self::Class2}.{self::Class2::nonNullable2} in #t252.{self::Class2::nonNullable2} = #t252.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  let final self::Class2? #t253 = n2 in #t253.{core::Object::==}(null) ?{self::Class2?} null : #t253.{self::Class2::nonNullable2} = #t253.{self::Class2::nonNullable2}.{self::Class2::+}(1);
+  nullable2 = let final self::Class2? #t254 = n2 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = #t254.{self::Class2::nonNullable2} in let final void #t256 = #t254.{self::Class2::nonNullable2} = #t255.{self::Class2::+}(1) in #t255;
+  let final self::Class2? #t257 = n2 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = #t257.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t259 = #t257.{self::Class2::nonNullable2} = #t258 in #t258;
+  nullable2 = let final self::Class2? #t260 = n2 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = #t260.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t262 = #t260.{self::Class2::nonNullable2} = #t261 in #t261;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class} null : #t259.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t259.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class? #t260 = c in #t260.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t261 = #t260.{self::Class::field} in #t261.{core::Object::==}(null) ?{self::Class} #t260.{self::Class::field} = c{self::Class} : #t261{self::Class};
-  let final self::Class #t262 = c{self::Class} in #t262.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t263 = #t262.{self::Class::property} in #t263.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t263.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class #t264 = c{self::Class} in #t264.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t265 = #t264.{self::Class::property} in let final self::Class? #t266 = #t265.{self::Class::field} in #t266.{core::Object::==}(null) ?{self::Class} #t265.{self::Class::field} = c{self::Class} : #t266{self::Class};
-  let final self::Class #t267 = c{self::Class} in #t267.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t268 = #t267.{self::Class::field} in let final self::Class #t269 = c{self::Class} in #t268.{self::Class::[]}(#t269).{core::Object::==}(null) ?{self::Class} #t268.{self::Class::[]=}(#t269, c{self::Class}) : null;
-  c = let final self::Class #t270 = c{self::Class} in #t270.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t271 = #t270.{self::Class::field} in let final self::Class #t272 = c{self::Class} in let final self::Class? #t273 = #t271.{self::Class::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class} let final self::Class #t274 = c{self::Class} in let final void #t275 = #t271.{self::Class::[]=}(#t272, #t274) in #t274 : #t273{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t263 = n1 in #t263.{core::Object::==}(null) ?{self::Class1?} null : #t263.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t263.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t264 = n1 in #t264.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t265 = #t264.{self::Class1::nullable1} in #t265.{core::Object::==}(null) ?{self::Class1} #t264.{self::Class1::nullable1} = n1{self::Class1} : #t265{self::Class1};
+  let final self::Class1? #t266 = n1 in #t266.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t267 = #t266{self::Class1}.{self::Class1::nonNullable1} in #t267{self::Class1}.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t267{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t268 = n1 in #t268.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t269 = #t268{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t270 = #t269{self::Class1}.{self::Class1::nullable1} in #t270.{core::Object::==}(null) ?{self::Class1} #t269{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : #t270{self::Class1};
+  let final self::Class1? #t271 = n1 in #t271.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t272 = #t271{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t273 = n1{self::Class1} in #t272.{self::Class1::[]}(#t273).{core::Object::==}(null) ?{self::Class1} #t272.{self::Class1::[]=}(#t273, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t274 = n1 in #t274.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t275 = #t274{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t276 = n1{self::Class1} in let final self::Class1? #t277 = #t275.{self::Class1::[]}(#t276) in #t277.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t278 = n1{self::Class1} in let final void #t279 = #t275.{self::Class1::[]=}(#t276, #t278) in #t278 : #t277{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.expect
index f3fc966..b9f84d6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.expect
@@ -1,172 +1,248 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
-  method method() → self::Class
-    return this.{self::Class::property};
-  operator [](self::Class? key) → self::Class?
-    return this.{self::Class::field};
-  operator []=(self::Class? key, self::Class? value) → void {
-    this.{self::Class::field} = value;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
+  get nullable1() → self::Class1?
+    return this.{self::Class1::property1};
+  set nullable1(self::Class1? value) → void {
+    this.{self::Class1::property} = value;
   }
-  operator +(core::int value) → self::Class?
-    return this.{self::Class::field};
-  operator unary-() → self::Class?
-    return this.{self::Class::field};
-  get property() → self::Class
+  method nonNullable1Method() → self::Class1
+    return this.{self::Class1::nonNullable1};
+  operator [](self::Class1? key) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator []=(self::Class1? key, self::Class1? value) → void {
+    this.{self::Class1::property} = value;
+  }
+  operator +(core::int value) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator unary-() → self::Class1?
+    return this.{self::Class1::nullable1};
+  get nonNullable1() → self::Class1
+    return this.{self::Class1::property1};
+  get nonNullable2() → self::Class2
+    return this.{self::Class1::property2};
+}
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
     return this;
+  set property(self::Class2 value) → void {}
+  method nonNullable2Method() → self::Class2
+    return this.{self::Class2::nonNullable2};
+  operator [](self::Class2? key) → self::Class2
+    return this.{self::Class2::property};
+  operator []=(self::Class2? key, self::Class2? value) → void
+    return this.{self::Class2::property};
+  operator +(core::int value) → self::Class2
+    return this.{self::Class2::property};
+  operator unary-() → self::Class2
+    return this.{self::Class2::property};
+  get nonNullable2() → self::Class2
+    return this.{self::Class2::property};
+  set nonNullable2(self::Class2 value) → void {
+    this.{self::Class2::property} = value;
+  }
+}
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
+  operator [](self::Class3? key) → self::Class2?
+    return this.{self::Class3::property};
 }
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : #t1{self::Class}.{self::Class::field};
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : #t2{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t4 = c{self::Class} in #t4.{core::Object::==}(null) ?{self::Class} null : #t4.{self::Class::method}();
-  let final self::Class #t5 = c{self::Class} in #t5.{core::Object::==}(null) ?{self::Class?} null : #t5.{self::Class::property}.{self::Class::field};
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t7 = #t6.{self::Class::field} in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::field};
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = #t8.{self::Class::property}.{self::Class::field} in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::field};
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class} null : #t10.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t11 = c{self::Class} in #t11.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t12 = #t11.{self::Class::field} in #t12.{core::Object::==}(null) ?{self::Class} null : #t12{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = #t13.{self::Class::property}.{self::Class::field} in #t14.{core::Object::==}(null) ?{self::Class} null : #t14{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class? #t15 = let final self::Class #t16 = c{self::Class} in #t16.{core::Object::==}(null) ?{self::Class?} null : #t16.{self::Class::field} in #t15.{core::Object::==}(null) ?{self::Class?} null : #t15{self::Class}.{self::Class::field};
-  self::throws(() → self::Class? => (let final self::Class? #t17 = c in #t17.{core::Object::==}(null) ?{self::Class} null : #t17{self::Class}.{self::Class::field} = new self::Class::•()).{self::Class::field});
-  self::throws(() → self::Class? => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{self::Class} null : #t18{self::Class}.{self::Class::method}()).{self::Class::field});
-  c = let final self::Class #t19 = c{self::Class} in #t19.{core::Object::==}(null) ?{self::Class} null : #t19.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t20 = c{self::Class} in #t20.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t21 = #t20.{self::Class::field} in #t21.{core::Object::==}(null) ?{self::Class} null : #t21{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t22 = c{self::Class} in #t22.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t23 = #t22.{self::Class::property}.{self::Class::field} in #t23.{core::Object::==}(null) ?{self::Class} null : #t23{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t24 = c{self::Class} in #t24.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t25 = #t24.{self::Class::field} in #t25.{core::Object::==}(null) ?{self::Class} null : #t25{self::Class}.{self::Class::method}();
-  let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class?} null : #t26.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t27 = c{self::Class} in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t28 = c in #t28.{core::Object::==}(null) ?{self::Class} null : #t28{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t29 = c in #t29.{core::Object::==}(null) ?{self::Class} null : #t29{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : #t30.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t31 = c{self::Class} in #t31.{core::Object::==}(null) ?{self::Class} null : #t31.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t32 = c{self::Class} in #t32.{core::Object::==}(null) ?{self::Class?} null : #t32.{self::Class::method}().{self::Class::field};
-  let final self::Class #t33 = c{self::Class} in #t33.{core::Object::==}(null) ?{self::Class} null : #t33.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : #t34.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : #t35.{self::Class::property}.{self::Class::property}.{self::Class::field};
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class} null : #t36.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class} null : #t37.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t38 = c{self::Class} in #t38.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t39 = #t38.{self::Class::property}.{self::Class::field} in #t39.{core::Object::==}(null) ?{self::Class} null : #t39{self::Class}.{self::Class::method}();
-  let final self::Class #t40 = c{self::Class} in #t40.{core::Object::==}(null) ?{self::Class?} null : #t40.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  c = let final self::Class #t41 = c{self::Class} in #t41.{core::Object::==}(null) ?{self::Class?} null : #t41.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : #t42{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : #t43{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t44 = c{self::Class} in #t44.{core::Object::==}(null) ?{self::Class} null : #t44.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  c = let final self::Class #t45 = c{self::Class} in #t45.{core::Object::==}(null) ?{self::Class} null : #t45.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t46 = c{self::Class} in #t46.{core::Object::==}(null) ?{self::Class?} null : #t46.{self::Class::method}().{self::Class::property}.{self::Class::field};
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : #t47.{self::Class::method}().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : #t48.{self::Class::method}().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class?} null : #t49.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t50 = c{self::Class} in #t50.{core::Object::==}(null) ?{self::Class?} null : #t50.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t51 = c in #t51.{core::Object::==}(null) ?{self::Class} null : #t51{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t52 = c in #t52.{core::Object::==}(null) ?{self::Class} null : #t52{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : #t53.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : #t54.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : #t55.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class?} null : #t56.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t57 = c in #t57.{core::Object::==}(null) ?{self::Class} null : #t57{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t58 = c in #t58.{core::Object::==}(null) ?{self::Class} null : #t58{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : #t59.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : #t60.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : #t61.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : #t62.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t63 = c in #t63.{core::Object::==}(null) ?{self::Class} null : #t63{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : #t64{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t65 = c{self::Class} in #t65.{core::Object::==}(null) ?{self::Class} null : #t65.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t66 = c{self::Class} in #t66.{core::Object::==}(null) ?{self::Class} null : #t66.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t67 = c{self::Class} in #t67.{core::Object::==}(null) ?{self::Class?} null : #t67.{self::Class::property}.{self::Class::method}().{self::Class::field};
-  let final self::Class #t68 = c{self::Class} in #t68.{core::Object::==}(null) ?{self::Class} null : #t68.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t69 = c{self::Class} in #t69.{core::Object::==}(null) ?{self::Class} null : #t69.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t70 = c{self::Class} in #t70.{core::Object::==}(null) ?{self::Class} null : #t70.{self::Class::property}.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t71 = c{self::Class} in #t71.{core::Object::==}(null) ?{self::Class?} null : #t71.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  c = let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class?} null : #t72.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  let final self::Class? #t73 = c in #t73.{core::Object::==}(null) ?{self::Class} null : #t73{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t74 = c in #t74.{core::Object::==}(null) ?{self::Class} null : #t74{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t75 = c{self::Class} in #t75.{core::Object::==}(null) ?{self::Class} null : #t75.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  c = let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class} null : #t76.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : #t77.{self::Class::method}().{self::Class::method}().{self::Class::field};
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : #t78.{self::Class::method}().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : #t79.{self::Class::method}().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t81 = #t80.{self::Class::method}() in #t81.{core::Object::==}(null) ?{self::Class} null : #t81.{self::Class::method}();
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : #t1{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : #t2{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : #t3{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t4 = n1 in #t4.{core::Object::==}(null) ?{self::Class1?} null : #t4{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t5 = n1 in #t5.{core::Object::==}(null) ?{self::Class1?} null : #t5{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t7 = #t6{self::Class1}.{self::Class1::nullable1} in #t7.{core::Object::==}(null) ?{self::Class1?} null : #t7{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = #t8{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t9.{core::Object::==}(null) ?{self::Class1?} null : #t9{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : #t10{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t11 = n1 in #t11.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t12 = #t11{self::Class1}.{self::Class1::nullable1} in #t12.{core::Object::==}(null) ?{self::Class1?} null : #t12{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = #t13{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t14.{core::Object::==}(null) ?{self::Class1?} null : #t14{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t15 = let final self::Class1? #t16 = n1 in #t16.{core::Object::==}(null) ?{self::Class1?} null : #t16{self::Class1}.{self::Class1::nullable1} in #t15.{core::Object::==}(null) ?{self::Class1?} null : #t15{self::Class1}.{self::Class1::nullable1};
+  self::throws(() → self::Class1? => (let final self::Class1? #t17 = n1 in #t17.{core::Object::==}(null) ?{self::Class1?} null : #t17{self::Class1}.{self::Class1::nullable1} = new self::Class1::•()).{self::Class1::nullable1});
+  self::throws(() → self::Class1? => (let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : #t18{self::Class1}.{self::Class1::nonNullable1Method}()).{self::Class1::nullable1});
+  nullable1 = let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : #t19{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t21 = #t20{self::Class1}.{self::Class1::nullable1} in #t21.{core::Object::==}(null) ?{self::Class1?} null : #t21{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t23 = #t22{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t23.{core::Object::==}(null) ?{self::Class1?} null : #t23{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t25 = #t24{self::Class1}.{self::Class1::nullable1} in #t25.{core::Object::==}(null) ?{self::Class1?} null : #t25{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : #t26{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t27 = n1 in #t27.{core::Object::==}(null) ?{self::Class1?} null : #t27{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : #t28{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t29 = n1 in #t29.{core::Object::==}(null) ?{self::Class1?} null : #t29{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : #t30{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t31 = n1 in #t31.{core::Object::==}(null) ?{self::Class1?} null : #t31{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : #t32{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t33 = n1 in #t33.{core::Object::==}(null) ?{self::Class1?} null : #t33{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : #t34{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t35 = n1 in #t35.{core::Object::==}(null) ?{self::Class1?} null : #t35{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : #t36{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : #t37{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t39 = #t38{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t39.{core::Object::==}(null) ?{self::Class1?} null : #t39{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : #t40{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t41 = n1 in #t41.{core::Object::==}(null) ?{self::Class1?} null : #t41{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : #t42{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : #t43{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t44 = n1 in #t44.{core::Object::==}(null) ?{self::Class1?} null : #t44{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : #t45{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t46 = n1 in #t46.{core::Object::==}(null) ?{self::Class1?} null : #t46{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t47 = n1 in #t47.{core::Object::==}(null) ?{self::Class1?} null : #t47{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : #t48{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : #t49{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : #t50{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : #t51{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : #t52{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : #t53{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : #t54{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : #t55{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : #t56{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : #t57{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : #t58{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : #t59{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : #t60{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t61 = n1 in #t61.{core::Object::==}(null) ?{self::Class1?} null : #t61{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : #t62{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : #t63{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : #t64{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : #t65{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : #t66{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t67 = n1 in #t67.{core::Object::==}(null) ?{self::Class1?} null : #t67{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : #t68{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : #t69{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t70 = n1 in #t70.{core::Object::==}(null) ?{self::Class1?} null : #t70{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : #t71{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t72 = n1 in #t72.{core::Object::==}(null) ?{self::Class1?} null : #t72{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t73 = n1 in #t73.{core::Object::==}(null) ?{self::Class1?} null : #t73{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : #t74{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : #t75{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : #t76{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : #t77{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : #t78{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : #t79{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t81 = #t80{self::Class1}.{self::Class1::nonNullable1Method}() in #t81.{core::Object::==}(null) ?{self::Class1?} null : #t81{self::Class1}.{self::Class1::nonNullable1Method}();
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t82 = c in #t82.{core::Object::==}(null) ?{self::Class?} null : #t82{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : #t83{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  let final self::Class? #t84 = c in #t84.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t85 = #t84{self::Class}.{self::Class::[]}(c{self::Class}) in #t85.{core::Object::==}(null) ?{self::Class} null : #t85{self::Class}.{self::Class::method}();
-  let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class?} null : #t86{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t87 = c in #t87.{core::Object::==}(null) ?{self::Class} null : #t87{self::Class}.{self::Class::field}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t89 = #t88{self::Class}.{self::Class::field} in let final self::Class #t90 = c{self::Class} in let final self::Class #t91 = new self::Class::•() in let final void #t92 = #t89.{self::Class::[]=}(#t90, #t91) in #t91;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t94 = #t93.{self::Class::field}.{self::Class::[]}(c{self::Class}) in #t94.{core::Object::==}(null) ?{self::Class} null : #t94{self::Class}.{self::Class::method}();
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t96 = #t95.{self::Class::field} in let final self::Class #t97 = c{self::Class} in #t96.{self::Class::[]=}(#t97, #t96.{self::Class::[]}(#t97).{self::Class::+}(0));
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = #t98.{self::Class::field} in let final self::Class #t100 = c{self::Class} in let final self::Class? #t101 = #t99.{self::Class::[]}(#t100).{self::Class::+}(0) in let final void #t102 = #t99.{self::Class::[]=}(#t100, #t101) in #t101;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t104 = c{self::Class} in #t103{self::Class}.{self::Class::[]}(#t104).{core::Object::==}(null) ?{self::Class} #t103{self::Class}.{self::Class::[]=}(#t104, c{self::Class}) : null;
-  c = let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t106 = c{self::Class} in let final self::Class? #t107 = #t105{self::Class}.{self::Class::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class} let final self::Class #t108 = c{self::Class} in let final void #t109 = #t105{self::Class}.{self::Class::[]=}(#t106, #t108) in #t108 : #t107{self::Class};
-  let final self::Class #t110 = c{self::Class} in #t110.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t111 = c{self::Class} in #t110.{self::Class::[]=}(#t111, #t110.{self::Class::[]}(#t111).{self::Class::+}(0));
-  c = let final self::Class #t112 = c{self::Class} in #t112.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t113 = c{self::Class} in let final self::Class? #t114 = #t112.{self::Class::[]}(#t113).{self::Class::+}(0) in let final void #t115 = #t112.{self::Class::[]=}(#t113, #t114) in #t114;
-  let final self::Class? #t116 = c in #t116.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t117 = c{self::Class} in #t116{self::Class}.{self::Class::[]=}(#t117, #t116{self::Class}.{self::Class::[]}(#t117).{self::Class::+}(0));
-  c = let final self::Class? #t118 = c in #t118.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t119 = c{self::Class} in let final self::Class? #t120 = #t118{self::Class}.{self::Class::[]}(#t119).{self::Class::+}(0) in let final void #t121 = #t118{self::Class}.{self::Class::[]=}(#t119, #t120) in #t120;
-  let final self::Class? #t122 = c in #t122.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t123 = c{self::Class} in #t122{self::Class}.{self::Class::[]=}(#t123, #t122{self::Class}.{self::Class::[]}(#t123).{self::Class::+}(1));
-  c = let final self::Class? #t124 = c in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t125 = c{self::Class} in let final self::Class? #t126 = #t124{self::Class}.{self::Class::[]}(#t125) in let final void #t127 = #t124{self::Class}.{self::Class::[]=}(#t125, #t126.{self::Class::+}(1)) in #t126;
-  let final self::Class? #t128 = c in #t128.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t129 = c{self::Class} in let final self::Class? #t130 = #t128{self::Class}.{self::Class::[]}(#t129).{self::Class::+}(1) in let final void #t131 = #t128{self::Class}.{self::Class::[]=}(#t129, #t130) in #t130;
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t133 = c{self::Class} in let final self::Class? #t134 = #t132{self::Class}.{self::Class::[]}(#t133).{self::Class::+}(1) in let final void #t135 = #t132{self::Class}.{self::Class::[]=}(#t133, #t134) in #t134;
-  let final self::Class? #t136 = c in #t136.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t137 = #t136{self::Class}.{self::Class::field} in let final self::Class #t138 = c{self::Class} in #t137.{self::Class::[]=}(#t138, #t137.{self::Class::[]}(#t138).{self::Class::+}(1));
-  c = let final self::Class? #t139 = c in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = #t139{self::Class}.{self::Class::field} in let final self::Class #t141 = c{self::Class} in let final self::Class? #t142 = #t140.{self::Class::[]}(#t141) in let final void #t143 = #t140.{self::Class::[]=}(#t141, #t142.{self::Class::+}(1)) in #t142;
-  let final self::Class? #t144 = c in #t144.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t145 = #t144{self::Class}.{self::Class::field} in let final self::Class #t146 = c{self::Class} in let final self::Class? #t147 = #t145.{self::Class::[]}(#t146).{self::Class::+}(1) in let final void #t148 = #t145.{self::Class::[]=}(#t146, #t147) in #t147;
-  c = let final self::Class? #t149 = c in #t149.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t150 = #t149{self::Class}.{self::Class::field} in let final self::Class #t151 = c{self::Class} in let final self::Class? #t152 = #t150.{self::Class::[]}(#t151).{self::Class::+}(1) in let final void #t153 = #t150.{self::Class::[]=}(#t151, #t152) in #t152;
-  let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class?} null : #t154{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class});
-  let final self::Class? #t155 = c in #t155.{core::Object::==}(null) ?{self::Class} null : #t155{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t157 = #t156{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t158 = c{self::Class} in let final self::Class #t159 = new self::Class::•() in let final void #t160 = #t157.{self::Class::[]=}(#t158, #t159) in #t159;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t162 = #t161.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class}) in #t162.{core::Object::==}(null) ?{self::Class} null : #t162{self::Class}.{self::Class::method}();
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t164 = #t163.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t165 = c{self::Class} in #t164.{self::Class::[]=}(#t165, #t164.{self::Class::[]}(#t165).{self::Class::+}(0));
-  c = let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t167 = #t166.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t168 = c{self::Class} in let final self::Class? #t169 = #t167.{self::Class::[]}(#t168).{self::Class::+}(0) in let final void #t170 = #t167.{self::Class::[]=}(#t168, #t169) in #t169;
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t172 = #t171{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t173 = c{self::Class} in #t172.{self::Class::[]=}(#t173, #t172.{self::Class::[]}(#t173).{self::Class::+}(1));
-  c = let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t175 = #t174{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t176 = c{self::Class} in let final self::Class? #t177 = #t175.{self::Class::[]}(#t176) in let final void #t178 = #t175.{self::Class::[]=}(#t176, #t177.{self::Class::+}(1)) in #t177;
-  let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t180 = #t179{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class? #t182 = #t180.{self::Class::[]}(#t181).{self::Class::+}(1) in let final void #t183 = #t180.{self::Class::[]=}(#t181, #t182) in #t182;
-  c = let final self::Class? #t184 = c in #t184.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t185 = #t184{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t186 = c{self::Class} in let final self::Class? #t187 = #t185.{self::Class::[]}(#t186).{self::Class::+}(1) in let final void #t188 = #t185.{self::Class::[]=}(#t186, #t187) in #t187;
-  let final self::Class? #t189 = c in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = #t189{self::Class}.{self::Class::[]}(c{self::Class}) in #t190.{core::Object::==}(null) ?{self::Class?} null : #t190{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t192 = #t191{self::Class}.{self::Class::[]}(c{self::Class}) in #t192.{core::Object::==}(null) ?{self::Class} null : #t192{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t194 = #t193{self::Class}.{self::Class::[]}(c{self::Class}) in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in let final self::Class #t196 = new self::Class::•() in let final void #t197 = #t194{self::Class}.{self::Class::[]=}(#t195, #t196) in #t196;
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t199 = #t198.{self::Class::[]}(c{self::Class}) in #t199.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t200 = #t199{self::Class}.{self::Class::[]}(c{self::Class}) in #t200.{core::Object::==}(null) ?{self::Class} null : #t200{self::Class}.{self::Class::method}();
-  c = let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t202 = #t201.{self::Class::[]}(c{self::Class}) in #t202.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t203 = #t202{self::Class}.{self::Class::[]}(c{self::Class}) in #t203.{core::Object::==}(null) ?{self::Class} null : #t203{self::Class}.{self::Class::method}();
-  let final self::Class #t204 = c{self::Class} in #t204.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t205 = #t204.{self::Class::[]}(c{self::Class}) in #t205.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t206 = c{self::Class} in #t205{self::Class}.{self::Class::[]}(#t206).{core::Object::==}(null) ?{self::Class} #t205{self::Class}.{self::Class::[]=}(#t206, c{self::Class}) : null;
-  c = let final self::Class #t207 = c{self::Class} in #t207.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t208 = #t207.{self::Class::[]}(c{self::Class}) in #t208.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t209 = c{self::Class} in let final self::Class? #t210 = #t208{self::Class}.{self::Class::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class} let final self::Class #t211 = c{self::Class} in let final void #t212 = #t208{self::Class}.{self::Class::[]=}(#t209, #t211) in #t211 : #t210{self::Class};
-  let final self::Class #t213 = c{self::Class} in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t214 = #t213.{self::Class::[]}(c{self::Class}) in #t214.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t215 = c{self::Class} in #t214{self::Class}.{self::Class::[]=}(#t215, #t214{self::Class}.{self::Class::[]}(#t215).{self::Class::+}(0));
-  c = let final self::Class #t216 = c{self::Class} in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t217 = #t216.{self::Class::[]}(c{self::Class}) in #t217.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t218 = c{self::Class} in let final self::Class? #t219 = #t217{self::Class}.{self::Class::[]}(#t218).{self::Class::+}(0) in let final void #t220 = #t217{self::Class}.{self::Class::[]=}(#t218, #t219) in #t219;
-  let final self::Class? #t221 = c in #t221.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t222 = #t221{self::Class}.{self::Class::[]}(c{self::Class}) in #t222.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t223 = c{self::Class} in #t222{self::Class}.{self::Class::[]=}(#t223, #t222{self::Class}.{self::Class::[]}(#t223).{self::Class::+}(1));
-  c = let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = #t224{self::Class}.{self::Class::[]}(c{self::Class}) in #t225.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t226 = c{self::Class} in let final self::Class? #t227 = #t225{self::Class}.{self::Class::[]}(#t226) in let final void #t228 = #t225{self::Class}.{self::Class::[]=}(#t226, #t227.{self::Class::+}(1)) in #t227;
-  let final self::Class? #t229 = c in #t229.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t230 = #t229{self::Class}.{self::Class::[]}(c{self::Class}) in #t230.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t231 = c{self::Class} in let final self::Class? #t232 = #t230{self::Class}.{self::Class::[]}(#t231).{self::Class::+}(1) in let final void #t233 = #t230{self::Class}.{self::Class::[]=}(#t231, #t232) in #t232;
-  c = let final self::Class? #t234 = c in #t234.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t235 = #t234{self::Class}.{self::Class::[]}(c{self::Class}) in #t235.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t236 = c{self::Class} in let final self::Class? #t237 = #t235{self::Class}.{self::Class::[]}(#t236).{self::Class::+}(1) in let final void #t238 = #t235{self::Class}.{self::Class::[]=}(#t236, #t237) in #t237;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : #t82{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : #t83{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = #t84{self::Class1}.{self::Class1::[]}(nullable1) in #t85.{core::Object::==}(null) ?{self::Class1?} null : #t85{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t86 = n1 in #t86.{core::Object::==}(null) ?{self::Class1?} null : #t86{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : #t87{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = #t88{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t90 = nullable1 in let final self::Class1 #t91 = new self::Class1::•() in let final void #t92 = #t89.{self::Class1::[]=}(#t90, #t91) in #t91;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t94 = #t93{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1) in #t94.{core::Object::==}(null) ?{self::Class1?} null : #t94{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t96 = #t95{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t97 = nullable2 in #t96.{self::Class2::[]=}(#t97, #t96.{self::Class2::[]}(#t97).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t98 = n1 in #t98.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t99 = #t98{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t100 = nullable2 in let final self::Class2 #t101 = #t99.{self::Class2::[]}(#t100).{self::Class2::+}(0) in let final void #t102 = #t99.{self::Class2::[]=}(#t100, #t101) in #t101;
+  let final self::Class1? #t103 = n1 in #t103.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t104 = nullable1 in #t103{self::Class1}.{self::Class1::[]}(#t104).{core::Object::==}(null) ?{self::Class1?} #t103{self::Class1}.{self::Class1::[]=}(#t104, nullable1) : null;
+  nullable1 = let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t106 = nullable1 in let final self::Class1? #t107 = #t105{self::Class1}.{self::Class1::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t108 = nullable1 in let final void #t109 = #t105{self::Class1}.{self::Class1::[]=}(#t106, #t108) in #t108 : #t107{self::Class1};
+  let final self::Class2? #t110 = n2 in #t110.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t111 = nullable2 in #t110{self::Class2}.{self::Class2::[]=}(#t111, #t110{self::Class2}.{self::Class2::[]}(#t111).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t112 = n2 in #t112.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t113 = nullable2 in let final self::Class2 #t114 = #t112{self::Class2}.{self::Class2::[]}(#t113).{self::Class2::+}(0) in let final void #t115 = #t112{self::Class2}.{self::Class2::[]=}(#t113, #t114) in #t114;
+  let final self::Class2? #t116 = n2 in #t116.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t117 = nullable2 in #t116{self::Class2}.{self::Class2::[]=}(#t117, #t116{self::Class2}.{self::Class2::[]}(#t117).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t118 = n2 in #t118.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t119 = nullable2 in let final self::Class2 #t120 = #t118{self::Class2}.{self::Class2::[]}(#t119).{self::Class2::+}(0) in let final void #t121 = #t118{self::Class2}.{self::Class2::[]=}(#t119, #t120) in #t120;
+  let final self::Class2? #t122 = n2 in #t122.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t123 = nullable2 in #t122{self::Class2}.{self::Class2::[]=}(#t123, #t122{self::Class2}.{self::Class2::[]}(#t123).{self::Class2::+}(1));
+  nullable2 = let final self::Class2? #t124 = n2 in #t124.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t125 = nullable2 in let final self::Class2 #t126 = #t124{self::Class2}.{self::Class2::[]}(#t125) in let final void #t127 = #t124{self::Class2}.{self::Class2::[]=}(#t125, #t126.{self::Class2::+}(1)) in #t126;
+  let final self::Class2? #t128 = n2 in #t128.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t129 = nullable2 in let final self::Class2 #t130 = #t128{self::Class2}.{self::Class2::[]}(#t129).{self::Class2::+}(1) in let final void #t131 = #t128{self::Class2}.{self::Class2::[]=}(#t129, #t130) in #t130;
+  nullable2 = let final self::Class2? #t132 = n2 in #t132.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t133 = nullable2 in let final self::Class2 #t134 = #t132{self::Class2}.{self::Class2::[]}(#t133).{self::Class2::+}(1) in let final void #t135 = #t132{self::Class2}.{self::Class2::[]=}(#t133, #t134) in #t134;
+  let final self::Class1? #t136 = n1 in #t136.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t137 = #t136{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t138 = nullable2 in #t137.{self::Class2::[]=}(#t138, #t137.{self::Class2::[]}(#t138).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t140 = #t139{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t141 = nullable2 in let final self::Class2 #t142 = #t140.{self::Class2::[]}(#t141) in let final void #t143 = #t140.{self::Class2::[]=}(#t141, #t142.{self::Class2::+}(1)) in #t142;
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t145 = #t144{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t146 = nullable2 in let final self::Class2 #t147 = #t145.{self::Class2::[]}(#t146).{self::Class2::+}(1) in let final void #t148 = #t145.{self::Class2::[]=}(#t146, #t147) in #t147;
+  nullable2 = let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t150 = #t149{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t151 = nullable2 in let final self::Class2 #t152 = #t150.{self::Class2::[]}(#t151).{self::Class2::+}(1) in let final void #t153 = #t150.{self::Class2::[]=}(#t151, #t152) in #t152;
+  let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class2?} null : #t154{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2);
+  let final self::Class1? #t155 = n1 in #t155.{core::Object::==}(null) ?{self::Class2?} null : #t155{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]=}(nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t157 = #t156{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t158 = nullable2 in let final self::Class2 #t159 = new self::Class2::•() in let final void #t160 = #t157.{self::Class2::[]=}(#t158, #t159) in #t159;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t162 = #t161{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2) in #t162.{core::Object::==}(null) ?{self::Class2?} null : #t162{self::Class2}.{self::Class2::nonNullable2Method}();
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t164 = #t163{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t165 = nullable2 in #t164.{self::Class2::[]=}(#t165, #t164.{self::Class2::[]}(#t165).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t167 = #t166{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t168 = nullable2 in let final self::Class2 #t169 = #t167.{self::Class2::[]}(#t168).{self::Class2::+}(0) in let final void #t170 = #t167.{self::Class2::[]=}(#t168, #t169) in #t169;
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t172 = #t171{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t173 = nullable2 in #t172.{self::Class2::[]=}(#t173, #t172.{self::Class2::[]}(#t173).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t175 = #t174{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t176 = nullable2 in let final self::Class2 #t177 = #t175.{self::Class2::[]}(#t176) in let final void #t178 = #t175.{self::Class2::[]=}(#t176, #t177.{self::Class2::+}(1)) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t180 = #t179{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t181 = nullable2 in let final self::Class2 #t182 = #t180.{self::Class2::[]}(#t181).{self::Class2::+}(1) in let final void #t183 = #t180.{self::Class2::[]=}(#t181, #t182) in #t182;
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = #t184{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = #t185.{self::Class2::[]}(#t186).{self::Class2::+}(1) in let final void #t188 = #t185.{self::Class2::[]=}(#t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = #t189{self::Class1}.{self::Class1::[]}(nullable1) in #t190.{core::Object::==}(null) ?{self::Class1?} null : #t190{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = #t191{self::Class1}.{self::Class1::[]}(nullable1) in #t192.{core::Object::==}(null) ?{self::Class1?} null : #t192{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = #t193{self::Class1}.{self::Class1::[]}(nullable1) in #t194.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t195 = nullable1 in let final self::Class1 #t196 = new self::Class1::•() in let final void #t197 = #t194{self::Class1}.{self::Class1::[]=}(#t195, #t196) in #t196;
+  let final self::Class1? #t198 = n1 in #t198.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t199 = #t198{self::Class1}.{self::Class1::[]}(nullable1) in #t199.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t200 = #t199{self::Class1}.{self::Class1::[]}(nullable1) in #t200.{core::Object::==}(null) ?{self::Class1?} null : #t200{self::Class1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t201 = n1 in #t201.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t202 = #t201{self::Class1}.{self::Class1::[]}(nullable1) in #t202.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t203 = #t202{self::Class1}.{self::Class1::[]}(nullable1) in #t203.{core::Object::==}(null) ?{self::Class1?} null : #t203{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t204 = n1 in #t204.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t205 = #t204{self::Class1}.{self::Class1::[]}(nullable1) in #t205.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t206 = nullable1 in #t205{self::Class1}.{self::Class1::[]}(#t206).{core::Object::==}(null) ?{self::Class1?} #t205{self::Class1}.{self::Class1::[]=}(#t206, nullable1) : null;
+  nullable1 = let final self::Class1? #t207 = n1 in #t207.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t208 = #t207{self::Class1}.{self::Class1::[]}(nullable1) in #t208.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t209 = nullable1 in let final self::Class1? #t210 = #t208{self::Class1}.{self::Class1::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t211 = nullable1 in let final void #t212 = #t208{self::Class1}.{self::Class1::[]=}(#t209, #t211) in #t211 : #t210{self::Class1};
+  let final self::Class3? #t213 = n3 in #t213.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t214 = #t213{self::Class3}.{self::Class3::[]}(nullable3) in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in #t214{self::Class2}.{self::Class2::[]=}(#t215, #t214{self::Class2}.{self::Class2::[]}(#t215).{self::Class2::+}(0));
+  nullable2 = let final self::Class3? #t216 = n3 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = #t216{self::Class3}.{self::Class3::[]}(nullable3) in #t217.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t218 = nullable2 in let final self::Class2 #t219 = #t217{self::Class2}.{self::Class2::[]}(#t218).{self::Class2::+}(0) in let final void #t220 = #t217{self::Class2}.{self::Class2::[]=}(#t218, #t219) in #t219;
+  let final self::Class3? #t221 = n3 in #t221.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t222 = #t221{self::Class3}.{self::Class3::[]}(nullable3) in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t223 = nullable2 in #t222{self::Class2}.{self::Class2::[]=}(#t223, #t222{self::Class2}.{self::Class2::[]}(#t223).{self::Class2::+}(1));
+  nullable2 = let final self::Class3? #t224 = n3 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t225 = #t224{self::Class3}.{self::Class3::[]}(nullable3) in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t226 = nullable2 in let final self::Class2 #t227 = #t225{self::Class2}.{self::Class2::[]}(#t226) in let final void #t228 = #t225{self::Class2}.{self::Class2::[]=}(#t226, #t227.{self::Class2::+}(1)) in #t227;
+  let final self::Class3? #t229 = n3 in #t229.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t230 = #t229{self::Class3}.{self::Class3::[]}(nullable3) in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t231 = nullable2 in let final self::Class2 #t232 = #t230{self::Class2}.{self::Class2::[]}(#t231).{self::Class2::+}(1) in let final void #t233 = #t230{self::Class2}.{self::Class2::[]=}(#t231, #t232) in #t232;
+  nullable2 = let final self::Class3? #t234 = n3 in #t234.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t235 = #t234{self::Class3}.{self::Class3::[]}(nullable3) in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t236 = nullable2 in let final self::Class2 #t237 = #t235{self::Class2}.{self::Class2::[]}(#t236).{self::Class2::+}(1) in let final void #t238 = #t235{self::Class2}.{self::Class2::[]=}(#t236, #t237) in #t237;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => (let final self::Class? #t239 = c in #t239.{core::Object::==}(null) ?{self::Class?} null : #t239{self::Class}.{self::Class::field}).{self::Class::+}(0));
-  self::throws(() → self::Class? => (let final self::Class? #t240 = c in #t240.{core::Object::==}(null) ?{self::Class?} null : #t240{self::Class}.{self::Class::field}).{self::Class::unary-}());
-  let final self::Class? #t241 = c in #t241.{core::Object::==}(null) ?{self::Class?} null : #t241.{self::Class::field} = #t241.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t243 = #t242.{self::Class::field}.{self::Class::+}(0) in let final void #t244 = #t242.{self::Class::field} = #t243 in #t243;
-  let final self::Class? #t245 = c in #t245.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t246 = #t245{self::Class}.{self::Class::property} in #t246.{self::Class::field} = #t246.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t247 = c in #t247.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t248 = #t247{self::Class}.{self::Class::property} in #t248.{self::Class::field} = #t248.{self::Class::field}.{self::Class::+}(0);
-  let final self::Class? #t249 = c in #t249.{core::Object::==}(null) ?{self::Class?} null : #t249.{self::Class::field} = #t249.{self::Class::field}.{self::Class::+}(1);
-  c = let final self::Class? #t250 = c in #t250.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t251 = #t250.{self::Class::field} in let final void #t252 = #t250.{self::Class::field} = #t251.{self::Class::+}(1) in #t251;
-  let final self::Class? #t253 = c in #t253.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t254 = #t253.{self::Class::field}.{self::Class::+}(1) in let final void #t255 = #t253.{self::Class::field} = #t254 in #t254;
-  c = let final self::Class? #t256 = c in #t256.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t257 = #t256.{self::Class::field}.{self::Class::+}(1) in let final void #t258 = #t256.{self::Class::field} = #t257 in #t257;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => (let final self::Class1? #t239 = n1 in #t239.{core::Object::==}(null) ?{self::Class1?} null : #t239{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::+}(0));
+  self::throws(() → self::Class1? => (let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class1?} null : #t240{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::unary-}());
+  let final self::Class2? #t241 = n2 in #t241.{core::Object::==}(null) ?{self::Class2?} null : #t241.{self::Class2::nonNullable2} = #t241.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t242 = n2 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = #t242.{self::Class2::nonNullable2}.{self::Class2::+}(0) in let final void #t244 = #t242.{self::Class2::nonNullable2} = #t243 in #t243;
+  let final self::Class2? #t245 = n2 in #t245.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t246 = #t245{self::Class2}.{self::Class2::nonNullable2} in #t246.{self::Class2::nonNullable2} = #t246.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t247 = n2 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t248 = #t247{self::Class2}.{self::Class2::nonNullable2} in #t248.{self::Class2::nonNullable2} = #t248.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  let final self::Class2? #t249 = n2 in #t249.{core::Object::==}(null) ?{self::Class2?} null : #t249.{self::Class2::nonNullable2} = #t249.{self::Class2::nonNullable2}.{self::Class2::+}(1);
+  nullable2 = let final self::Class2? #t250 = n2 in #t250.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t251 = #t250.{self::Class2::nonNullable2} in let final void #t252 = #t250.{self::Class2::nonNullable2} = #t251.{self::Class2::+}(1) in #t251;
+  let final self::Class2? #t253 = n2 in #t253.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t254 = #t253.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t255 = #t253.{self::Class2::nonNullable2} = #t254 in #t254;
+  nullable2 = let final self::Class2? #t256 = n2 in #t256.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t257 = #t256.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t258 = #t256.{self::Class2::nonNullable2} = #t257 in #t257;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class} null : #t259.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t259.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class? #t260 = c in #t260.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t261 = #t260.{self::Class::field} in #t261.{core::Object::==}(null) ?{self::Class} #t260.{self::Class::field} = c{self::Class} : #t261{self::Class};
-  let final self::Class #t262 = c{self::Class} in #t262.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t263 = #t262.{self::Class::property} in #t263.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t263.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class #t264 = c{self::Class} in #t264.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t265 = #t264.{self::Class::property} in let final self::Class? #t266 = #t265.{self::Class::field} in #t266.{core::Object::==}(null) ?{self::Class} #t265.{self::Class::field} = c{self::Class} : #t266{self::Class};
-  let final self::Class #t267 = c{self::Class} in #t267.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t268 = #t267.{self::Class::field} in let final self::Class #t269 = c{self::Class} in #t268.{self::Class::[]}(#t269).{core::Object::==}(null) ?{self::Class} #t268.{self::Class::[]=}(#t269, c{self::Class}) : null;
-  c = let final self::Class #t270 = c{self::Class} in #t270.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t271 = #t270.{self::Class::field} in let final self::Class #t272 = c{self::Class} in let final self::Class? #t273 = #t271.{self::Class::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class} let final self::Class #t274 = c{self::Class} in let final void #t275 = #t271.{self::Class::[]=}(#t272, #t274) in #t274 : #t273{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class1?} null : #t259.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t259.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t261 = #t260.{self::Class1::nullable1} in #t261.{core::Object::==}(null) ?{self::Class1} #t260.{self::Class1::nullable1} = n1{self::Class1} : #t261{self::Class1};
+  let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t263 = #t262{self::Class1}.{self::Class1::nonNullable1} in #t263{self::Class1}.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t263{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t264 = n1 in #t264.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t265 = #t264{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t266 = #t265{self::Class1}.{self::Class1::nullable1} in #t266.{core::Object::==}(null) ?{self::Class1} #t265{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : #t266{self::Class1};
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t268 = #t267{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t269 = n1{self::Class1} in #t268.{self::Class1::[]}(#t269).{core::Object::==}(null) ?{self::Class1} #t268.{self::Class1::[]=}(#t269, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t271 = #t270{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t272 = n1{self::Class1} in let final self::Class1? #t273 = #t271.{self::Class1::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t274 = n1{self::Class1} in let final void #t275 = #t271.{self::Class1::[]=}(#t272, #t274) in #t274 : #t273{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.transformed.expect
index f3fc966..b9f84d6 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.weak.transformed.expect
@@ -1,172 +1,248 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:87:47: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:88:43: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:226:33: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting.dart:227:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
-  method method() → self::Class
-    return this.{self::Class::property};
-  operator [](self::Class? key) → self::Class?
-    return this.{self::Class::field};
-  operator []=(self::Class? key, self::Class? value) → void {
-    this.{self::Class::field} = value;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
+  get nullable1() → self::Class1?
+    return this.{self::Class1::property1};
+  set nullable1(self::Class1? value) → void {
+    this.{self::Class1::property} = value;
   }
-  operator +(core::int value) → self::Class?
-    return this.{self::Class::field};
-  operator unary-() → self::Class?
-    return this.{self::Class::field};
-  get property() → self::Class
+  method nonNullable1Method() → self::Class1
+    return this.{self::Class1::nonNullable1};
+  operator [](self::Class1? key) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator []=(self::Class1? key, self::Class1? value) → void {
+    this.{self::Class1::property} = value;
+  }
+  operator +(core::int value) → self::Class1?
+    return this.{self::Class1::nullable1};
+  operator unary-() → self::Class1?
+    return this.{self::Class1::nullable1};
+  get nonNullable1() → self::Class1
+    return this.{self::Class1::property1};
+  get nonNullable2() → self::Class2
+    return this.{self::Class1::property2};
+}
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
     return this;
+  set property(self::Class2 value) → void {}
+  method nonNullable2Method() → self::Class2
+    return this.{self::Class2::nonNullable2};
+  operator [](self::Class2? key) → self::Class2
+    return this.{self::Class2::property};
+  operator []=(self::Class2? key, self::Class2? value) → void
+    return this.{self::Class2::property};
+  operator +(core::int value) → self::Class2
+    return this.{self::Class2::property};
+  operator unary-() → self::Class2
+    return this.{self::Class2::property};
+  get nonNullable2() → self::Class2
+    return this.{self::Class2::property};
+  set nonNullable2(self::Class2 value) → void {
+    this.{self::Class2::property} = value;
+  }
+}
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
+  operator [](self::Class3? key) → self::Class2?
+    return this.{self::Class3::property};
 }
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : #t1{self::Class}.{self::Class::field};
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : #t2{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : #t3{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t4 = c{self::Class} in #t4.{core::Object::==}(null) ?{self::Class} null : #t4.{self::Class::method}();
-  let final self::Class #t5 = c{self::Class} in #t5.{core::Object::==}(null) ?{self::Class?} null : #t5.{self::Class::property}.{self::Class::field};
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t7 = #t6.{self::Class::field} in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::field};
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = #t8.{self::Class::property}.{self::Class::field} in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::field};
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class} null : #t10.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t11 = c{self::Class} in #t11.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t12 = #t11.{self::Class::field} in #t12.{core::Object::==}(null) ?{self::Class} null : #t12{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = #t13.{self::Class::property}.{self::Class::field} in #t14.{core::Object::==}(null) ?{self::Class} null : #t14{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class? #t15 = let final self::Class #t16 = c{self::Class} in #t16.{core::Object::==}(null) ?{self::Class?} null : #t16.{self::Class::field} in #t15.{core::Object::==}(null) ?{self::Class?} null : #t15{self::Class}.{self::Class::field};
-  self::throws(() → self::Class? => (let final self::Class? #t17 = c in #t17.{core::Object::==}(null) ?{self::Class} null : #t17{self::Class}.{self::Class::field} = new self::Class::•()).{self::Class::field});
-  self::throws(() → self::Class? => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{self::Class} null : #t18{self::Class}.{self::Class::method}()).{self::Class::field});
-  c = let final self::Class #t19 = c{self::Class} in #t19.{core::Object::==}(null) ?{self::Class} null : #t19.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t20 = c{self::Class} in #t20.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t21 = #t20.{self::Class::field} in #t21.{core::Object::==}(null) ?{self::Class} null : #t21{self::Class}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t22 = c{self::Class} in #t22.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t23 = #t22.{self::Class::property}.{self::Class::field} in #t23.{core::Object::==}(null) ?{self::Class} null : #t23{self::Class}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t24 = c{self::Class} in #t24.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t25 = #t24.{self::Class::field} in #t25.{core::Object::==}(null) ?{self::Class} null : #t25{self::Class}.{self::Class::method}();
-  let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class?} null : #t26.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t27 = c{self::Class} in #t27.{core::Object::==}(null) ?{self::Class?} null : #t27.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t28 = c in #t28.{core::Object::==}(null) ?{self::Class} null : #t28{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t29 = c in #t29.{core::Object::==}(null) ?{self::Class} null : #t29{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : #t30.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t31 = c{self::Class} in #t31.{core::Object::==}(null) ?{self::Class} null : #t31.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t32 = c{self::Class} in #t32.{core::Object::==}(null) ?{self::Class?} null : #t32.{self::Class::method}().{self::Class::field};
-  let final self::Class #t33 = c{self::Class} in #t33.{core::Object::==}(null) ?{self::Class} null : #t33.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : #t34.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : #t35.{self::Class::property}.{self::Class::property}.{self::Class::field};
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class} null : #t36.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class} null : #t37.{self::Class::property}.{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t38 = c{self::Class} in #t38.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t39 = #t38.{self::Class::property}.{self::Class::field} in #t39.{core::Object::==}(null) ?{self::Class} null : #t39{self::Class}.{self::Class::method}();
-  let final self::Class #t40 = c{self::Class} in #t40.{core::Object::==}(null) ?{self::Class?} null : #t40.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  c = let final self::Class #t41 = c{self::Class} in #t41.{core::Object::==}(null) ?{self::Class?} null : #t41.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field};
-  let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : #t42{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : #t43{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t44 = c{self::Class} in #t44.{core::Object::==}(null) ?{self::Class} null : #t44.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  c = let final self::Class #t45 = c{self::Class} in #t45.{core::Object::==}(null) ?{self::Class} null : #t45.{self::Class::field} = new self::Class::•().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t46 = c{self::Class} in #t46.{core::Object::==}(null) ?{self::Class?} null : #t46.{self::Class::method}().{self::Class::property}.{self::Class::field};
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : #t47.{self::Class::method}().{self::Class::property}.{self::Class::field} = new self::Class::•();
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : #t48.{self::Class::method}().{self::Class::property}.{self::Class::method}();
-  let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class?} null : #t49.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t50 = c{self::Class} in #t50.{core::Object::==}(null) ?{self::Class?} null : #t50.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t51 = c in #t51.{core::Object::==}(null) ?{self::Class} null : #t51{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t52 = c in #t52.{core::Object::==}(null) ?{self::Class} null : #t52{self::Class}.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : #t53.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : #t54.{self::Class::property}.{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : #t55.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class?} null : #t56.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t57 = c in #t57.{core::Object::==}(null) ?{self::Class} null : #t57{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t58 = c in #t58.{core::Object::==}(null) ?{self::Class} null : #t58{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : #t59.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : #t60.{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : #t61.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : #t62.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field};
-  let final self::Class? #t63 = c in #t63.{core::Object::==}(null) ?{self::Class} null : #t63{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : #t64{self::Class}.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::field} = new self::Class::•();
-  let final self::Class #t65 = c{self::Class} in #t65.{core::Object::==}(null) ?{self::Class} null : #t65.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  c = let final self::Class #t66 = c{self::Class} in #t66.{core::Object::==}(null) ?{self::Class} null : #t66.{self::Class::method}().{self::Class::field} = new self::Class::•().{self::Class::method}();
-  let final self::Class #t67 = c{self::Class} in #t67.{core::Object::==}(null) ?{self::Class?} null : #t67.{self::Class::property}.{self::Class::method}().{self::Class::field};
-  let final self::Class #t68 = c{self::Class} in #t68.{core::Object::==}(null) ?{self::Class} null : #t68.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class #t69 = c{self::Class} in #t69.{core::Object::==}(null) ?{self::Class} null : #t69.{self::Class::property}.{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t70 = c{self::Class} in #t70.{core::Object::==}(null) ?{self::Class} null : #t70.{self::Class::property}.{self::Class::method}().{self::Class::method}();
-  let final self::Class #t71 = c{self::Class} in #t71.{core::Object::==}(null) ?{self::Class?} null : #t71.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  c = let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class?} null : #t72.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field};
-  let final self::Class? #t73 = c in #t73.{core::Object::==}(null) ?{self::Class} null : #t73{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  c = let final self::Class? #t74 = c in #t74.{core::Object::==}(null) ?{self::Class} null : #t74{self::Class}.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t75 = c{self::Class} in #t75.{core::Object::==}(null) ?{self::Class} null : #t75.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  c = let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class} null : #t76.{self::Class::field} = new self::Class::•().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : #t77.{self::Class::method}().{self::Class::method}().{self::Class::field};
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : #t78.{self::Class::method}().{self::Class::method}().{self::Class::field} = new self::Class::•();
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : #t79.{self::Class::method}().{self::Class::method}().{self::Class::method}();
-  let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t81 = #t80.{self::Class::method}() in #t81.{core::Object::==}(null) ?{self::Class} null : #t81.{self::Class::method}();
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : #t1{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : #t2{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : #t3{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t4 = n1 in #t4.{core::Object::==}(null) ?{self::Class1?} null : #t4{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t5 = n1 in #t5.{core::Object::==}(null) ?{self::Class1?} null : #t5{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t7 = #t6{self::Class1}.{self::Class1::nullable1} in #t7.{core::Object::==}(null) ?{self::Class1?} null : #t7{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = #t8{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t9.{core::Object::==}(null) ?{self::Class1?} null : #t9{self::Class1}.{self::Class1::nullable1};
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : #t10{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t11 = n1 in #t11.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t12 = #t11{self::Class1}.{self::Class1::nullable1} in #t12.{core::Object::==}(null) ?{self::Class1?} null : #t12{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = #t13{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t14.{core::Object::==}(null) ?{self::Class1?} null : #t14{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t15 = let final self::Class1? #t16 = n1 in #t16.{core::Object::==}(null) ?{self::Class1?} null : #t16{self::Class1}.{self::Class1::nullable1} in #t15.{core::Object::==}(null) ?{self::Class1?} null : #t15{self::Class1}.{self::Class1::nullable1};
+  self::throws(() → self::Class1? => (let final self::Class1? #t17 = n1 in #t17.{core::Object::==}(null) ?{self::Class1?} null : #t17{self::Class1}.{self::Class1::nullable1} = new self::Class1::•()).{self::Class1::nullable1});
+  self::throws(() → self::Class1? => (let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : #t18{self::Class1}.{self::Class1::nonNullable1Method}()).{self::Class1::nullable1});
+  nullable1 = let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : #t19{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t21 = #t20{self::Class1}.{self::Class1::nullable1} in #t21.{core::Object::==}(null) ?{self::Class1?} null : #t21{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t23 = #t22{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t23.{core::Object::==}(null) ?{self::Class1?} null : #t23{self::Class1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t25 = #t24{self::Class1}.{self::Class1::nullable1} in #t25.{core::Object::==}(null) ?{self::Class1?} null : #t25{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : #t26{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t27 = n1 in #t27.{core::Object::==}(null) ?{self::Class1?} null : #t27{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : #t28{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t29 = n1 in #t29.{core::Object::==}(null) ?{self::Class1?} null : #t29{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : #t30{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t31 = n1 in #t31.{core::Object::==}(null) ?{self::Class1?} null : #t31{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : #t32{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t33 = n1 in #t33.{core::Object::==}(null) ?{self::Class1?} null : #t33{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : #t34{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t35 = n1 in #t35.{core::Object::==}(null) ?{self::Class1?} null : #t35{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : #t36{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : #t37{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t39 = #t38{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} in #t39.{core::Object::==}(null) ?{self::Class1?} null : #t39{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : #t40{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t41 = n1 in #t41.{core::Object::==}(null) ?{self::Class1?} null : #t41{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : #t42{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : #t43{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t44 = n1 in #t44.{core::Object::==}(null) ?{self::Class1?} null : #t44{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : #t45{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t46 = n1 in #t46.{core::Object::==}(null) ?{self::Class1?} null : #t46{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1};
+  let final self::Class1? #t47 = n1 in #t47.{core::Object::==}(null) ?{self::Class1?} null : #t47{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : #t48{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : #t49{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : #t50{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : #t51{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : #t52{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : #t53{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : #t54{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : #t55{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : #t56{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : #t57{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : #t58{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : #t59{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : #t60{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t61 = n1 in #t61.{core::Object::==}(null) ?{self::Class1?} null : #t61{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : #t62{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1};
+  let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : #t63{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : #t64{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : #t65{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : #t66{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t67 = n1 in #t67.{core::Object::==}(null) ?{self::Class1?} null : #t67{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : #t68{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : #t69{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t70 = n1 in #t70.{core::Object::==}(null) ?{self::Class1?} null : #t70{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : #t71{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  nullable1 = let final self::Class1? #t72 = n1 in #t72.{core::Object::==}(null) ?{self::Class1?} null : #t72{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t73 = n1 in #t73.{core::Object::==}(null) ?{self::Class1?} null : #t73{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  nullable1 = let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : #t74{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : #t75{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : #t76{self::Class1}.{self::Class1::nullable1} = new self::Class1::•().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : #t77{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1};
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : #t78{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nullable1} = new self::Class1::•();
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : #t79{self::Class1}.{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}().{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t81 = #t80{self::Class1}.{self::Class1::nonNullable1Method}() in #t81.{core::Object::==}(null) ?{self::Class1?} null : #t81{self::Class1}.{self::Class1::nonNullable1Method}();
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t82 = c in #t82.{core::Object::==}(null) ?{self::Class?} null : #t82{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : #t83{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  let final self::Class? #t84 = c in #t84.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t85 = #t84{self::Class}.{self::Class::[]}(c{self::Class}) in #t85.{core::Object::==}(null) ?{self::Class} null : #t85{self::Class}.{self::Class::method}();
-  let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class?} null : #t86{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t87 = c in #t87.{core::Object::==}(null) ?{self::Class} null : #t87{self::Class}.{self::Class::field}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t89 = #t88{self::Class}.{self::Class::field} in let final self::Class #t90 = c{self::Class} in let final self::Class #t91 = new self::Class::•() in let final void #t92 = #t89.{self::Class::[]=}(#t90, #t91) in #t91;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t94 = #t93.{self::Class::field}.{self::Class::[]}(c{self::Class}) in #t94.{core::Object::==}(null) ?{self::Class} null : #t94{self::Class}.{self::Class::method}();
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t96 = #t95.{self::Class::field} in let final self::Class #t97 = c{self::Class} in #t96.{self::Class::[]=}(#t97, #t96.{self::Class::[]}(#t97).{self::Class::+}(0));
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = #t98.{self::Class::field} in let final self::Class #t100 = c{self::Class} in let final self::Class? #t101 = #t99.{self::Class::[]}(#t100).{self::Class::+}(0) in let final void #t102 = #t99.{self::Class::[]=}(#t100, #t101) in #t101;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t104 = c{self::Class} in #t103{self::Class}.{self::Class::[]}(#t104).{core::Object::==}(null) ?{self::Class} #t103{self::Class}.{self::Class::[]=}(#t104, c{self::Class}) : null;
-  c = let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t106 = c{self::Class} in let final self::Class? #t107 = #t105{self::Class}.{self::Class::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class} let final self::Class #t108 = c{self::Class} in let final void #t109 = #t105{self::Class}.{self::Class::[]=}(#t106, #t108) in #t108 : #t107{self::Class};
-  let final self::Class #t110 = c{self::Class} in #t110.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t111 = c{self::Class} in #t110.{self::Class::[]=}(#t111, #t110.{self::Class::[]}(#t111).{self::Class::+}(0));
-  c = let final self::Class #t112 = c{self::Class} in #t112.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t113 = c{self::Class} in let final self::Class? #t114 = #t112.{self::Class::[]}(#t113).{self::Class::+}(0) in let final void #t115 = #t112.{self::Class::[]=}(#t113, #t114) in #t114;
-  let final self::Class? #t116 = c in #t116.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t117 = c{self::Class} in #t116{self::Class}.{self::Class::[]=}(#t117, #t116{self::Class}.{self::Class::[]}(#t117).{self::Class::+}(0));
-  c = let final self::Class? #t118 = c in #t118.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t119 = c{self::Class} in let final self::Class? #t120 = #t118{self::Class}.{self::Class::[]}(#t119).{self::Class::+}(0) in let final void #t121 = #t118{self::Class}.{self::Class::[]=}(#t119, #t120) in #t120;
-  let final self::Class? #t122 = c in #t122.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t123 = c{self::Class} in #t122{self::Class}.{self::Class::[]=}(#t123, #t122{self::Class}.{self::Class::[]}(#t123).{self::Class::+}(1));
-  c = let final self::Class? #t124 = c in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t125 = c{self::Class} in let final self::Class? #t126 = #t124{self::Class}.{self::Class::[]}(#t125) in let final void #t127 = #t124{self::Class}.{self::Class::[]=}(#t125, #t126.{self::Class::+}(1)) in #t126;
-  let final self::Class? #t128 = c in #t128.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t129 = c{self::Class} in let final self::Class? #t130 = #t128{self::Class}.{self::Class::[]}(#t129).{self::Class::+}(1) in let final void #t131 = #t128{self::Class}.{self::Class::[]=}(#t129, #t130) in #t130;
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t133 = c{self::Class} in let final self::Class? #t134 = #t132{self::Class}.{self::Class::[]}(#t133).{self::Class::+}(1) in let final void #t135 = #t132{self::Class}.{self::Class::[]=}(#t133, #t134) in #t134;
-  let final self::Class? #t136 = c in #t136.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t137 = #t136{self::Class}.{self::Class::field} in let final self::Class #t138 = c{self::Class} in #t137.{self::Class::[]=}(#t138, #t137.{self::Class::[]}(#t138).{self::Class::+}(1));
-  c = let final self::Class? #t139 = c in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = #t139{self::Class}.{self::Class::field} in let final self::Class #t141 = c{self::Class} in let final self::Class? #t142 = #t140.{self::Class::[]}(#t141) in let final void #t143 = #t140.{self::Class::[]=}(#t141, #t142.{self::Class::+}(1)) in #t142;
-  let final self::Class? #t144 = c in #t144.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t145 = #t144{self::Class}.{self::Class::field} in let final self::Class #t146 = c{self::Class} in let final self::Class? #t147 = #t145.{self::Class::[]}(#t146).{self::Class::+}(1) in let final void #t148 = #t145.{self::Class::[]=}(#t146, #t147) in #t147;
-  c = let final self::Class? #t149 = c in #t149.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t150 = #t149{self::Class}.{self::Class::field} in let final self::Class #t151 = c{self::Class} in let final self::Class? #t152 = #t150.{self::Class::[]}(#t151).{self::Class::+}(1) in let final void #t153 = #t150.{self::Class::[]=}(#t151, #t152) in #t152;
-  let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class?} null : #t154{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class});
-  let final self::Class? #t155 = c in #t155.{core::Object::==}(null) ?{self::Class} null : #t155{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t157 = #t156{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t158 = c{self::Class} in let final self::Class #t159 = new self::Class::•() in let final void #t160 = #t157.{self::Class::[]=}(#t158, #t159) in #t159;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t162 = #t161.{self::Class::field}.{self::Class::[]}(c{self::Class}).{self::Class::[]}(c{self::Class}) in #t162.{core::Object::==}(null) ?{self::Class} null : #t162{self::Class}.{self::Class::method}();
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t164 = #t163.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t165 = c{self::Class} in #t164.{self::Class::[]=}(#t165, #t164.{self::Class::[]}(#t165).{self::Class::+}(0));
-  c = let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t167 = #t166.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t168 = c{self::Class} in let final self::Class? #t169 = #t167.{self::Class::[]}(#t168).{self::Class::+}(0) in let final void #t170 = #t167.{self::Class::[]=}(#t168, #t169) in #t169;
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t172 = #t171{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t173 = c{self::Class} in #t172.{self::Class::[]=}(#t173, #t172.{self::Class::[]}(#t173).{self::Class::+}(1));
-  c = let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t175 = #t174{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t176 = c{self::Class} in let final self::Class? #t177 = #t175.{self::Class::[]}(#t176) in let final void #t178 = #t175.{self::Class::[]=}(#t176, #t177.{self::Class::+}(1)) in #t177;
-  let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t180 = #t179{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class? #t182 = #t180.{self::Class::[]}(#t181).{self::Class::+}(1) in let final void #t183 = #t180.{self::Class::[]=}(#t181, #t182) in #t182;
-  c = let final self::Class? #t184 = c in #t184.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t185 = #t184{self::Class}.{self::Class::field}.{self::Class::[]}(c{self::Class}) in let final self::Class #t186 = c{self::Class} in let final self::Class? #t187 = #t185.{self::Class::[]}(#t186).{self::Class::+}(1) in let final void #t188 = #t185.{self::Class::[]=}(#t186, #t187) in #t187;
-  let final self::Class? #t189 = c in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = #t189{self::Class}.{self::Class::[]}(c{self::Class}) in #t190.{core::Object::==}(null) ?{self::Class?} null : #t190{self::Class}.{self::Class::[]}(c{self::Class});
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t192 = #t191{self::Class}.{self::Class::[]}(c{self::Class}) in #t192.{core::Object::==}(null) ?{self::Class} null : #t192{self::Class}.{self::Class::[]=}(c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t194 = #t193{self::Class}.{self::Class::[]}(c{self::Class}) in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in let final self::Class #t196 = new self::Class::•() in let final void #t197 = #t194{self::Class}.{self::Class::[]=}(#t195, #t196) in #t196;
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t199 = #t198.{self::Class::[]}(c{self::Class}) in #t199.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t200 = #t199{self::Class}.{self::Class::[]}(c{self::Class}) in #t200.{core::Object::==}(null) ?{self::Class} null : #t200{self::Class}.{self::Class::method}();
-  c = let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t202 = #t201.{self::Class::[]}(c{self::Class}) in #t202.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t203 = #t202{self::Class}.{self::Class::[]}(c{self::Class}) in #t203.{core::Object::==}(null) ?{self::Class} null : #t203{self::Class}.{self::Class::method}();
-  let final self::Class #t204 = c{self::Class} in #t204.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t205 = #t204.{self::Class::[]}(c{self::Class}) in #t205.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t206 = c{self::Class} in #t205{self::Class}.{self::Class::[]}(#t206).{core::Object::==}(null) ?{self::Class} #t205{self::Class}.{self::Class::[]=}(#t206, c{self::Class}) : null;
-  c = let final self::Class #t207 = c{self::Class} in #t207.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t208 = #t207.{self::Class::[]}(c{self::Class}) in #t208.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t209 = c{self::Class} in let final self::Class? #t210 = #t208{self::Class}.{self::Class::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class} let final self::Class #t211 = c{self::Class} in let final void #t212 = #t208{self::Class}.{self::Class::[]=}(#t209, #t211) in #t211 : #t210{self::Class};
-  let final self::Class #t213 = c{self::Class} in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t214 = #t213.{self::Class::[]}(c{self::Class}) in #t214.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t215 = c{self::Class} in #t214{self::Class}.{self::Class::[]=}(#t215, #t214{self::Class}.{self::Class::[]}(#t215).{self::Class::+}(0));
-  c = let final self::Class #t216 = c{self::Class} in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t217 = #t216.{self::Class::[]}(c{self::Class}) in #t217.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t218 = c{self::Class} in let final self::Class? #t219 = #t217{self::Class}.{self::Class::[]}(#t218).{self::Class::+}(0) in let final void #t220 = #t217{self::Class}.{self::Class::[]=}(#t218, #t219) in #t219;
-  let final self::Class? #t221 = c in #t221.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t222 = #t221{self::Class}.{self::Class::[]}(c{self::Class}) in #t222.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t223 = c{self::Class} in #t222{self::Class}.{self::Class::[]=}(#t223, #t222{self::Class}.{self::Class::[]}(#t223).{self::Class::+}(1));
-  c = let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = #t224{self::Class}.{self::Class::[]}(c{self::Class}) in #t225.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t226 = c{self::Class} in let final self::Class? #t227 = #t225{self::Class}.{self::Class::[]}(#t226) in let final void #t228 = #t225{self::Class}.{self::Class::[]=}(#t226, #t227.{self::Class::+}(1)) in #t227;
-  let final self::Class? #t229 = c in #t229.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t230 = #t229{self::Class}.{self::Class::[]}(c{self::Class}) in #t230.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t231 = c{self::Class} in let final self::Class? #t232 = #t230{self::Class}.{self::Class::[]}(#t231).{self::Class::+}(1) in let final void #t233 = #t230{self::Class}.{self::Class::[]=}(#t231, #t232) in #t232;
-  c = let final self::Class? #t234 = c in #t234.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t235 = #t234{self::Class}.{self::Class::[]}(c{self::Class}) in #t235.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t236 = c{self::Class} in let final self::Class? #t237 = #t235{self::Class}.{self::Class::[]}(#t236).{self::Class::+}(1) in let final void #t238 = #t235{self::Class}.{self::Class::[]=}(#t236, #t237) in #t237;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : #t82{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : #t83{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = #t84{self::Class1}.{self::Class1::[]}(nullable1) in #t85.{core::Object::==}(null) ?{self::Class1?} null : #t85{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t86 = n1 in #t86.{core::Object::==}(null) ?{self::Class1?} null : #t86{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : #t87{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = #t88{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t90 = nullable1 in let final self::Class1 #t91 = new self::Class1::•() in let final void #t92 = #t89.{self::Class1::[]=}(#t90, #t91) in #t91;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t94 = #t93{self::Class1}.{self::Class1::nonNullable1}.{self::Class1::[]}(nullable1) in #t94.{core::Object::==}(null) ?{self::Class1?} null : #t94{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t96 = #t95{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t97 = nullable2 in #t96.{self::Class2::[]=}(#t97, #t96.{self::Class2::[]}(#t97).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t98 = n1 in #t98.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t99 = #t98{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t100 = nullable2 in let final self::Class2 #t101 = #t99.{self::Class2::[]}(#t100).{self::Class2::+}(0) in let final void #t102 = #t99.{self::Class2::[]=}(#t100, #t101) in #t101;
+  let final self::Class1? #t103 = n1 in #t103.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t104 = nullable1 in #t103{self::Class1}.{self::Class1::[]}(#t104).{core::Object::==}(null) ?{self::Class1?} #t103{self::Class1}.{self::Class1::[]=}(#t104, nullable1) : null;
+  nullable1 = let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t106 = nullable1 in let final self::Class1? #t107 = #t105{self::Class1}.{self::Class1::[]}(#t106) in #t107.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t108 = nullable1 in let final void #t109 = #t105{self::Class1}.{self::Class1::[]=}(#t106, #t108) in #t108 : #t107{self::Class1};
+  let final self::Class2? #t110 = n2 in #t110.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t111 = nullable2 in #t110{self::Class2}.{self::Class2::[]=}(#t111, #t110{self::Class2}.{self::Class2::[]}(#t111).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t112 = n2 in #t112.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t113 = nullable2 in let final self::Class2 #t114 = #t112{self::Class2}.{self::Class2::[]}(#t113).{self::Class2::+}(0) in let final void #t115 = #t112{self::Class2}.{self::Class2::[]=}(#t113, #t114) in #t114;
+  let final self::Class2? #t116 = n2 in #t116.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t117 = nullable2 in #t116{self::Class2}.{self::Class2::[]=}(#t117, #t116{self::Class2}.{self::Class2::[]}(#t117).{self::Class2::+}(0));
+  nullable2 = let final self::Class2? #t118 = n2 in #t118.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t119 = nullable2 in let final self::Class2 #t120 = #t118{self::Class2}.{self::Class2::[]}(#t119).{self::Class2::+}(0) in let final void #t121 = #t118{self::Class2}.{self::Class2::[]=}(#t119, #t120) in #t120;
+  let final self::Class2? #t122 = n2 in #t122.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t123 = nullable2 in #t122{self::Class2}.{self::Class2::[]=}(#t123, #t122{self::Class2}.{self::Class2::[]}(#t123).{self::Class2::+}(1));
+  nullable2 = let final self::Class2? #t124 = n2 in #t124.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t125 = nullable2 in let final self::Class2 #t126 = #t124{self::Class2}.{self::Class2::[]}(#t125) in let final void #t127 = #t124{self::Class2}.{self::Class2::[]=}(#t125, #t126.{self::Class2::+}(1)) in #t126;
+  let final self::Class2? #t128 = n2 in #t128.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t129 = nullable2 in let final self::Class2 #t130 = #t128{self::Class2}.{self::Class2::[]}(#t129).{self::Class2::+}(1) in let final void #t131 = #t128{self::Class2}.{self::Class2::[]=}(#t129, #t130) in #t130;
+  nullable2 = let final self::Class2? #t132 = n2 in #t132.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t133 = nullable2 in let final self::Class2 #t134 = #t132{self::Class2}.{self::Class2::[]}(#t133).{self::Class2::+}(1) in let final void #t135 = #t132{self::Class2}.{self::Class2::[]=}(#t133, #t134) in #t134;
+  let final self::Class1? #t136 = n1 in #t136.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t137 = #t136{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t138 = nullable2 in #t137.{self::Class2::[]=}(#t138, #t137.{self::Class2::[]}(#t138).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t140 = #t139{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t141 = nullable2 in let final self::Class2 #t142 = #t140.{self::Class2::[]}(#t141) in let final void #t143 = #t140.{self::Class2::[]=}(#t141, #t142.{self::Class2::+}(1)) in #t142;
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t145 = #t144{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t146 = nullable2 in let final self::Class2 #t147 = #t145.{self::Class2::[]}(#t146).{self::Class2::+}(1) in let final void #t148 = #t145.{self::Class2::[]=}(#t146, #t147) in #t147;
+  nullable2 = let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t150 = #t149{self::Class1}.{self::Class1::nonNullable2} in let final self::Class2? #t151 = nullable2 in let final self::Class2 #t152 = #t150.{self::Class2::[]}(#t151).{self::Class2::+}(1) in let final void #t153 = #t150.{self::Class2::[]=}(#t151, #t152) in #t152;
+  let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class2?} null : #t154{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2);
+  let final self::Class1? #t155 = n1 in #t155.{core::Object::==}(null) ?{self::Class2?} null : #t155{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]=}(nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t157 = #t156{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t158 = nullable2 in let final self::Class2 #t159 = new self::Class2::•() in let final void #t160 = #t157.{self::Class2::[]=}(#t158, #t159) in #t159;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t162 = #t161{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2).{self::Class2::[]}(nullable2) in #t162.{core::Object::==}(null) ?{self::Class2?} null : #t162{self::Class2}.{self::Class2::nonNullable2Method}();
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t164 = #t163{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t165 = nullable2 in #t164.{self::Class2::[]=}(#t165, #t164.{self::Class2::[]}(#t165).{self::Class2::+}(0));
+  nullable2 = let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t167 = #t166{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t168 = nullable2 in let final self::Class2 #t169 = #t167.{self::Class2::[]}(#t168).{self::Class2::+}(0) in let final void #t170 = #t167.{self::Class2::[]=}(#t168, #t169) in #t169;
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t172 = #t171{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t173 = nullable2 in #t172.{self::Class2::[]=}(#t173, #t172.{self::Class2::[]}(#t173).{self::Class2::+}(1));
+  nullable2 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t175 = #t174{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t176 = nullable2 in let final self::Class2 #t177 = #t175.{self::Class2::[]}(#t176) in let final void #t178 = #t175.{self::Class2::[]=}(#t176, #t177.{self::Class2::+}(1)) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t180 = #t179{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t181 = nullable2 in let final self::Class2 #t182 = #t180.{self::Class2::[]}(#t181).{self::Class2::+}(1) in let final void #t183 = #t180.{self::Class2::[]=}(#t181, #t182) in #t182;
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = #t184{self::Class1}.{self::Class1::nonNullable2}.{self::Class2::[]}(nullable2) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = #t185.{self::Class2::[]}(#t186).{self::Class2::+}(1) in let final void #t188 = #t185.{self::Class2::[]=}(#t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = #t189{self::Class1}.{self::Class1::[]}(nullable1) in #t190.{core::Object::==}(null) ?{self::Class1?} null : #t190{self::Class1}.{self::Class1::[]}(nullable1);
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = #t191{self::Class1}.{self::Class1::[]}(nullable1) in #t192.{core::Object::==}(null) ?{self::Class1?} null : #t192{self::Class1}.{self::Class1::[]=}(nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = #t193{self::Class1}.{self::Class1::[]}(nullable1) in #t194.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t195 = nullable1 in let final self::Class1 #t196 = new self::Class1::•() in let final void #t197 = #t194{self::Class1}.{self::Class1::[]=}(#t195, #t196) in #t196;
+  let final self::Class1? #t198 = n1 in #t198.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t199 = #t198{self::Class1}.{self::Class1::[]}(nullable1) in #t199.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t200 = #t199{self::Class1}.{self::Class1::[]}(nullable1) in #t200.{core::Object::==}(null) ?{self::Class1?} null : #t200{self::Class1}.{self::Class1::nonNullable1Method}();
+  nullable1 = let final self::Class1? #t201 = n1 in #t201.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t202 = #t201{self::Class1}.{self::Class1::[]}(nullable1) in #t202.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t203 = #t202{self::Class1}.{self::Class1::[]}(nullable1) in #t203.{core::Object::==}(null) ?{self::Class1?} null : #t203{self::Class1}.{self::Class1::nonNullable1Method}();
+  let final self::Class1? #t204 = n1 in #t204.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t205 = #t204{self::Class1}.{self::Class1::[]}(nullable1) in #t205.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t206 = nullable1 in #t205{self::Class1}.{self::Class1::[]}(#t206).{core::Object::==}(null) ?{self::Class1?} #t205{self::Class1}.{self::Class1::[]=}(#t206, nullable1) : null;
+  nullable1 = let final self::Class1? #t207 = n1 in #t207.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t208 = #t207{self::Class1}.{self::Class1::[]}(nullable1) in #t208.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t209 = nullable1 in let final self::Class1? #t210 = #t208{self::Class1}.{self::Class1::[]}(#t209) in #t210.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t211 = nullable1 in let final void #t212 = #t208{self::Class1}.{self::Class1::[]=}(#t209, #t211) in #t211 : #t210{self::Class1};
+  let final self::Class3? #t213 = n3 in #t213.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t214 = #t213{self::Class3}.{self::Class3::[]}(nullable3) in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in #t214{self::Class2}.{self::Class2::[]=}(#t215, #t214{self::Class2}.{self::Class2::[]}(#t215).{self::Class2::+}(0));
+  nullable2 = let final self::Class3? #t216 = n3 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = #t216{self::Class3}.{self::Class3::[]}(nullable3) in #t217.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t218 = nullable2 in let final self::Class2 #t219 = #t217{self::Class2}.{self::Class2::[]}(#t218).{self::Class2::+}(0) in let final void #t220 = #t217{self::Class2}.{self::Class2::[]=}(#t218, #t219) in #t219;
+  let final self::Class3? #t221 = n3 in #t221.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t222 = #t221{self::Class3}.{self::Class3::[]}(nullable3) in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t223 = nullable2 in #t222{self::Class2}.{self::Class2::[]=}(#t223, #t222{self::Class2}.{self::Class2::[]}(#t223).{self::Class2::+}(1));
+  nullable2 = let final self::Class3? #t224 = n3 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t225 = #t224{self::Class3}.{self::Class3::[]}(nullable3) in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t226 = nullable2 in let final self::Class2 #t227 = #t225{self::Class2}.{self::Class2::[]}(#t226) in let final void #t228 = #t225{self::Class2}.{self::Class2::[]=}(#t226, #t227.{self::Class2::+}(1)) in #t227;
+  let final self::Class3? #t229 = n3 in #t229.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t230 = #t229{self::Class3}.{self::Class3::[]}(nullable3) in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t231 = nullable2 in let final self::Class2 #t232 = #t230{self::Class2}.{self::Class2::[]}(#t231).{self::Class2::+}(1) in let final void #t233 = #t230{self::Class2}.{self::Class2::[]=}(#t231, #t232) in #t232;
+  nullable2 = let final self::Class3? #t234 = n3 in #t234.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t235 = #t234{self::Class3}.{self::Class3::[]}(nullable3) in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t236 = nullable2 in let final self::Class2 #t237 = #t235{self::Class2}.{self::Class2::[]}(#t236).{self::Class2::+}(1) in let final void #t238 = #t235{self::Class2}.{self::Class2::[]=}(#t236, #t237) in #t237;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => (let final self::Class? #t239 = c in #t239.{core::Object::==}(null) ?{self::Class?} null : #t239{self::Class}.{self::Class::field}).{self::Class::+}(0));
-  self::throws(() → self::Class? => (let final self::Class? #t240 = c in #t240.{core::Object::==}(null) ?{self::Class?} null : #t240{self::Class}.{self::Class::field}).{self::Class::unary-}());
-  let final self::Class? #t241 = c in #t241.{core::Object::==}(null) ?{self::Class?} null : #t241.{self::Class::field} = #t241.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t243 = #t242.{self::Class::field}.{self::Class::+}(0) in let final void #t244 = #t242.{self::Class::field} = #t243 in #t243;
-  let final self::Class? #t245 = c in #t245.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t246 = #t245{self::Class}.{self::Class::property} in #t246.{self::Class::field} = #t246.{self::Class::field}.{self::Class::+}(0);
-  c = let final self::Class? #t247 = c in #t247.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t248 = #t247{self::Class}.{self::Class::property} in #t248.{self::Class::field} = #t248.{self::Class::field}.{self::Class::+}(0);
-  let final self::Class? #t249 = c in #t249.{core::Object::==}(null) ?{self::Class?} null : #t249.{self::Class::field} = #t249.{self::Class::field}.{self::Class::+}(1);
-  c = let final self::Class? #t250 = c in #t250.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t251 = #t250.{self::Class::field} in let final void #t252 = #t250.{self::Class::field} = #t251.{self::Class::+}(1) in #t251;
-  let final self::Class? #t253 = c in #t253.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t254 = #t253.{self::Class::field}.{self::Class::+}(1) in let final void #t255 = #t253.{self::Class::field} = #t254 in #t254;
-  c = let final self::Class? #t256 = c in #t256.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t257 = #t256.{self::Class::field}.{self::Class::+}(1) in let final void #t258 = #t256.{self::Class::field} = #t257 in #t257;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => (let final self::Class1? #t239 = n1 in #t239.{core::Object::==}(null) ?{self::Class1?} null : #t239{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::+}(0));
+  self::throws(() → self::Class1? => (let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class1?} null : #t240{self::Class1}.{self::Class1::nonNullable1}).{self::Class1::unary-}());
+  let final self::Class2? #t241 = n2 in #t241.{core::Object::==}(null) ?{self::Class2?} null : #t241.{self::Class2::nonNullable2} = #t241.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t242 = n2 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = #t242.{self::Class2::nonNullable2}.{self::Class2::+}(0) in let final void #t244 = #t242.{self::Class2::nonNullable2} = #t243 in #t243;
+  let final self::Class2? #t245 = n2 in #t245.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t246 = #t245{self::Class2}.{self::Class2::nonNullable2} in #t246.{self::Class2::nonNullable2} = #t246.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  nullable2 = let final self::Class2? #t247 = n2 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t248 = #t247{self::Class2}.{self::Class2::nonNullable2} in #t248.{self::Class2::nonNullable2} = #t248.{self::Class2::nonNullable2}.{self::Class2::+}(0);
+  let final self::Class2? #t249 = n2 in #t249.{core::Object::==}(null) ?{self::Class2?} null : #t249.{self::Class2::nonNullable2} = #t249.{self::Class2::nonNullable2}.{self::Class2::+}(1);
+  nullable2 = let final self::Class2? #t250 = n2 in #t250.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t251 = #t250.{self::Class2::nonNullable2} in let final void #t252 = #t250.{self::Class2::nonNullable2} = #t251.{self::Class2::+}(1) in #t251;
+  let final self::Class2? #t253 = n2 in #t253.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t254 = #t253.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t255 = #t253.{self::Class2::nonNullable2} = #t254 in #t254;
+  nullable2 = let final self::Class2? #t256 = n2 in #t256.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t257 = #t256.{self::Class2::nonNullable2}.{self::Class2::+}(1) in let final void #t258 = #t256.{self::Class2::nonNullable2} = #t257 in #t257;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class} null : #t259.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t259.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class? #t260 = c in #t260.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t261 = #t260.{self::Class::field} in #t261.{core::Object::==}(null) ?{self::Class} #t260.{self::Class::field} = c{self::Class} : #t261{self::Class};
-  let final self::Class #t262 = c{self::Class} in #t262.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t263 = #t262.{self::Class::property} in #t263.{self::Class::field}.{core::Object::==}(null) ?{self::Class} #t263.{self::Class::field} = c{self::Class} : null;
-  c = let final self::Class #t264 = c{self::Class} in #t264.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t265 = #t264.{self::Class::property} in let final self::Class? #t266 = #t265.{self::Class::field} in #t266.{core::Object::==}(null) ?{self::Class} #t265.{self::Class::field} = c{self::Class} : #t266{self::Class};
-  let final self::Class #t267 = c{self::Class} in #t267.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t268 = #t267.{self::Class::field} in let final self::Class #t269 = c{self::Class} in #t268.{self::Class::[]}(#t269).{core::Object::==}(null) ?{self::Class} #t268.{self::Class::[]=}(#t269, c{self::Class}) : null;
-  c = let final self::Class #t270 = c{self::Class} in #t270.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t271 = #t270.{self::Class::field} in let final self::Class #t272 = c{self::Class} in let final self::Class? #t273 = #t271.{self::Class::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class} let final self::Class #t274 = c{self::Class} in let final void #t275 = #t271.{self::Class::[]=}(#t272, #t274) in #t274 : #t273{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class1?} null : #t259.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t259.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t261 = #t260.{self::Class1::nullable1} in #t261.{core::Object::==}(null) ?{self::Class1} #t260.{self::Class1::nullable1} = n1{self::Class1} : #t261{self::Class1};
+  let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t263 = #t262{self::Class1}.{self::Class1::nonNullable1} in #t263{self::Class1}.{self::Class1::nullable1}.{core::Object::==}(null) ?{self::Class1} #t263{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : null;
+  n1 = let final self::Class1? #t264 = n1 in #t264.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t265 = #t264{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1? #t266 = #t265{self::Class1}.{self::Class1::nullable1} in #t266.{core::Object::==}(null) ?{self::Class1} #t265{self::Class1}.{self::Class1::nullable1} = n1{self::Class1} : #t266{self::Class1};
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t268 = #t267{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t269 = n1{self::Class1} in #t268.{self::Class1::[]}(#t269).{core::Object::==}(null) ?{self::Class1} #t268.{self::Class1::[]=}(#t269, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t271 = #t270{self::Class1}.{self::Class1::nonNullable1} in let final self::Class1 #t272 = n1{self::Class1} in let final self::Class1? #t273 = #t271.{self::Class1::[]}(#t272) in #t273.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t274 = n1{self::Class1} in let final void #t275 = #t271.{self::Class1::[]=}(#t272, #t274) in #t274 : #t273{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
index 96ba0fa..aba8676 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart
@@ -2,198 +2,274 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-class Class {
-  Class? _field;
+class Class1 {
+  Class1? get property => null;
+
+  void set property(Class1? value) {}
+
+  Class1 get property1 => new Class1();
+
+  Class2 get property2 => new Class2();
 }
 
-extension Extension on Class {
-  Class? get field => _field;
-  void set field(Class? value) {
-    _field = value;
+extension Extension1 on Class1 {
+  Class1? get nullable1 => property1;
+
+  void set nullable1(Class1? value) {
+    property = value;
   }
 
-  Class method() => property;
+  Class1 nonNullable1Method() => nonNullable1;
 
-  Class? operator [](Class? key) => field;
-  void operator []=(Class? key, Class? value) {
-    field = value;
+  Class1? operator [](Class1? key) => nullable1;
+
+  void operator []=(Class1? key, Class1? value) {
+    property = value;
   }
 
-  Class? operator +(int value) => field;
+  Class1? operator +(int value) => nullable1;
 
-  Class? operator -() => field;
+  Class1? operator -() => nullable1;
 
-  Class get property => this;
+  Class1 get nonNullable1 => property1;
+
+  Class2 get nonNullable2 => property2;
+}
+
+class Class2 {
+  Class2 get property => this;
+
+  void set property(Class2 value) {}
+}
+
+extension Extension2 on Class2 {
+  Class2 nonNullable2Method() => nonNullable2;
+
+  Class2 operator [](Class2? key) => property;
+
+  void operator []=(Class2? key, Class2? value) => property;
+
+  Class2 operator +(int value) => property;
+
+  Class2 operator -() => property;
+
+  Class2 get nonNullable2 => property;
+
+  void set nonNullable2(Class2 value) {
+    property = value;
+  }
+}
+
+class Class3 {
+  Class2? get property => null;
+}
+
+extension Extension3 on Class3 {
+  Class2? operator [](Class3? key) => property;
 }
 
 main() {
   propertyAccess(null);
-  indexAccess(null);
-  operatorAccess(null);
+  indexAccess(null, null, null);
+  operatorAccess(null, null);
   ifNull(null);
 }
 
-void propertyAccess(Class? c) {
-  Extension(c)?.field;
-  Extension(c)?.field = new Class();
-  c = Extension(c)?.field = new Class();
-  Extension(c)?.method();
+void propertyAccess(Class1? n1) {
+  Class1? nullable1 = n1;
 
-  Extension(c)?.property.field;
-  Extension(c)?.field?.field;
-  Extension(c)?.property.field?.field;
-  Extension(c)?.property.field = new Class();
-  Extension(c)?.field?.field = new Class();
-  Extension(c)?.property.field?.field = new Class();
-  (Extension(c)?.field)?.field;
-  throws(() => (Extension(c)?.field = new Class()).field);
-  throws(() => (Extension(c)?.method()).field);
-  c = Extension(c)?.property.field = new Class();
-  c = Extension(c)?.field?.field = new Class();
-  c = Extension(c)?.property.field?.field = new Class();
-  Extension(c)?.field?.method();
-  Extension(c)?.field = new Class().field;
-  c = Extension(c)?.field = new Class().field;
-  Extension(c)?.field = new Class().field = new Class();
-  c = Extension(c)?.field = new Class().field = new Class();
-  Extension(c)?.field = new Class().method();
-  c = Extension(c)?.field = new Class().method();
-  Extension(c)?.method().field;
-  Extension(c)?.method().field = new Class();
-  Extension(c)?.method().method();
+  Extension1(n1)?.nullable1;
+  Extension1(n1)?.nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1Method();
 
-  Extension(c)?.property.property.field;
-  Extension(c)?.property.property.field = new Class();
-  c = Extension(c)?.property.property.field = new Class();
-  Extension(c)?.property.property.method();
-  Extension(c)?.field = new Class().property.field;
-  c = Extension(c)?.field = new Class().property.field;
-  Extension(c)?.field = new Class().property.field = new Class();
-  c = Extension(c)?.field = new Class().property.field = new Class();
-  Extension(c)?.field = new Class().property.method();
-  c = Extension(c)?.field = new Class().property.method();
-  Extension(c)?.method().property.field;
-  Extension(c)?.method().property.field = new Class();
-  Extension(c)?.method().field?.method();
+  Extension1(n1)?.nonNullable1.nullable1;
+  Extension1(n1)?.nullable1?.nullable1;
+  Extension1(n1)?.nonNullable1.nullable1?.nullable1;
+  Extension1(n1)?.nonNullable1.nullable1 = new Class1();
+  Extension1(n1)?.nullable1?.nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1.nullable1?.nullable1 = new Class1();
+  (Extension1(n1)?.nullable1)?.nullable1;
+  throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+  throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+  nullable1 = Extension1(n1)?.nonNullable1.nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1?.nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nonNullable1.nullable1?.nullable1 = new Class1();
+  Extension1(n1)?.nullable1?.nonNullable1Method();
+  Extension1(n1)?.nullable1 = new Class1().nullable1;
+  nullable1 = Extension1(n1)?.nullable1 = new Class1().nullable1;
+  Extension1(n1)?.nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1 = new Class1().nullable1 = new Class1();
+  Extension1(n1)?.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = Extension1(n1)?.nullable1 = new Class1().nonNullable1Method();
+  Extension1(n1)?.nonNullable1Method().nullable1;
+  Extension1(n1)?.nonNullable1Method().nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1Method().nonNullable1Method();
 
-  Extension(c)?.property.field = new Class().field;
-  c = Extension(c)?.property.field = new Class().field;
-  Extension(c)?.property.field = new Class().field = new Class();
-  c = Extension(c)?.property.field = new Class().field = new Class();
-  Extension(c)?.property.field = new Class().method();
-  c = Extension(c)?.property.field = new Class().method();
-  Extension(c)?.field = new Class().field = new Class().field;
-  c = Extension(c)?.field = new Class().field = new Class().field;
-  Extension(c)?.field = new Class().field = new Class().field = new Class();
-  c = Extension(c)?.field = new Class().field = new Class().field = new Class();
-  Extension(c)?.field = new Class().field = new Class().method();
-  c = Extension(c)?.field = new Class().field = new Class().method();
-  Extension(c)?.method().field = new Class().field;
-  c = Extension(c)?.method().field = new Class().field;
-  Extension(c)?.method().field = new Class().field = new Class();
-  c = Extension(c)?.method().field = new Class().field = new Class();
-  Extension(c)?.method().field = new Class().method();
-  c = Extension(c)?.method().field = new Class().method();
+  Extension1(n1)?.nonNullable1.nonNullable1.nullable1;
+  Extension1(n1)?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  nullable1 =
+      Extension1(n1)?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1.nullable1?.nonNullable1Method();
+  Extension1(n1)?.nullable1 = new Class1().nonNullable1.nullable1;
+  nullable1 = Extension1(n1)?.nullable1 = new Class1().nonNullable1.nullable1;
+  Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1.nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1.nullable1 = new Class1();
+  Extension1(n1)?.nullable1 = new Class1().nonNullable1.nonNullable1Method();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1.nonNullable1Method();
+  Extension1(n1)?.nonNullable1Method().nonNullable1.nullable1;
+  Extension1(n1)?.nonNullable1Method().nonNullable1.nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1Method().nonNullable1.nonNullable1Method();
 
-  Extension(c)?.property.method().field;
-  Extension(c)?.property.method().field = new Class();
-  c = Extension(c)?.property.method().field = new Class();
-  Extension(c)?.property.method().method();
-  Extension(c)?.field = new Class().method().field;
-  c = Extension(c)?.field = new Class().method().field;
-  Extension(c)?.field = new Class().method().field = new Class();
-  c = Extension(c)?.field = new Class().method().field = new Class();
-  Extension(c)?.field = new Class().method().method();
-  c = Extension(c)?.field = new Class().method().method();
-  Extension(c)?.method().method().field;
-  Extension(c)?.method().method().field = new Class();
-  Extension(c)?.method().method().method();
+  Extension1(n1)?.nonNullable1.nullable1 = new Class1().nullable1;
+  nullable1 = Extension1(n1)?.nonNullable1.nullable1 = new Class1().nullable1;
+  Extension1(n1)?.nonNullable1.nullable1 =
+      new Class1().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nonNullable1.nullable1 =
+      new Class1().nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = Extension1(n1)?.nonNullable1.nullable1 =
+      new Class1().nonNullable1Method();
+  Extension1(n1)?.nullable1 = new Class1().nullable1 = new Class1().nullable1;
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1;
+  Extension1(n1)?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  Extension1(n1)?.nullable1 =
+      new Class1().nullable1 = new Class1().nonNullable1Method();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nullable1 = new Class1().nonNullable1Method();
+  Extension1(n1)?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  nullable1 =
+      Extension1(n1)?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  Extension1(n1)?.nonNullable1Method().nullable1 =
+      new Class1().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nonNullable1Method().nullable1 =
+      new Class1().nullable1 = new Class1();
+  Extension1(n1)?.nonNullable1Method().nullable1 =
+      new Class1().nonNullable1Method();
+  nullable1 = Extension1(n1)?.nonNullable1Method().nullable1 =
+      new Class1().nonNullable1Method();
 
-  Extension(c)?.method()?.method();
+  Extension1(n1)?.nonNullable1.nonNullable1Method().nullable1;
+  Extension1(n1)?.nonNullable1.nonNullable1Method().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nonNullable1.nonNullable1Method().nullable1 =
+      new Class1();
+  Extension1(n1)?.nonNullable1.nonNullable1Method().nonNullable1Method();
+  Extension1(n1)?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  nullable1 =
+      Extension1(n1)?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1Method().nullable1 = new Class1();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1Method().nullable1 = new Class1();
+  Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1Method().nonNullable1Method();
+  nullable1 = Extension1(n1)?.nullable1 =
+      new Class1().nonNullable1Method().nonNullable1Method();
+  Extension1(n1)?.nonNullable1Method().nonNullable1Method().nullable1;
+  Extension1(n1)?.nonNullable1Method().nonNullable1Method().nullable1 =
+      new Class1();
+  Extension1(n1)
+      ?.nonNullable1Method()
+      .nonNullable1Method()
+      .nonNullable1Method();
 
-  (Extension(c?.field)?.field)?.field;
-  Extension(c?.field)?.field;
+  Extension1(n1)?.nonNullable1Method()?.nonNullable1Method();
 }
 
-void indexAccess(Class? c) {
-  Extension(c)?.[c];
-  Extension(c)?.[c] = new Class();
-  Extension(c)?.[c]?.method();
-  Extension(c)?.field[c];
-  Extension(c)?.field[c] = new Class();
-  c = Extension(c)?.field[c] = new Class();
-  Extension(c)?.field[c]?.method();
-  Extension(c)?.field[c] += 0;
-  c = Extension(c)?.field[c] += 0;
-  Extension(c)?.[c] ??= c;
-  c = Extension(c)?.[c] ??= c;
-  Extension(c)?.[c] += 0;
-  c = Extension(c)?.[c] += 0;
-  Extension(c)?.[c] += 0;
-  c = Extension(c)?.[c] += 0;
-  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
-  // update.
-  Extension(c)?.[c]++;
-  c = Extension(c)?.[c]++;
-  Extension(c)?.[c];
-  c = ++Extension(c)?.[c];
-  Extension(c)?.field[c]++;
-  c = Extension(c)?.field[c]++;
-  ++Extension(c)?.field[c];
-  c = ++Extension(c)?.field[c];
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {
+  Class1? nullable1 = n1;
+  Class2? nullable2 = n2;
+  Class3? nullable3 = n3;
 
-  Extension(c)?.field[c][c];
-  Extension(c)?.field[c][c] = new Class();
-  c = Extension(c)?.field[c][c] = new Class();
-  Extension(c)?.field[c][c]?.method();
-  Extension(c)?.field[c][c] += 0;
-  c = Extension(c)?.field[c][c] += 0;
+  Extension1(n1)?.[nullable1];
+  Extension1(n1)?.[nullable1] = new Class1();
+  Extension1(n1)?.[nullable1]?.nonNullable1Method();
+  Extension1(n1)?.nonNullable1[nullable1];
+  Extension1(n1)?.nonNullable1[nullable1] = new Class1();
+  nullable1 = Extension1(n1)?.nonNullable1[nullable1] = new Class1();
+  Extension1(n1)?.nonNullable1[nullable1]?.nonNullable1Method();
+  Extension1(n1)?.nonNullable2[nullable2] += 0;
+  nullable2 = Extension1(n1)?.nonNullable2[nullable2] += 0;
+  Extension1(n1)?.[nullable1] ??= nullable1;
+  nullable1 = Extension1(n1)?.[nullable1] ??= nullable1;
+  Extension2(n2)?.[nullable2] += 0;
+  nullable2 = Extension2(n2)?.[nullable2] += 0;
+  Extension2(n2)?.[nullable2] += 0;
+  nullable2 = Extension2(n2)?.[nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  Extension(c)?.field[c][c]++;
-  c = Extension(c)?.field[c][c]++;
-  ++Extension(c)?.field[c][c];
-  c = ++Extension(c)?.field[c][c];
+  Extension2(n2)?.[nullable2]++;
+  nullable2 = Extension2(n2)?.[nullable2]++;
+  ++Extension2(n2)?.[nullable2];
+  nullable2 = ++Extension2(n2)?.[nullable2];
+  Extension1(n1)?.nonNullable2[nullable2]++;
+  nullable2 = Extension1(n1)?.nonNullable2[nullable2]++;
+  ++Extension1(n1)?.nonNullable2[nullable2];
+  nullable2 = ++Extension1(n1)?.nonNullable2[nullable2];
 
-  Extension(c)?.[c]?.[c];
-  Extension(c)?.[c]?.[c] = new Class();
-  c = Extension(c)?.[c]?.[c] = new Class();
-  Extension(c)?.[c]?.[c]?.method();
-  c = Extension(c)?.[c]?.[c]?.method();
-  Extension(c)?.[c]?.[c] ??= c;
-  c = Extension(c)?.[c]?.[c] ??= c;
-  Extension(c)?.[c]?.[c] += 0;
-  c = Extension(c)?.[c]?.[c] += 0;
+  Extension1(n1)?.nonNullable2[nullable2][nullable2];
+  Extension1(n1)?.nonNullable2[nullable2][nullable2] = new Class2();
+  nullable2 = Extension1(n1)?.nonNullable2[nullable2][nullable2] = new Class2();
+  Extension1(n1)?.nonNullable2[nullable2][nullable2]?.nonNullable2Method();
+  Extension1(n1)?.nonNullable2[nullable2][nullable2] += 0;
+  nullable2 = Extension1(n1)?.nonNullable2[nullable2][nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  Extension(c)?.[c]?.[c]++;
-  c = Extension(c)?.[c]?.[c]++;
-  ++Extension(c)?.[c]?.[c];
-  c = ++Extension(c)?.[c]?.[c];
-}
+  Extension1(n1)?.nonNullable2[nullable2][nullable2]++;
+  nullable2 = Extension1(n1)?.nonNullable2[nullable2][nullable2]++;
+  ++Extension1(n1)?.nonNullable2[nullable2][nullable2];
+  nullable2 = ++Extension1(n1)?.nonNullable2[nullable2][nullable2];
 
-void operatorAccess(Class? c) {
-  throws(() => Extension(c)?.field + 0);
-  throws(() => -Extension(c)?.field);
-  Extension(c)?.field += 0;
-  c = Extension(c)?.field += 0;
-  Extension(c)?.property.field += 0;
-  c = Extension(c)?.property.field += 0;
+  Extension1(n1)?.[nullable1]?.[nullable1];
+  Extension1(n1)?.[nullable1]?.[nullable1] = new Class1();
+  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1] = new Class1();
+  Extension1(n1)?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  Extension1(n1)?.[nullable1]?.[nullable1] ??= nullable1;
+  nullable1 = Extension1(n1)?.[nullable1]?.[nullable1] ??= nullable1;
+  Extension3(n3)?.[nullable3]?.[nullable2] += 0;
+  nullable2 = Extension3(n3)?.[nullable3]?.[nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
-  // update.
-  Extension(c)?.field++;
-  c = Extension(c)?.field++;
-  ++Extension(c)?.field;
-  c = ++Extension(c)?.field;
+  //  update.
+  Extension3(n3)?.[nullable3]?.[nullable2]++;
+  nullable2 = Extension3(n3)?.[nullable3]?.[nullable2]++;
+  ++Extension3(n3)?.[nullable3]?.[nullable2];
+  nullable2 = ++Extension3(n3)?.[nullable3]?.[nullable2];
 }
 
-void ifNull(Class? c) {
-  Extension(c)?.field ??= c;
-  c = Extension(c)?.field ??= c;
-  Extension(c)?.property.field ??= c;
-  c = Extension(c)?.property.field ??= c;
-  Extension(c)?.field[c] ??= c;
-  c = Extension(c)?.field[c] ??= c;
+void operatorAccess(Class1? n1, Class2? n2) {
+  Class2? nullable2 = n2;
+
+  throws(() => Extension1(n1)?.nonNullable1 + 0);
+  throws(() => -Extension1(n1)?.nonNullable1);
+  Extension2(n2)?.nonNullable2 += 0;
+  nullable2 = Extension2(n2)?.nonNullable2 += 0;
+  Extension2(n2)?.nonNullable2.nonNullable2 += 0;
+  nullable2 = Extension2(n2)?.nonNullable2.nonNullable2 += 0;
+  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
+  //  update.
+  Extension2(n2)?.nonNullable2++;
+  nullable2 = Extension2(n2)?.nonNullable2++;
+  ++Extension2(n2)?.nonNullable2;
+  nullable2 = ++Extension2(n2)?.nonNullable2;
+}
+
+void ifNull(Class1? n1) {
+  Class1? nullable1 = n1;
+
+  n1?.nullable1 ??= n1;
+  n1 = n1?.nullable1 ??= n1;
+  n1?.nonNullable1.nullable1 ??= n1;
+  n1 = n1?.nonNullable1.nullable1 ??= n1;
+  n1?.nonNullable1[n1] ??= n1;
+  n1 = n1?.nonNullable1[n1] ??= n1;
 }
 
 void throws(void Function() f) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
index a880ff1..32edac1 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect
@@ -2,49 +2,104 @@
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    ;
+  get property() → self::Class1?
+    ;
+  set property(self::Class1? value) → void
+    ;
+  get property1() → self::Class1
+    ;
+  get property2() → self::Class2
     ;
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    ;
+  get property() → self::Class2
+    ;
+  set property(self::Class2 value) → void
+    ;
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    ;
+  get property() → self::Class2?
+    ;
+}
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
+}
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
   ;
-static method Extension|set#field(final self::Class #this, self::Class? value) → void
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void
   ;
-static method Extension|method(final self::Class #this) → self::Class
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
   ;
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
   ;
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void
   ;
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
   ;
-static method Extension|unary-(final self::Class #this) → self::Class?
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
   ;
-static method Extension|get#property(final self::Class #this) → self::Class
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  ;
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  ;
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  ;
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  ;
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  ;
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void
+  ;
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
   ;
 static method main() → dynamic
   ;
-static method propertyAccess(self::Class? c) → void
+static method propertyAccess(self::Class1? n1) → void
   ;
-static method indexAccess(self::Class? c) → void
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void
   ;
-static method operatorAccess(self::Class? c) → void
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void
   ;
-static method ifNull(self::Class? c) → void
+static method ifNull(self::Class1? n1) → void
   ;
 static method throws(() → void f) → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
index 7ce7211..7bd0924 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect
@@ -1,192 +1,291 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+//                                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+//                                                       ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => Extension1(n1)?.nonNullable1 + 0);
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => -Extension1(n1)?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t35 = self::Extension|get#field(#t34) in #t35.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t35{self::Class});
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t36, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t38 = self::Extension|get#field(new self::Class::•()) in let final void #t39 = self::Extension|set#field(#t37, #t38) in #t38;
-  let final self::Class? #t40 = c in #t40.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t40{self::Class}, let final self::Class #t41 = new self::Class::•() in let final void #t42 = self::Extension|set#field(new self::Class::•(), #t41) in #t41);
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t44 = let final self::Class #t45 = new self::Class::•() in let final void #t46 = self::Extension|set#field(new self::Class::•(), #t45) in #t45 in let final void #t47 = self::Extension|set#field(#t43{self::Class}, #t44) in #t44;
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t48, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t50 = self::Extension|method(new self::Class::•()) in let final void #t51 = self::Extension|set#field(#t49, #t50) in #t50;
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t52));
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t53), new self::Class::•());
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t54));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t55)));
-  let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), new self::Class::•());
-  c = let final self::Class #t57 = c{self::Class} in #t57.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t58 = new self::Class::•() in let final void #t59 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t57)), #t58) in #t58;
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t60)));
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t61, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t63 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t64 = self::Extension|set#field(#t62, #t63) in #t63;
-  let final self::Class? #t65 = c in #t65.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t65{self::Class}, let final self::Class #t66 = new self::Class::•() in let final void #t67 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t66) in #t66);
-  c = let final self::Class? #t68 = c in #t68.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t69 = let final self::Class #t70 = new self::Class::•() in let final void #t71 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t70) in #t70 in let final void #t72 = self::Extension|set#field(#t68{self::Class}, #t69) in #t69;
-  let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t73, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t74 = c{self::Class} in #t74.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t75 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t76 = self::Extension|set#field(#t74, #t75) in #t75;
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t77)));
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t78)), new self::Class::•());
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t80 = self::Extension|get#field(self::Extension|method(#t79)) in #t80.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t80{self::Class});
-  let final self::Class #t81 = c{self::Class} in #t81.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t81), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t82 = c{self::Class} in #t82.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t83 = self::Extension|get#field(new self::Class::•()) in let final void #t84 = self::Extension|set#field(self::Extension|get#property(#t82), #t83) in #t83;
-  let final self::Class? #t85 = c in #t85.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t85{self::Class}), let final self::Class #t86 = new self::Class::•() in let final void #t87 = self::Extension|set#field(new self::Class::•(), #t86) in #t86);
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t89 = let final self::Class #t90 = new self::Class::•() in let final void #t91 = self::Extension|set#field(new self::Class::•(), #t90) in #t90 in let final void #t92 = self::Extension|set#field(self::Extension|get#property(#t88{self::Class}), #t89) in #t89;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t93), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t94 = c{self::Class} in #t94.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t95 = self::Extension|method(new self::Class::•()) in let final void #t96 = self::Extension|set#field(self::Extension|get#property(#t94), #t95) in #t95;
-  let final self::Class #t97 = c{self::Class} in #t97.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t97, let final self::Class? #t98 = self::Extension|get#field(new self::Class::•()) in let final void #t99 = self::Extension|set#field(new self::Class::•(), #t98) in #t98);
-  c = let final self::Class #t100 = c{self::Class} in #t100.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t101 = let final self::Class? #t102 = self::Extension|get#field(new self::Class::•()) in let final void #t103 = self::Extension|set#field(new self::Class::•(), #t102) in #t102 in let final void #t104 = self::Extension|set#field(#t100, #t101) in #t101;
-  let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t105{self::Class}, let final self::Class #t106 = let final self::Class #t107 = new self::Class::•() in let final void #t108 = self::Extension|set#field(new self::Class::•(), #t107) in #t107 in let final void #t109 = self::Extension|set#field(new self::Class::•(), #t106) in #t106);
-  c = let final self::Class? #t110 = c in #t110.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t111 = let final self::Class #t112 = let final self::Class #t113 = new self::Class::•() in let final void #t114 = self::Extension|set#field(new self::Class::•(), #t113) in #t113 in let final void #t115 = self::Extension|set#field(new self::Class::•(), #t112) in #t112 in let final void #t116 = self::Extension|set#field(#t110{self::Class}, #t111) in #t111;
-  let final self::Class #t117 = c{self::Class} in #t117.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t117, let final self::Class #t118 = self::Extension|method(new self::Class::•()) in let final void #t119 = self::Extension|set#field(new self::Class::•(), #t118) in #t118);
-  c = let final self::Class #t120 = c{self::Class} in #t120.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t121 = let final self::Class #t122 = self::Extension|method(new self::Class::•()) in let final void #t123 = self::Extension|set#field(new self::Class::•(), #t122) in #t122 in let final void #t124 = self::Extension|set#field(#t120, #t121) in #t121;
-  let final self::Class #t125 = c{self::Class} in #t125.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t125), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t126 = c{self::Class} in #t126.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t127 = self::Extension|get#field(new self::Class::•()) in let final void #t128 = self::Extension|set#field(self::Extension|method(#t126), #t127) in #t127;
-  let final self::Class? #t129 = c in #t129.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t129{self::Class}), let final self::Class #t130 = new self::Class::•() in let final void #t131 = self::Extension|set#field(new self::Class::•(), #t130) in #t130);
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t133 = let final self::Class #t134 = new self::Class::•() in let final void #t135 = self::Extension|set#field(new self::Class::•(), #t134) in #t134 in let final void #t136 = self::Extension|set#field(self::Extension|method(#t132{self::Class}), #t133) in #t133;
-  let final self::Class #t137 = c{self::Class} in #t137.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t137), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t138 = c{self::Class} in #t138.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t139 = self::Extension|method(new self::Class::•()) in let final void #t140 = self::Extension|set#field(self::Extension|method(#t138), #t139) in #t139;
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|get#property(#t141)));
-  let final self::Class #t142 = c{self::Class} in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t142)), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t144 = new self::Class::•() in let final void #t145 = self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t143)), #t144) in #t144;
-  let final self::Class #t146 = c{self::Class} in #t146.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|get#property(#t146)));
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t147, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t148 = c{self::Class} in #t148.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t149 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t150 = self::Extension|set#field(#t148, #t149) in #t149;
-  let final self::Class? #t151 = c in #t151.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t151{self::Class}, let final self::Class #t152 = new self::Class::•() in let final void #t153 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t152) in #t152);
-  c = let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t155 = let final self::Class #t156 = new self::Class::•() in let final void #t157 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t156) in #t156 in let final void #t158 = self::Extension|set#field(#t154{self::Class}, #t155) in #t155;
-  let final self::Class #t159 = c{self::Class} in #t159.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t159, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t160 = c{self::Class} in #t160.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t161 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t162 = self::Extension|set#field(#t160, #t161) in #t161;
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t163)));
-  let final self::Class #t164 = c{self::Class} in #t164.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t164)), new self::Class::•());
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t167 = self::Extension|method(#t166) in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t167);
-  let final self::Class? #t168 = let final self::Class? #t169 = let final self::Class #t170 = c{self::Class} in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t170) in #t169.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t169{self::Class}) in #t168.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t168{self::Class});
-  let final self::Class? #t171 = let final self::Class #t172 = c{self::Class} in #t172.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t172) in #t171.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t171{self::Class});
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+                                                          ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t21 = new self::Class1::•() in let final void #t22 = self::Extension1|set#nullable1(#t20{self::Class1}, #t21) in #t21));
+  self::throws(() → self::Class1? => let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+                                                      ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t24{self::Class1})));
+  nullable1 = let final self::Class1? #t25 = n1 in #t25.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t26 = new self::Class1::•() in let final void #t27 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t25{self::Class1}), #t26) in #t26;
+  nullable1 = let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t29 = self::Extension1|get#nullable1(#t28{self::Class1}) in #t29.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t30 = new self::Class1::•() in let final void #t31 = self::Extension1|set#nullable1(#t29{self::Class1}, #t30) in #t30;
+  nullable1 = let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t33 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t32{self::Class1})) in #t33.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t34 = new self::Class1::•() in let final void #t35 = self::Extension1|set#nullable1(#t33{self::Class1}, #t34) in #t34;
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t37 = self::Extension1|get#nullable1(#t36{self::Class1}) in #t37.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t37{self::Class1});
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t38{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t40 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t41 = self::Extension1|set#nullable1(#t39{self::Class1}, #t40) in #t40;
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t42{self::Class1}, let final self::Class1 #t43 = new self::Class1::•() in let final void #t44 = self::Extension1|set#nullable1(new self::Class1::•(), #t43) in #t43);
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t46 = let final self::Class1 #t47 = new self::Class1::•() in let final void #t48 = self::Extension1|set#nullable1(new self::Class1::•(), #t47) in #t47 in let final void #t49 = self::Extension1|set#nullable1(#t45{self::Class1}, #t46) in #t46;
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t50{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t52 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t53 = self::Extension1|set#nullable1(#t51{self::Class1}, #t52) in #t52;
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t55{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t56{self::Class1}));
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})));
+  let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t58{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t60 = new self::Class1::•() in let final void #t61 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t59{self::Class1})), #t60) in #t60;
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t63 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t62{self::Class1})) in #t63.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t63{self::Class1});
+  let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t64{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t66 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t67 = self::Extension1|set#nullable1(#t65{self::Class1}, #t66) in #t66;
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t68{self::Class1}, let final self::Class1 #t69 = new self::Class1::•() in let final void #t70 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t69) in #t69);
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t72 = let final self::Class1 #t73 = new self::Class1::•() in let final void #t74 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t73) in #t73 in let final void #t75 = self::Extension1|set#nullable1(#t71{self::Class1}, #t72) in #t72;
+  let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t76{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t78 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t79 = self::Extension1|set#nullable1(#t77{self::Class1}, #t78) in #t78;
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t81{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t82{self::Class1})));
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t83{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t86 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t84{self::Class1}), #t85) in #t85;
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t87{self::Class1}), let final self::Class1 #t88 = new self::Class1::•() in let final void #t89 = self::Extension1|set#nullable1(new self::Class1::•(), #t88) in #t88);
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = let final self::Class1 #t92 = new self::Class1::•() in let final void #t93 = self::Extension1|set#nullable1(new self::Class1::•(), #t92) in #t92 in let final void #t94 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t90{self::Class1}), #t91) in #t91;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t95{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t96 = n1 in #t96.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t97 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t98 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t96{self::Class1}), #t97) in #t97;
+  let final self::Class1? #t99 = n1 in #t99.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t99{self::Class1}, let final self::Class1? #t100 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t101 = self::Extension1|set#nullable1(new self::Class1::•(), #t100) in #t100);
+  nullable1 = let final self::Class1? #t102 = n1 in #t102.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t103 = let final self::Class1? #t104 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t105 = self::Extension1|set#nullable1(new self::Class1::•(), #t104) in #t104 in let final void #t106 = self::Extension1|set#nullable1(#t102{self::Class1}, #t103) in #t103;
+  let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t107{self::Class1}, let final self::Class1 #t108 = let final self::Class1 #t109 = new self::Class1::•() in let final void #t110 = self::Extension1|set#nullable1(new self::Class1::•(), #t109) in #t109 in let final void #t111 = self::Extension1|set#nullable1(new self::Class1::•(), #t108) in #t108);
+  nullable1 = let final self::Class1? #t112 = n1 in #t112.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t113 = let final self::Class1 #t114 = let final self::Class1 #t115 = new self::Class1::•() in let final void #t116 = self::Extension1|set#nullable1(new self::Class1::•(), #t115) in #t115 in let final void #t117 = self::Extension1|set#nullable1(new self::Class1::•(), #t114) in #t114 in let final void #t118 = self::Extension1|set#nullable1(#t112{self::Class1}, #t113) in #t113;
+  let final self::Class1? #t119 = n1 in #t119.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t119{self::Class1}, let final self::Class1 #t120 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t121 = self::Extension1|set#nullable1(new self::Class1::•(), #t120) in #t120);
+  nullable1 = let final self::Class1? #t122 = n1 in #t122.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t123 = let final self::Class1 #t124 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t125 = self::Extension1|set#nullable1(new self::Class1::•(), #t124) in #t124 in let final void #t126 = self::Extension1|set#nullable1(#t122{self::Class1}, #t123) in #t123;
+  let final self::Class1? #t127 = n1 in #t127.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t127{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t128 = n1 in #t128.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t129 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t130 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t128{self::Class1}), #t129) in #t129;
+  let final self::Class1? #t131 = n1 in #t131.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t131{self::Class1}), let final self::Class1 #t132 = new self::Class1::•() in let final void #t133 = self::Extension1|set#nullable1(new self::Class1::•(), #t132) in #t132);
+  nullable1 = let final self::Class1? #t134 = n1 in #t134.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t135 = let final self::Class1 #t136 = new self::Class1::•() in let final void #t137 = self::Extension1|set#nullable1(new self::Class1::•(), #t136) in #t136 in let final void #t138 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t134{self::Class1}), #t135) in #t135;
+  let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t139{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t140 = n1 in #t140.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t141 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t142 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t140{self::Class1}), #t141) in #t141;
+  let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})));
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t144{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t145 = n1 in #t145.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t146 = new self::Class1::•() in let final void #t147 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t145{self::Class1})), #t146) in #t146;
+  let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t148{self::Class1})));
+  let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t149{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t150 = n1 in #t150.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t151 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t152 = self::Extension1|set#nullable1(#t150{self::Class1}, #t151) in #t151;
+  let final self::Class1? #t153 = n1 in #t153.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t153{self::Class1}, let final self::Class1 #t154 = new self::Class1::•() in let final void #t155 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t154) in #t154);
+  nullable1 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t157 = let final self::Class1 #t158 = new self::Class1::•() in let final void #t159 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t158) in #t158 in let final void #t160 = self::Extension1|set#nullable1(#t156{self::Class1}, #t157) in #t157;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t161{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t162 = n1 in #t162.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t163 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t164 = self::Extension1|set#nullable1(#t162{self::Class1}, #t163) in #t163;
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t166{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t167 = n1 in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t167{self::Class1})));
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t169 = self::Extension1|nonNullable1Method(#t168{self::Class1}) in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t169{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t173 = c in #t173.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t173{self::Class}, c{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t174{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t176 = self::Extension|[](#t175{self::Class}, c{self::Class}) in #t176.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t176{self::Class});
-  let final self::Class? #t177 = c in #t177.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t177{self::Class}), c{self::Class});
-  let final self::Class? #t178 = c in #t178.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t178{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t180 = self::Extension|get#field(#t179{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class #t182 = new self::Class::•() in let final void #t183 = self::Extension|[]=(#t180, #t181, #t182) in #t182;
-  let final self::Class #t184 = c{self::Class} in #t184.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t185 = self::Extension|[](self::Extension|get#field(#t184), c{self::Class}) in #t185.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t185{self::Class});
-  let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in self::Extension|[]=(#t187, #t188, self::Extension|+(self::Extension|[](#t187, #t188), 0));
-  c = let final self::Class #t189 = c{self::Class} in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = self::Extension|get#field(#t189) in let final self::Class #t191 = c{self::Class} in let final self::Class? #t192 = self::Extension|+(self::Extension|[](#t190, #t191), 0) in let final void #t193 = self::Extension|[]=(#t190, #t191, #t192) in #t192;
-  let final self::Class? #t194 = c in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in self::Extension|[](#t194{self::Class}, #t195).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t194{self::Class}, #t195, c{self::Class}) : null;
-  c = let final self::Class? #t196 = c in #t196.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t197 = c{self::Class} in let final self::Class? #t198 = self::Extension|[](#t196{self::Class}, #t197) in #t198.{core::Object::==}(null) ?{self::Class} let final self::Class #t199 = c{self::Class} in let final void #t200 = self::Extension|[]=(#t196{self::Class}, #t197, #t199) in #t199 : #t198{self::Class};
-  let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t202 = c{self::Class} in self::Extension|[]=(#t201, #t202, self::Extension|+(self::Extension|[](#t201, #t202), 0));
-  c = let final self::Class #t203 = c{self::Class} in #t203.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t204 = c{self::Class} in let final self::Class? #t205 = self::Extension|+(self::Extension|[](#t203, #t204), 0) in let final void #t206 = self::Extension|[]=(#t203, #t204, #t205) in #t205;
-  let final self::Class? #t207 = c in #t207.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t208 = c{self::Class} in self::Extension|[]=(#t207{self::Class}, #t208, self::Extension|+(self::Extension|[](#t207{self::Class}, #t208), 0));
-  c = let final self::Class? #t209 = c in #t209.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t210 = c{self::Class} in let final self::Class? #t211 = self::Extension|+(self::Extension|[](#t209{self::Class}, #t210), 0) in let final void #t212 = self::Extension|[]=(#t209{self::Class}, #t210, #t211) in #t211;
-  let final self::Class? #t213 = c in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t214 = c{self::Class} in self::Extension|[]=(#t213{self::Class}, #t214, self::Extension|+(self::Extension|[](#t213{self::Class}, #t214), 1));
-  c = let final self::Class? #t215 = c in #t215.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t216 = c{self::Class} in let final self::Class? #t217 = self::Extension|[](#t215{self::Class}, #t216) in let final void #t218 = self::Extension|[]=(#t215{self::Class}, #t216, self::Extension|+(#t217, 1)) in #t217;
-  let final self::Class? #t219 = c in #t219.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t219{self::Class}, c{self::Class});
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t170{self::Class1}, nullable1);
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{void} null : self::Extension1|[]=(#t171{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t173 = self::Extension1|[](#t172{self::Class1}, nullable1) in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t173{self::Class1});
+  let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t174{self::Class1}), nullable1);
+  let final self::Class1? #t175 = n1 in #t175.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t175{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t177 = self::Extension1|get#nonNullable1(#t176{self::Class1}) in let final self::Class1? #t178 = nullable1 in let final self::Class1 #t179 = new self::Class1::•() in let final void #t180 = self::Extension1|[]=(#t177, #t178, #t179) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t182 = self::Extension1|[](self::Extension1|get#nonNullable1(#t181{self::Class1}), nullable1) in #t182.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t182{self::Class1});
+  let final self::Class1? #t183 = n1 in #t183.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t184 = self::Extension1|get#nonNullable2(#t183{self::Class1}) in let final self::Class2? #t185 = nullable2 in self::Extension2|[]=(#t184, #t185, self::Extension2|+(self::Extension2|[](#t184, #t185), 0));
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = self::Extension1|get#nonNullable2(#t186{self::Class1}) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = self::Extension2|+(self::Extension2|[](#t187, #t188), 0) in let final void #t190 = self::Extension2|[]=(#t187, #t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in self::Extension1|[](#t191{self::Class1}, #t192).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t191{self::Class1}, #t192, nullable1) : null;
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = nullable1 in let final self::Class1? #t195 = self::Extension1|[](#t193{self::Class1}, #t194) in #t195.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t196 = nullable1 in let final void #t197 = self::Extension1|[]=(#t193{self::Class1}, #t194, #t196) in #t196 : #t195{self::Class1};
+  let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in self::Extension2|[]=(#t198{self::Class2}, #t199, self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0));
+  nullable2 = let final self::Class2? #t200 = n2 in #t200.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t201 = nullable2 in let final self::Class2 #t202 = self::Extension2|+(self::Extension2|[](#t200{self::Class2}, #t201), 0) in let final void #t203 = self::Extension2|[]=(#t200{self::Class2}, #t201, #t202) in #t202;
+  let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in self::Extension2|[]=(#t204{self::Class2}, #t205, self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0));
+  nullable2 = let final self::Class2? #t206 = n2 in #t206.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t207 = nullable2 in let final self::Class2 #t208 = self::Extension2|+(self::Extension2|[](#t206{self::Class2}, #t207), 0) in let final void #t209 = self::Extension2|[]=(#t206{self::Class2}, #t207, #t208) in #t208;
+  let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(self::Extension2|[](#t210{self::Class2}, #t211), 1));
+  nullable2 = let final self::Class2? #t212 = n2 in #t212.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t213 = nullable2 in let final self::Class2 #t214 = self::Extension2|[](#t212{self::Class2}, #t213) in let final void #t215 = self::Extension2|[]=(#t212{self::Class2}, #t213, self::Extension2|+(#t214, 1)) in #t214;
+  let final self::Class2? #t216 = n2 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in let final self::Class2 #t218 = self::Extension2|+(self::Extension2|[](#t216{self::Class2}, #t217), 1) in let final void #t219 = self::Extension2|[]=(#t216{self::Class2}, #t217, #t218) in #t218;
+  nullable2 = let final self::Class2? #t220 = n2 in #t220.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t221 = nullable2 in let final self::Class2 #t222 = self::Extension2|+(self::Extension2|[](#t220{self::Class2}, #t221), 1) in let final void #t223 = self::Extension2|[]=(#t220{self::Class2}, #t221, #t222) in #t222;
+  let final self::Class1? #t224 = n1 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t225 = self::Extension1|get#nonNullable2(#t224{self::Class1}) in let final self::Class2? #t226 = nullable2 in self::Extension2|[]=(#t225, #t226, self::Extension2|+(self::Extension2|[](#t225, #t226), 1));
+  nullable2 = let final self::Class1? #t227 = n1 in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t228 = self::Extension1|get#nonNullable2(#t227{self::Class1}) in let final self::Class2? #t229 = nullable2 in let final self::Class2 #t230 = self::Extension2|[](#t228, #t229) in let final void #t231 = self::Extension2|[]=(#t228, #t229, self::Extension2|+(#t230, 1)) in #t230;
+  let final self::Class1? #t232 = n1 in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t233 = self::Extension1|get#nonNullable2(#t232{self::Class1}) in let final self::Class2? #t234 = nullable2 in let final self::Class2 #t235 = self::Extension2|+(self::Extension2|[](#t233, #t234), 1) in let final void #t236 = self::Extension2|[]=(#t233, #t234, #t235) in #t235;
+  nullable2 = let final self::Class1? #t237 = n1 in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t238 = self::Extension1|get#nonNullable2(#t237{self::Class1}) in let final self::Class2? #t239 = nullable2 in let final self::Class2 #t240 = self::Extension2|+(self::Extension2|[](#t238, #t239), 1) in let final void #t241 = self::Extension2|[]=(#t238, #t239, #t240) in #t240;
+  let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t243 = n1 in #t243.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t243{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t245 = self::Extension2|[](self::Extension1|get#nonNullable2(#t244{self::Class1}), nullable2) in let final self::Class2? #t246 = nullable2 in let final self::Class2 #t247 = new self::Class2::•() in let final void #t248 = self::Extension2|[]=(#t245, #t246, #t247) in #t247;
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t250 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2), nullable2) in #t250.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t250{self::Class2});
+  let final self::Class1? #t251 = n1 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = self::Extension2|[](self::Extension1|get#nonNullable2(#t251{self::Class1}), nullable2) in let final self::Class2? #t253 = nullable2 in self::Extension2|[]=(#t252, #t253, self::Extension2|+(self::Extension2|[](#t252, #t253), 0));
+  nullable2 = let final self::Class1? #t254 = n1 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = self::Extension2|[](self::Extension1|get#nonNullable2(#t254{self::Class1}), nullable2) in let final self::Class2? #t256 = nullable2 in let final self::Class2 #t257 = self::Extension2|+(self::Extension2|[](#t255, #t256), 0) in let final void #t258 = self::Extension2|[]=(#t255, #t256, #t257) in #t257;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t260 = self::Extension2|[](self::Extension1|get#nonNullable2(#t259{self::Class1}), nullable2) in let final self::Class2? #t261 = nullable2 in self::Extension2|[]=(#t260, #t261, self::Extension2|+(self::Extension2|[](#t260, #t261), 1));
+  nullable2 = let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t263 = self::Extension2|[](self::Extension1|get#nonNullable2(#t262{self::Class1}), nullable2) in let final self::Class2? #t264 = nullable2 in let final self::Class2 #t265 = self::Extension2|[](#t263, #t264) in let final void #t266 = self::Extension2|[]=(#t263, #t264, self::Extension2|+(#t265, 1)) in #t265;
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t268 = self::Extension2|[](self::Extension1|get#nonNullable2(#t267{self::Class1}), nullable2) in let final self::Class2? #t269 = nullable2 in let final self::Class2 #t270 = self::Extension2|+(self::Extension2|[](#t268, #t269), 1) in let final void #t271 = self::Extension2|[]=(#t268, #t269, #t270) in #t270;
+  nullable2 = let final self::Class1? #t272 = n1 in #t272.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t273 = self::Extension2|[](self::Extension1|get#nonNullable2(#t272{self::Class1}), nullable2) in let final self::Class2? #t274 = nullable2 in let final self::Class2 #t275 = self::Extension2|+(self::Extension2|[](#t273, #t274), 1) in let final void #t276 = self::Extension2|[]=(#t273, #t274, #t275) in #t275;
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t278{self::Class1}, nullable1);
+  let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t280{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t281 = n1 in #t281.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t282 = self::Extension1|[](#t281{self::Class1}, nullable1) in #t282.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t283 = nullable1 in let final self::Class1 #t284 = new self::Class1::•() in let final void #t285 = self::Extension1|[]=(#t282{self::Class1}, #t283, #t284) in #t284;
+  let final self::Class1? #t286 = n1 in #t286.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t287 = self::Extension1|[](#t286{self::Class1}, nullable1) in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t288{self::Class1});
+  nullable1 = let final self::Class1? #t289 = n1 in #t289.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t290 = self::Extension1|[](#t289{self::Class1}, nullable1) in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t291{self::Class1});
+  let final self::Class1? #t292 = n1 in #t292.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t293 = self::Extension1|[](#t292{self::Class1}, nullable1) in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = nullable1 in self::Extension1|[](#t293{self::Class1}, #t294).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t293{self::Class1}, #t294, nullable1) : null;
+  nullable1 = let final self::Class1? #t295 = n1 in #t295.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t296 = self::Extension1|[](#t295{self::Class1}, nullable1) in #t296.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t297 = nullable1 in let final self::Class1? #t298 = self::Extension1|[](#t296{self::Class1}, #t297) in #t298.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t299 = nullable1 in let final void #t300 = self::Extension1|[]=(#t296{self::Class1}, #t297, #t299) in #t299 : #t298{self::Class1};
+  let final self::Class3? #t301 = n3 in #t301.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t302 = self::Extension3|[](#t301{self::Class3}, nullable3) in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = nullable2 in self::Extension2|[]=(#t302{self::Class2}, #t303, self::Extension2|+(self::Extension2|[](#t302{self::Class2}, #t303), 0));
+  nullable2 = let final self::Class3? #t304 = n3 in #t304.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t305 = self::Extension3|[](#t304{self::Class3}, nullable3) in #t305.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t306 = nullable2 in let final self::Class2 #t307 = self::Extension2|+(self::Extension2|[](#t305{self::Class2}, #t306), 0) in let final void #t308 = self::Extension2|[]=(#t305{self::Class2}, #t306, #t307) in #t307;
+  let final self::Class3? #t309 = n3 in #t309.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t310 = self::Extension3|[](#t309{self::Class3}, nullable3) in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = nullable2 in self::Extension2|[]=(#t310{self::Class2}, #t311, self::Extension2|+(self::Extension2|[](#t310{self::Class2}, #t311), 1));
+  nullable2 = let final self::Class3? #t312 = n3 in #t312.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t313 = self::Extension3|[](#t312{self::Class3}, nullable3) in #t313.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t314 = nullable2 in let final self::Class2 #t315 = self::Extension2|[](#t313{self::Class2}, #t314) in let final void #t316 = self::Extension2|[]=(#t313{self::Class2}, #t314, self::Extension2|+(#t315, 1)) in #t315;
+  let final self::Class3? #t317 = n3 in #t317.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t318 = self::Extension3|[](#t317{self::Class3}, nullable3) in #t318.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t319 = nullable2 in let final self::Class2 #t320 = self::Extension2|+(self::Extension2|[](#t318{self::Class2}, #t319), 1) in let final void #t321 = self::Extension2|[]=(#t318{self::Class2}, #t319, #t320) in #t320;
+  nullable2 = let final self::Class3? #t322 = n3 in #t322.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t323 = self::Extension3|[](#t322{self::Class3}, nullable3) in #t323.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t324 = nullable2 in let final self::Class2 #t325 = self::Extension2|+(self::Extension2|[](#t323{self::Class2}, #t324), 1) in let final void #t326 = self::Extension2|[]=(#t323{self::Class2}, #t324, #t325) in #t325;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329{self::Class}, self::Extension|+(self::Extension|get#field(#t329{self::Class}), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330{self::Class}), 0) in let final void #t332 = self::Extension|set#field(#t330{self::Class}, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339{self::Class}, self::Extension|+(self::Extension|get#field(#t339{self::Class}), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340{self::Class}) in let final self::Class? #t342 = let final self::Class? #t343 = self::Extension|+(#t341, 1) in let final void #t344 = self::Extension|set#field(#t340{self::Class}, #t343) in #t343 in #t341;
-  let final self::Class? #t345 = c in #t345.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t346 = self::Extension|+(self::Extension|get#field(#t345{self::Class}), 1) in let final void #t347 = self::Extension|set#field(#t345{self::Class}, #t346) in #t346;
-  c = let final self::Class? #t348 = c in #t348.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t349 = self::Extension|+(self::Extension|get#field(#t348{self::Class}), 1) in let final void #t350 = self::Extension|set#field(#t348{self::Class}, #t349) in #t349;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t327 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+  throws(() => Extension1(n1)?.nonNullable1 + 0);
+                                            ^" in self::Extension1|+(let final self::Class1? #t328 = n1 in #t328.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t328{self::Class1}), 0));
+  self::throws(() → self::Class1? => let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+  throws(() => -Extension1(n1)?.nonNullable1);
+               ^" in self::Extension1|unary-(let final self::Class1? #t330 = n1 in #t330.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t330{self::Class1})));
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t331{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t331{self::Class2}), 0));
+  nullable2 = let final self::Class2? #t332 = n2 in #t332.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t333 = self::Extension2|+(self::Extension2|get#nonNullable2(#t332{self::Class2}), 0) in let final void #t334 = self::Extension2|set#nonNullable2(#t332{self::Class2}, #t333) in #t333;
+  let final self::Class2? #t335 = n2 in #t335.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t336 = self::Extension2|get#nonNullable2(#t335{self::Class2}) in self::Extension2|set#nonNullable2(#t336, self::Extension2|+(self::Extension2|get#nonNullable2(#t336), 0));
+  nullable2 = let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t338 = self::Extension2|get#nonNullable2(#t337{self::Class2}) in let final self::Class2 #t339 = self::Extension2|+(self::Extension2|get#nonNullable2(#t338), 0) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, #t339) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t341{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t341{self::Class2}), 1));
+  nullable2 = let final self::Class2? #t342 = n2 in #t342.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t343 = self::Extension2|get#nonNullable2(#t342{self::Class2}) in let final self::Class2 #t344 = let final self::Class2 #t345 = self::Extension2|+(#t343, 1) in let final void #t346 = self::Extension2|set#nonNullable2(#t342{self::Class2}, #t345) in #t345 in #t343;
+  let final self::Class2? #t347 = n2 in #t347.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t348 = self::Extension2|+(self::Extension2|get#nonNullable2(#t347{self::Class2}), 1) in let final void #t349 = self::Extension2|set#nonNullable2(#t347{self::Class2}, #t348) in #t348;
+  nullable2 = let final self::Class2? #t350 = n2 in #t350.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t351 = self::Extension2|+(self::Extension2|get#nonNullable2(#t350{self::Class2}), 1) in let final void #t352 = self::Extension2|set#nonNullable2(#t350{self::Class2}, #t351) in #t351;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t351 = c in #t351.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t351{self::Class}).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t351{self::Class}, c{self::Class}) : null;
-  c = let final self::Class? #t352 = c in #t352.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t353 = self::Extension|get#field(#t352{self::Class}) in #t353.{core::Object::==}(null) ?{self::Class} let final self::Class #t354 = c{self::Class} in let final void #t355 = self::Extension|set#field(#t352{self::Class}, #t354) in #t354 : #t353{self::Class};
-  let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in self::Extension|get#field(#t357).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t357, c{self::Class}) : null;
-  c = let final self::Class #t358 = c{self::Class} in #t358.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t359 = self::Extension|get#property(#t358) in let final self::Class? #t360 = self::Extension|get#field(#t359) in #t360.{core::Object::==}(null) ?{self::Class} let final self::Class #t361 = c{self::Class} in let final void #t362 = self::Extension|set#field(#t359, #t361) in #t361 : #t360{self::Class};
-  let final self::Class #t363 = c{self::Class} in #t363.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t364 = self::Extension|get#field(#t363) in let final self::Class #t365 = c{self::Class} in self::Extension|[](#t364, #t365).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t364, #t365, c{self::Class}) : null;
-  c = let final self::Class #t366 = c{self::Class} in #t366.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t367 = self::Extension|get#field(#t366) in let final self::Class #t368 = c{self::Class} in let final self::Class? #t369 = self::Extension|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class} let final self::Class #t370 = c{self::Class} in let final void #t371 = self::Extension|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t353 = n1 in #t353.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t353).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t353, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nullable1(#t354) in #t355.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t356 = n1{self::Class1} in let final void #t357 = self::Extension1|set#nullable1(#t354, #t356) in #t356 : #t355{self::Class1};
+  let final self::Class1? #t358 = n1 in #t358.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t359 = self::Extension1|get#nonNullable1(#t358{self::Class1}) in self::Extension1|get#nullable1(#t359{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t359{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t360 = n1 in #t360.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t361 = self::Extension1|get#nonNullable1(#t360{self::Class1}) in let final self::Class1? #t362 = self::Extension1|get#nullable1(#t361{self::Class1}) in #t362.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t363 = n1{self::Class1} in let final void #t364 = self::Extension1|set#nullable1(#t361{self::Class1}, #t363) in #t363 : #t362{self::Class1};
+  let final self::Class1? #t365 = n1 in #t365.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t366 = self::Extension1|get#nonNullable1(#t365{self::Class1}) in let final self::Class1 #t367 = n1{self::Class1} in self::Extension1|[](#t366, #t367).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t366, #t367, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t368 = n1 in #t368.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t369 = self::Extension1|get#nonNullable1(#t368{self::Class1}) in let final self::Class1 #t370 = n1{self::Class1} in let final self::Class1? #t371 = self::Extension1|[](#t369, #t370) in #t371.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t372 = n1{self::Class1} in let final void #t373 = self::Extension1|[]=(#t369, #t370, #t372) in #t372 : #t371{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
index 7ce7211..7bd0924 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect
@@ -1,192 +1,291 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+//                                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+//                                                       ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => Extension1(n1)?.nonNullable1 + 0);
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => -Extension1(n1)?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t35 = self::Extension|get#field(#t34) in #t35.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t35{self::Class});
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t36, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t38 = self::Extension|get#field(new self::Class::•()) in let final void #t39 = self::Extension|set#field(#t37, #t38) in #t38;
-  let final self::Class? #t40 = c in #t40.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t40{self::Class}, let final self::Class #t41 = new self::Class::•() in let final void #t42 = self::Extension|set#field(new self::Class::•(), #t41) in #t41);
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t44 = let final self::Class #t45 = new self::Class::•() in let final void #t46 = self::Extension|set#field(new self::Class::•(), #t45) in #t45 in let final void #t47 = self::Extension|set#field(#t43{self::Class}, #t44) in #t44;
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t48, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t50 = self::Extension|method(new self::Class::•()) in let final void #t51 = self::Extension|set#field(#t49, #t50) in #t50;
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t52));
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t53), new self::Class::•());
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t54));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t55)));
-  let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), new self::Class::•());
-  c = let final self::Class #t57 = c{self::Class} in #t57.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t58 = new self::Class::•() in let final void #t59 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t57)), #t58) in #t58;
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t60)));
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t61, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t63 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t64 = self::Extension|set#field(#t62, #t63) in #t63;
-  let final self::Class? #t65 = c in #t65.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t65{self::Class}, let final self::Class #t66 = new self::Class::•() in let final void #t67 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t66) in #t66);
-  c = let final self::Class? #t68 = c in #t68.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t69 = let final self::Class #t70 = new self::Class::•() in let final void #t71 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t70) in #t70 in let final void #t72 = self::Extension|set#field(#t68{self::Class}, #t69) in #t69;
-  let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t73, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t74 = c{self::Class} in #t74.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t75 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t76 = self::Extension|set#field(#t74, #t75) in #t75;
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t77)));
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t78)), new self::Class::•());
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t80 = self::Extension|get#field(self::Extension|method(#t79)) in #t80.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t80{self::Class});
-  let final self::Class #t81 = c{self::Class} in #t81.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t81), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t82 = c{self::Class} in #t82.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t83 = self::Extension|get#field(new self::Class::•()) in let final void #t84 = self::Extension|set#field(self::Extension|get#property(#t82), #t83) in #t83;
-  let final self::Class? #t85 = c in #t85.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t85{self::Class}), let final self::Class #t86 = new self::Class::•() in let final void #t87 = self::Extension|set#field(new self::Class::•(), #t86) in #t86);
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t89 = let final self::Class #t90 = new self::Class::•() in let final void #t91 = self::Extension|set#field(new self::Class::•(), #t90) in #t90 in let final void #t92 = self::Extension|set#field(self::Extension|get#property(#t88{self::Class}), #t89) in #t89;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t93), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t94 = c{self::Class} in #t94.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t95 = self::Extension|method(new self::Class::•()) in let final void #t96 = self::Extension|set#field(self::Extension|get#property(#t94), #t95) in #t95;
-  let final self::Class #t97 = c{self::Class} in #t97.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t97, let final self::Class? #t98 = self::Extension|get#field(new self::Class::•()) in let final void #t99 = self::Extension|set#field(new self::Class::•(), #t98) in #t98);
-  c = let final self::Class #t100 = c{self::Class} in #t100.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t101 = let final self::Class? #t102 = self::Extension|get#field(new self::Class::•()) in let final void #t103 = self::Extension|set#field(new self::Class::•(), #t102) in #t102 in let final void #t104 = self::Extension|set#field(#t100, #t101) in #t101;
-  let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t105{self::Class}, let final self::Class #t106 = let final self::Class #t107 = new self::Class::•() in let final void #t108 = self::Extension|set#field(new self::Class::•(), #t107) in #t107 in let final void #t109 = self::Extension|set#field(new self::Class::•(), #t106) in #t106);
-  c = let final self::Class? #t110 = c in #t110.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t111 = let final self::Class #t112 = let final self::Class #t113 = new self::Class::•() in let final void #t114 = self::Extension|set#field(new self::Class::•(), #t113) in #t113 in let final void #t115 = self::Extension|set#field(new self::Class::•(), #t112) in #t112 in let final void #t116 = self::Extension|set#field(#t110{self::Class}, #t111) in #t111;
-  let final self::Class #t117 = c{self::Class} in #t117.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t117, let final self::Class #t118 = self::Extension|method(new self::Class::•()) in let final void #t119 = self::Extension|set#field(new self::Class::•(), #t118) in #t118);
-  c = let final self::Class #t120 = c{self::Class} in #t120.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t121 = let final self::Class #t122 = self::Extension|method(new self::Class::•()) in let final void #t123 = self::Extension|set#field(new self::Class::•(), #t122) in #t122 in let final void #t124 = self::Extension|set#field(#t120, #t121) in #t121;
-  let final self::Class #t125 = c{self::Class} in #t125.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t125), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t126 = c{self::Class} in #t126.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t127 = self::Extension|get#field(new self::Class::•()) in let final void #t128 = self::Extension|set#field(self::Extension|method(#t126), #t127) in #t127;
-  let final self::Class? #t129 = c in #t129.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t129{self::Class}), let final self::Class #t130 = new self::Class::•() in let final void #t131 = self::Extension|set#field(new self::Class::•(), #t130) in #t130);
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t133 = let final self::Class #t134 = new self::Class::•() in let final void #t135 = self::Extension|set#field(new self::Class::•(), #t134) in #t134 in let final void #t136 = self::Extension|set#field(self::Extension|method(#t132{self::Class}), #t133) in #t133;
-  let final self::Class #t137 = c{self::Class} in #t137.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t137), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t138 = c{self::Class} in #t138.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t139 = self::Extension|method(new self::Class::•()) in let final void #t140 = self::Extension|set#field(self::Extension|method(#t138), #t139) in #t139;
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|get#property(#t141)));
-  let final self::Class #t142 = c{self::Class} in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t142)), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t144 = new self::Class::•() in let final void #t145 = self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t143)), #t144) in #t144;
-  let final self::Class #t146 = c{self::Class} in #t146.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|get#property(#t146)));
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t147, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t148 = c{self::Class} in #t148.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t149 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t150 = self::Extension|set#field(#t148, #t149) in #t149;
-  let final self::Class? #t151 = c in #t151.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t151{self::Class}, let final self::Class #t152 = new self::Class::•() in let final void #t153 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t152) in #t152);
-  c = let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t155 = let final self::Class #t156 = new self::Class::•() in let final void #t157 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t156) in #t156 in let final void #t158 = self::Extension|set#field(#t154{self::Class}, #t155) in #t155;
-  let final self::Class #t159 = c{self::Class} in #t159.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t159, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t160 = c{self::Class} in #t160.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t161 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t162 = self::Extension|set#field(#t160, #t161) in #t161;
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t163)));
-  let final self::Class #t164 = c{self::Class} in #t164.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t164)), new self::Class::•());
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t167 = self::Extension|method(#t166) in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t167);
-  let final self::Class? #t168 = let final self::Class? #t169 = let final self::Class #t170 = c{self::Class} in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t170) in #t169.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t169{self::Class}) in #t168.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t168{self::Class});
-  let final self::Class? #t171 = let final self::Class #t172 = c{self::Class} in #t172.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t172) in #t171.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t171{self::Class});
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+                                                          ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t21 = new self::Class1::•() in let final void #t22 = self::Extension1|set#nullable1(#t20{self::Class1}, #t21) in #t21));
+  self::throws(() → self::Class1? => let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+                                                      ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t24{self::Class1})));
+  nullable1 = let final self::Class1? #t25 = n1 in #t25.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t26 = new self::Class1::•() in let final void #t27 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t25{self::Class1}), #t26) in #t26;
+  nullable1 = let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t29 = self::Extension1|get#nullable1(#t28{self::Class1}) in #t29.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t30 = new self::Class1::•() in let final void #t31 = self::Extension1|set#nullable1(#t29{self::Class1}, #t30) in #t30;
+  nullable1 = let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t33 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t32{self::Class1})) in #t33.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t34 = new self::Class1::•() in let final void #t35 = self::Extension1|set#nullable1(#t33{self::Class1}, #t34) in #t34;
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t37 = self::Extension1|get#nullable1(#t36{self::Class1}) in #t37.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t37{self::Class1});
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t38{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t40 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t41 = self::Extension1|set#nullable1(#t39{self::Class1}, #t40) in #t40;
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t42{self::Class1}, let final self::Class1 #t43 = new self::Class1::•() in let final void #t44 = self::Extension1|set#nullable1(new self::Class1::•(), #t43) in #t43);
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t46 = let final self::Class1 #t47 = new self::Class1::•() in let final void #t48 = self::Extension1|set#nullable1(new self::Class1::•(), #t47) in #t47 in let final void #t49 = self::Extension1|set#nullable1(#t45{self::Class1}, #t46) in #t46;
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t50{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t52 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t53 = self::Extension1|set#nullable1(#t51{self::Class1}, #t52) in #t52;
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t55{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t56{self::Class1}));
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})));
+  let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t58{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t60 = new self::Class1::•() in let final void #t61 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t59{self::Class1})), #t60) in #t60;
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t63 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t62{self::Class1})) in #t63.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t63{self::Class1});
+  let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t64{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t66 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t67 = self::Extension1|set#nullable1(#t65{self::Class1}, #t66) in #t66;
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t68{self::Class1}, let final self::Class1 #t69 = new self::Class1::•() in let final void #t70 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t69) in #t69);
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t72 = let final self::Class1 #t73 = new self::Class1::•() in let final void #t74 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t73) in #t73 in let final void #t75 = self::Extension1|set#nullable1(#t71{self::Class1}, #t72) in #t72;
+  let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t76{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t78 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t79 = self::Extension1|set#nullable1(#t77{self::Class1}, #t78) in #t78;
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t81{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t82{self::Class1})));
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t83{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t86 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t84{self::Class1}), #t85) in #t85;
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t87{self::Class1}), let final self::Class1 #t88 = new self::Class1::•() in let final void #t89 = self::Extension1|set#nullable1(new self::Class1::•(), #t88) in #t88);
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = let final self::Class1 #t92 = new self::Class1::•() in let final void #t93 = self::Extension1|set#nullable1(new self::Class1::•(), #t92) in #t92 in let final void #t94 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t90{self::Class1}), #t91) in #t91;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t95{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t96 = n1 in #t96.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t97 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t98 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t96{self::Class1}), #t97) in #t97;
+  let final self::Class1? #t99 = n1 in #t99.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t99{self::Class1}, let final self::Class1? #t100 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t101 = self::Extension1|set#nullable1(new self::Class1::•(), #t100) in #t100);
+  nullable1 = let final self::Class1? #t102 = n1 in #t102.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t103 = let final self::Class1? #t104 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t105 = self::Extension1|set#nullable1(new self::Class1::•(), #t104) in #t104 in let final void #t106 = self::Extension1|set#nullable1(#t102{self::Class1}, #t103) in #t103;
+  let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t107{self::Class1}, let final self::Class1 #t108 = let final self::Class1 #t109 = new self::Class1::•() in let final void #t110 = self::Extension1|set#nullable1(new self::Class1::•(), #t109) in #t109 in let final void #t111 = self::Extension1|set#nullable1(new self::Class1::•(), #t108) in #t108);
+  nullable1 = let final self::Class1? #t112 = n1 in #t112.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t113 = let final self::Class1 #t114 = let final self::Class1 #t115 = new self::Class1::•() in let final void #t116 = self::Extension1|set#nullable1(new self::Class1::•(), #t115) in #t115 in let final void #t117 = self::Extension1|set#nullable1(new self::Class1::•(), #t114) in #t114 in let final void #t118 = self::Extension1|set#nullable1(#t112{self::Class1}, #t113) in #t113;
+  let final self::Class1? #t119 = n1 in #t119.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t119{self::Class1}, let final self::Class1 #t120 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t121 = self::Extension1|set#nullable1(new self::Class1::•(), #t120) in #t120);
+  nullable1 = let final self::Class1? #t122 = n1 in #t122.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t123 = let final self::Class1 #t124 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t125 = self::Extension1|set#nullable1(new self::Class1::•(), #t124) in #t124 in let final void #t126 = self::Extension1|set#nullable1(#t122{self::Class1}, #t123) in #t123;
+  let final self::Class1? #t127 = n1 in #t127.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t127{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t128 = n1 in #t128.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t129 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t130 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t128{self::Class1}), #t129) in #t129;
+  let final self::Class1? #t131 = n1 in #t131.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t131{self::Class1}), let final self::Class1 #t132 = new self::Class1::•() in let final void #t133 = self::Extension1|set#nullable1(new self::Class1::•(), #t132) in #t132);
+  nullable1 = let final self::Class1? #t134 = n1 in #t134.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t135 = let final self::Class1 #t136 = new self::Class1::•() in let final void #t137 = self::Extension1|set#nullable1(new self::Class1::•(), #t136) in #t136 in let final void #t138 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t134{self::Class1}), #t135) in #t135;
+  let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t139{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t140 = n1 in #t140.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t141 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t142 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t140{self::Class1}), #t141) in #t141;
+  let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})));
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t144{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t145 = n1 in #t145.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t146 = new self::Class1::•() in let final void #t147 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t145{self::Class1})), #t146) in #t146;
+  let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t148{self::Class1})));
+  let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t149{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t150 = n1 in #t150.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t151 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t152 = self::Extension1|set#nullable1(#t150{self::Class1}, #t151) in #t151;
+  let final self::Class1? #t153 = n1 in #t153.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t153{self::Class1}, let final self::Class1 #t154 = new self::Class1::•() in let final void #t155 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t154) in #t154);
+  nullable1 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t157 = let final self::Class1 #t158 = new self::Class1::•() in let final void #t159 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t158) in #t158 in let final void #t160 = self::Extension1|set#nullable1(#t156{self::Class1}, #t157) in #t157;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t161{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t162 = n1 in #t162.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t163 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t164 = self::Extension1|set#nullable1(#t162{self::Class1}, #t163) in #t163;
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t166{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t167 = n1 in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t167{self::Class1})));
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t169 = self::Extension1|nonNullable1Method(#t168{self::Class1}) in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t169{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t173 = c in #t173.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t173{self::Class}, c{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t174{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t176 = self::Extension|[](#t175{self::Class}, c{self::Class}) in #t176.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t176{self::Class});
-  let final self::Class? #t177 = c in #t177.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t177{self::Class}), c{self::Class});
-  let final self::Class? #t178 = c in #t178.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t178{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t180 = self::Extension|get#field(#t179{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class #t182 = new self::Class::•() in let final void #t183 = self::Extension|[]=(#t180, #t181, #t182) in #t182;
-  let final self::Class #t184 = c{self::Class} in #t184.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t185 = self::Extension|[](self::Extension|get#field(#t184), c{self::Class}) in #t185.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t185{self::Class});
-  let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in self::Extension|[]=(#t187, #t188, self::Extension|+(self::Extension|[](#t187, #t188), 0));
-  c = let final self::Class #t189 = c{self::Class} in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = self::Extension|get#field(#t189) in let final self::Class #t191 = c{self::Class} in let final self::Class? #t192 = self::Extension|+(self::Extension|[](#t190, #t191), 0) in let final void #t193 = self::Extension|[]=(#t190, #t191, #t192) in #t192;
-  let final self::Class? #t194 = c in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in self::Extension|[](#t194{self::Class}, #t195).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t194{self::Class}, #t195, c{self::Class}) : null;
-  c = let final self::Class? #t196 = c in #t196.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t197 = c{self::Class} in let final self::Class? #t198 = self::Extension|[](#t196{self::Class}, #t197) in #t198.{core::Object::==}(null) ?{self::Class} let final self::Class #t199 = c{self::Class} in let final void #t200 = self::Extension|[]=(#t196{self::Class}, #t197, #t199) in #t199 : #t198{self::Class};
-  let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t202 = c{self::Class} in self::Extension|[]=(#t201, #t202, self::Extension|+(self::Extension|[](#t201, #t202), 0));
-  c = let final self::Class #t203 = c{self::Class} in #t203.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t204 = c{self::Class} in let final self::Class? #t205 = self::Extension|+(self::Extension|[](#t203, #t204), 0) in let final void #t206 = self::Extension|[]=(#t203, #t204, #t205) in #t205;
-  let final self::Class? #t207 = c in #t207.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t208 = c{self::Class} in self::Extension|[]=(#t207{self::Class}, #t208, self::Extension|+(self::Extension|[](#t207{self::Class}, #t208), 0));
-  c = let final self::Class? #t209 = c in #t209.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t210 = c{self::Class} in let final self::Class? #t211 = self::Extension|+(self::Extension|[](#t209{self::Class}, #t210), 0) in let final void #t212 = self::Extension|[]=(#t209{self::Class}, #t210, #t211) in #t211;
-  let final self::Class? #t213 = c in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t214 = c{self::Class} in self::Extension|[]=(#t213{self::Class}, #t214, self::Extension|+(self::Extension|[](#t213{self::Class}, #t214), 1));
-  c = let final self::Class? #t215 = c in #t215.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t216 = c{self::Class} in let final self::Class? #t217 = self::Extension|[](#t215{self::Class}, #t216) in let final void #t218 = self::Extension|[]=(#t215{self::Class}, #t216, self::Extension|+(#t217, 1)) in #t217;
-  let final self::Class? #t219 = c in #t219.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t219{self::Class}, c{self::Class});
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t170{self::Class1}, nullable1);
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{void} null : self::Extension1|[]=(#t171{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t173 = self::Extension1|[](#t172{self::Class1}, nullable1) in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t173{self::Class1});
+  let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t174{self::Class1}), nullable1);
+  let final self::Class1? #t175 = n1 in #t175.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t175{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t177 = self::Extension1|get#nonNullable1(#t176{self::Class1}) in let final self::Class1? #t178 = nullable1 in let final self::Class1 #t179 = new self::Class1::•() in let final void #t180 = self::Extension1|[]=(#t177, #t178, #t179) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t182 = self::Extension1|[](self::Extension1|get#nonNullable1(#t181{self::Class1}), nullable1) in #t182.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t182{self::Class1});
+  let final self::Class1? #t183 = n1 in #t183.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t184 = self::Extension1|get#nonNullable2(#t183{self::Class1}) in let final self::Class2? #t185 = nullable2 in self::Extension2|[]=(#t184, #t185, self::Extension2|+(self::Extension2|[](#t184, #t185), 0));
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = self::Extension1|get#nonNullable2(#t186{self::Class1}) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = self::Extension2|+(self::Extension2|[](#t187, #t188), 0) in let final void #t190 = self::Extension2|[]=(#t187, #t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in self::Extension1|[](#t191{self::Class1}, #t192).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t191{self::Class1}, #t192, nullable1) : null;
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = nullable1 in let final self::Class1? #t195 = self::Extension1|[](#t193{self::Class1}, #t194) in #t195.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t196 = nullable1 in let final void #t197 = self::Extension1|[]=(#t193{self::Class1}, #t194, #t196) in #t196 : #t195{self::Class1};
+  let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in self::Extension2|[]=(#t198{self::Class2}, #t199, self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0));
+  nullable2 = let final self::Class2? #t200 = n2 in #t200.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t201 = nullable2 in let final self::Class2 #t202 = self::Extension2|+(self::Extension2|[](#t200{self::Class2}, #t201), 0) in let final void #t203 = self::Extension2|[]=(#t200{self::Class2}, #t201, #t202) in #t202;
+  let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in self::Extension2|[]=(#t204{self::Class2}, #t205, self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0));
+  nullable2 = let final self::Class2? #t206 = n2 in #t206.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t207 = nullable2 in let final self::Class2 #t208 = self::Extension2|+(self::Extension2|[](#t206{self::Class2}, #t207), 0) in let final void #t209 = self::Extension2|[]=(#t206{self::Class2}, #t207, #t208) in #t208;
+  let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(self::Extension2|[](#t210{self::Class2}, #t211), 1));
+  nullable2 = let final self::Class2? #t212 = n2 in #t212.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t213 = nullable2 in let final self::Class2 #t214 = self::Extension2|[](#t212{self::Class2}, #t213) in let final void #t215 = self::Extension2|[]=(#t212{self::Class2}, #t213, self::Extension2|+(#t214, 1)) in #t214;
+  let final self::Class2? #t216 = n2 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in let final self::Class2 #t218 = self::Extension2|+(self::Extension2|[](#t216{self::Class2}, #t217), 1) in let final void #t219 = self::Extension2|[]=(#t216{self::Class2}, #t217, #t218) in #t218;
+  nullable2 = let final self::Class2? #t220 = n2 in #t220.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t221 = nullable2 in let final self::Class2 #t222 = self::Extension2|+(self::Extension2|[](#t220{self::Class2}, #t221), 1) in let final void #t223 = self::Extension2|[]=(#t220{self::Class2}, #t221, #t222) in #t222;
+  let final self::Class1? #t224 = n1 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t225 = self::Extension1|get#nonNullable2(#t224{self::Class1}) in let final self::Class2? #t226 = nullable2 in self::Extension2|[]=(#t225, #t226, self::Extension2|+(self::Extension2|[](#t225, #t226), 1));
+  nullable2 = let final self::Class1? #t227 = n1 in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t228 = self::Extension1|get#nonNullable2(#t227{self::Class1}) in let final self::Class2? #t229 = nullable2 in let final self::Class2 #t230 = self::Extension2|[](#t228, #t229) in let final void #t231 = self::Extension2|[]=(#t228, #t229, self::Extension2|+(#t230, 1)) in #t230;
+  let final self::Class1? #t232 = n1 in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t233 = self::Extension1|get#nonNullable2(#t232{self::Class1}) in let final self::Class2? #t234 = nullable2 in let final self::Class2 #t235 = self::Extension2|+(self::Extension2|[](#t233, #t234), 1) in let final void #t236 = self::Extension2|[]=(#t233, #t234, #t235) in #t235;
+  nullable2 = let final self::Class1? #t237 = n1 in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t238 = self::Extension1|get#nonNullable2(#t237{self::Class1}) in let final self::Class2? #t239 = nullable2 in let final self::Class2 #t240 = self::Extension2|+(self::Extension2|[](#t238, #t239), 1) in let final void #t241 = self::Extension2|[]=(#t238, #t239, #t240) in #t240;
+  let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t243 = n1 in #t243.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t243{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t245 = self::Extension2|[](self::Extension1|get#nonNullable2(#t244{self::Class1}), nullable2) in let final self::Class2? #t246 = nullable2 in let final self::Class2 #t247 = new self::Class2::•() in let final void #t248 = self::Extension2|[]=(#t245, #t246, #t247) in #t247;
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t250 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2), nullable2) in #t250.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t250{self::Class2});
+  let final self::Class1? #t251 = n1 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = self::Extension2|[](self::Extension1|get#nonNullable2(#t251{self::Class1}), nullable2) in let final self::Class2? #t253 = nullable2 in self::Extension2|[]=(#t252, #t253, self::Extension2|+(self::Extension2|[](#t252, #t253), 0));
+  nullable2 = let final self::Class1? #t254 = n1 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = self::Extension2|[](self::Extension1|get#nonNullable2(#t254{self::Class1}), nullable2) in let final self::Class2? #t256 = nullable2 in let final self::Class2 #t257 = self::Extension2|+(self::Extension2|[](#t255, #t256), 0) in let final void #t258 = self::Extension2|[]=(#t255, #t256, #t257) in #t257;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t260 = self::Extension2|[](self::Extension1|get#nonNullable2(#t259{self::Class1}), nullable2) in let final self::Class2? #t261 = nullable2 in self::Extension2|[]=(#t260, #t261, self::Extension2|+(self::Extension2|[](#t260, #t261), 1));
+  nullable2 = let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t263 = self::Extension2|[](self::Extension1|get#nonNullable2(#t262{self::Class1}), nullable2) in let final self::Class2? #t264 = nullable2 in let final self::Class2 #t265 = self::Extension2|[](#t263, #t264) in let final void #t266 = self::Extension2|[]=(#t263, #t264, self::Extension2|+(#t265, 1)) in #t265;
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t268 = self::Extension2|[](self::Extension1|get#nonNullable2(#t267{self::Class1}), nullable2) in let final self::Class2? #t269 = nullable2 in let final self::Class2 #t270 = self::Extension2|+(self::Extension2|[](#t268, #t269), 1) in let final void #t271 = self::Extension2|[]=(#t268, #t269, #t270) in #t270;
+  nullable2 = let final self::Class1? #t272 = n1 in #t272.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t273 = self::Extension2|[](self::Extension1|get#nonNullable2(#t272{self::Class1}), nullable2) in let final self::Class2? #t274 = nullable2 in let final self::Class2 #t275 = self::Extension2|+(self::Extension2|[](#t273, #t274), 1) in let final void #t276 = self::Extension2|[]=(#t273, #t274, #t275) in #t275;
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t278{self::Class1}, nullable1);
+  let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t280{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t281 = n1 in #t281.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t282 = self::Extension1|[](#t281{self::Class1}, nullable1) in #t282.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t283 = nullable1 in let final self::Class1 #t284 = new self::Class1::•() in let final void #t285 = self::Extension1|[]=(#t282{self::Class1}, #t283, #t284) in #t284;
+  let final self::Class1? #t286 = n1 in #t286.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t287 = self::Extension1|[](#t286{self::Class1}, nullable1) in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t288{self::Class1});
+  nullable1 = let final self::Class1? #t289 = n1 in #t289.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t290 = self::Extension1|[](#t289{self::Class1}, nullable1) in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t291{self::Class1});
+  let final self::Class1? #t292 = n1 in #t292.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t293 = self::Extension1|[](#t292{self::Class1}, nullable1) in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = nullable1 in self::Extension1|[](#t293{self::Class1}, #t294).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t293{self::Class1}, #t294, nullable1) : null;
+  nullable1 = let final self::Class1? #t295 = n1 in #t295.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t296 = self::Extension1|[](#t295{self::Class1}, nullable1) in #t296.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t297 = nullable1 in let final self::Class1? #t298 = self::Extension1|[](#t296{self::Class1}, #t297) in #t298.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t299 = nullable1 in let final void #t300 = self::Extension1|[]=(#t296{self::Class1}, #t297, #t299) in #t299 : #t298{self::Class1};
+  let final self::Class3? #t301 = n3 in #t301.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t302 = self::Extension3|[](#t301{self::Class3}, nullable3) in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = nullable2 in self::Extension2|[]=(#t302{self::Class2}, #t303, self::Extension2|+(self::Extension2|[](#t302{self::Class2}, #t303), 0));
+  nullable2 = let final self::Class3? #t304 = n3 in #t304.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t305 = self::Extension3|[](#t304{self::Class3}, nullable3) in #t305.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t306 = nullable2 in let final self::Class2 #t307 = self::Extension2|+(self::Extension2|[](#t305{self::Class2}, #t306), 0) in let final void #t308 = self::Extension2|[]=(#t305{self::Class2}, #t306, #t307) in #t307;
+  let final self::Class3? #t309 = n3 in #t309.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t310 = self::Extension3|[](#t309{self::Class3}, nullable3) in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = nullable2 in self::Extension2|[]=(#t310{self::Class2}, #t311, self::Extension2|+(self::Extension2|[](#t310{self::Class2}, #t311), 1));
+  nullable2 = let final self::Class3? #t312 = n3 in #t312.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t313 = self::Extension3|[](#t312{self::Class3}, nullable3) in #t313.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t314 = nullable2 in let final self::Class2 #t315 = self::Extension2|[](#t313{self::Class2}, #t314) in let final void #t316 = self::Extension2|[]=(#t313{self::Class2}, #t314, self::Extension2|+(#t315, 1)) in #t315;
+  let final self::Class3? #t317 = n3 in #t317.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t318 = self::Extension3|[](#t317{self::Class3}, nullable3) in #t318.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t319 = nullable2 in let final self::Class2 #t320 = self::Extension2|+(self::Extension2|[](#t318{self::Class2}, #t319), 1) in let final void #t321 = self::Extension2|[]=(#t318{self::Class2}, #t319, #t320) in #t320;
+  nullable2 = let final self::Class3? #t322 = n3 in #t322.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t323 = self::Extension3|[](#t322{self::Class3}, nullable3) in #t323.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t324 = nullable2 in let final self::Class2 #t325 = self::Extension2|+(self::Extension2|[](#t323{self::Class2}, #t324), 1) in let final void #t326 = self::Extension2|[]=(#t323{self::Class2}, #t324, #t325) in #t325;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329{self::Class}, self::Extension|+(self::Extension|get#field(#t329{self::Class}), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330{self::Class}), 0) in let final void #t332 = self::Extension|set#field(#t330{self::Class}, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339{self::Class}, self::Extension|+(self::Extension|get#field(#t339{self::Class}), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340{self::Class}) in let final self::Class? #t342 = let final self::Class? #t343 = self::Extension|+(#t341, 1) in let final void #t344 = self::Extension|set#field(#t340{self::Class}, #t343) in #t343 in #t341;
-  let final self::Class? #t345 = c in #t345.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t346 = self::Extension|+(self::Extension|get#field(#t345{self::Class}), 1) in let final void #t347 = self::Extension|set#field(#t345{self::Class}, #t346) in #t346;
-  c = let final self::Class? #t348 = c in #t348.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t349 = self::Extension|+(self::Extension|get#field(#t348{self::Class}), 1) in let final void #t350 = self::Extension|set#field(#t348{self::Class}, #t349) in #t349;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t327 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+  throws(() => Extension1(n1)?.nonNullable1 + 0);
+                                            ^" in self::Extension1|+(let final self::Class1? #t328 = n1 in #t328.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t328{self::Class1}), 0));
+  self::throws(() → self::Class1? => let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+  throws(() => -Extension1(n1)?.nonNullable1);
+               ^" in self::Extension1|unary-(let final self::Class1? #t330 = n1 in #t330.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t330{self::Class1})));
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t331{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t331{self::Class2}), 0));
+  nullable2 = let final self::Class2? #t332 = n2 in #t332.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t333 = self::Extension2|+(self::Extension2|get#nonNullable2(#t332{self::Class2}), 0) in let final void #t334 = self::Extension2|set#nonNullable2(#t332{self::Class2}, #t333) in #t333;
+  let final self::Class2? #t335 = n2 in #t335.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t336 = self::Extension2|get#nonNullable2(#t335{self::Class2}) in self::Extension2|set#nonNullable2(#t336, self::Extension2|+(self::Extension2|get#nonNullable2(#t336), 0));
+  nullable2 = let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t338 = self::Extension2|get#nonNullable2(#t337{self::Class2}) in let final self::Class2 #t339 = self::Extension2|+(self::Extension2|get#nonNullable2(#t338), 0) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, #t339) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t341{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t341{self::Class2}), 1));
+  nullable2 = let final self::Class2? #t342 = n2 in #t342.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t343 = self::Extension2|get#nonNullable2(#t342{self::Class2}) in let final self::Class2 #t344 = let final self::Class2 #t345 = self::Extension2|+(#t343, 1) in let final void #t346 = self::Extension2|set#nonNullable2(#t342{self::Class2}, #t345) in #t345 in #t343;
+  let final self::Class2? #t347 = n2 in #t347.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t348 = self::Extension2|+(self::Extension2|get#nonNullable2(#t347{self::Class2}), 1) in let final void #t349 = self::Extension2|set#nonNullable2(#t347{self::Class2}, #t348) in #t348;
+  nullable2 = let final self::Class2? #t350 = n2 in #t350.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t351 = self::Extension2|+(self::Extension2|get#nonNullable2(#t350{self::Class2}), 1) in let final void #t352 = self::Extension2|set#nonNullable2(#t350{self::Class2}, #t351) in #t351;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t351 = c in #t351.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t351{self::Class}).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t351{self::Class}, c{self::Class}) : null;
-  c = let final self::Class? #t352 = c in #t352.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t353 = self::Extension|get#field(#t352{self::Class}) in #t353.{core::Object::==}(null) ?{self::Class} let final self::Class #t354 = c{self::Class} in let final void #t355 = self::Extension|set#field(#t352{self::Class}, #t354) in #t354 : #t353{self::Class};
-  let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in self::Extension|get#field(#t357).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t357, c{self::Class}) : null;
-  c = let final self::Class #t358 = c{self::Class} in #t358.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t359 = self::Extension|get#property(#t358) in let final self::Class? #t360 = self::Extension|get#field(#t359) in #t360.{core::Object::==}(null) ?{self::Class} let final self::Class #t361 = c{self::Class} in let final void #t362 = self::Extension|set#field(#t359, #t361) in #t361 : #t360{self::Class};
-  let final self::Class #t363 = c{self::Class} in #t363.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t364 = self::Extension|get#field(#t363) in let final self::Class #t365 = c{self::Class} in self::Extension|[](#t364, #t365).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t364, #t365, c{self::Class}) : null;
-  c = let final self::Class #t366 = c{self::Class} in #t366.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t367 = self::Extension|get#field(#t366) in let final self::Class #t368 = c{self::Class} in let final self::Class? #t369 = self::Extension|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class} let final self::Class #t370 = c{self::Class} in let final void #t371 = self::Extension|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t353 = n1 in #t353.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t353).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t353, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nullable1(#t354) in #t355.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t356 = n1{self::Class1} in let final void #t357 = self::Extension1|set#nullable1(#t354, #t356) in #t356 : #t355{self::Class1};
+  let final self::Class1? #t358 = n1 in #t358.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t359 = self::Extension1|get#nonNullable1(#t358{self::Class1}) in self::Extension1|get#nullable1(#t359{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t359{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t360 = n1 in #t360.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t361 = self::Extension1|get#nonNullable1(#t360{self::Class1}) in let final self::Class1? #t362 = self::Extension1|get#nullable1(#t361{self::Class1}) in #t362.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t363 = n1{self::Class1} in let final void #t364 = self::Extension1|set#nullable1(#t361{self::Class1}, #t363) in #t363 : #t362{self::Class1};
+  let final self::Class1? #t365 = n1 in #t365.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t366 = self::Extension1|get#nonNullable1(#t365{self::Class1}) in let final self::Class1 #t367 = n1{self::Class1} in self::Extension1|[](#t366, #t367).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t366, #t367, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t368 = n1 in #t368.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t369 = self::Extension1|get#nonNullable1(#t368{self::Class1}) in let final self::Class1 #t370 = n1{self::Class1} in let final self::Class1? #t371 = self::Extension1|[](#t369, #t370) in #t371.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t372 = n1{self::Class1} in let final void #t373 = self::Extension1|[]=(#t369, #t370, #t372) in #t372 : #t371{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
index 7ce7211..d564c89 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.expect
@@ -1,192 +1,277 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+//                                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+//                                                       ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => Extension1(n1)?.nonNullable1 + 0);
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => -Extension1(n1)?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t35 = self::Extension|get#field(#t34) in #t35.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t35{self::Class});
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t36, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t38 = self::Extension|get#field(new self::Class::•()) in let final void #t39 = self::Extension|set#field(#t37, #t38) in #t38;
-  let final self::Class? #t40 = c in #t40.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t40{self::Class}, let final self::Class #t41 = new self::Class::•() in let final void #t42 = self::Extension|set#field(new self::Class::•(), #t41) in #t41);
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t44 = let final self::Class #t45 = new self::Class::•() in let final void #t46 = self::Extension|set#field(new self::Class::•(), #t45) in #t45 in let final void #t47 = self::Extension|set#field(#t43{self::Class}, #t44) in #t44;
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t48, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t50 = self::Extension|method(new self::Class::•()) in let final void #t51 = self::Extension|set#field(#t49, #t50) in #t50;
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t52));
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t53), new self::Class::•());
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t54));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t55)));
-  let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), new self::Class::•());
-  c = let final self::Class #t57 = c{self::Class} in #t57.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t58 = new self::Class::•() in let final void #t59 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t57)), #t58) in #t58;
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t60)));
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t61, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t63 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t64 = self::Extension|set#field(#t62, #t63) in #t63;
-  let final self::Class? #t65 = c in #t65.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t65{self::Class}, let final self::Class #t66 = new self::Class::•() in let final void #t67 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t66) in #t66);
-  c = let final self::Class? #t68 = c in #t68.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t69 = let final self::Class #t70 = new self::Class::•() in let final void #t71 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t70) in #t70 in let final void #t72 = self::Extension|set#field(#t68{self::Class}, #t69) in #t69;
-  let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t73, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t74 = c{self::Class} in #t74.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t75 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t76 = self::Extension|set#field(#t74, #t75) in #t75;
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t77)));
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t78)), new self::Class::•());
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t80 = self::Extension|get#field(self::Extension|method(#t79)) in #t80.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t80{self::Class});
-  let final self::Class #t81 = c{self::Class} in #t81.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t81), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t82 = c{self::Class} in #t82.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t83 = self::Extension|get#field(new self::Class::•()) in let final void #t84 = self::Extension|set#field(self::Extension|get#property(#t82), #t83) in #t83;
-  let final self::Class? #t85 = c in #t85.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t85{self::Class}), let final self::Class #t86 = new self::Class::•() in let final void #t87 = self::Extension|set#field(new self::Class::•(), #t86) in #t86);
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t89 = let final self::Class #t90 = new self::Class::•() in let final void #t91 = self::Extension|set#field(new self::Class::•(), #t90) in #t90 in let final void #t92 = self::Extension|set#field(self::Extension|get#property(#t88{self::Class}), #t89) in #t89;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t93), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t94 = c{self::Class} in #t94.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t95 = self::Extension|method(new self::Class::•()) in let final void #t96 = self::Extension|set#field(self::Extension|get#property(#t94), #t95) in #t95;
-  let final self::Class #t97 = c{self::Class} in #t97.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t97, let final self::Class? #t98 = self::Extension|get#field(new self::Class::•()) in let final void #t99 = self::Extension|set#field(new self::Class::•(), #t98) in #t98);
-  c = let final self::Class #t100 = c{self::Class} in #t100.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t101 = let final self::Class? #t102 = self::Extension|get#field(new self::Class::•()) in let final void #t103 = self::Extension|set#field(new self::Class::•(), #t102) in #t102 in let final void #t104 = self::Extension|set#field(#t100, #t101) in #t101;
-  let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t105{self::Class}, let final self::Class #t106 = let final self::Class #t107 = new self::Class::•() in let final void #t108 = self::Extension|set#field(new self::Class::•(), #t107) in #t107 in let final void #t109 = self::Extension|set#field(new self::Class::•(), #t106) in #t106);
-  c = let final self::Class? #t110 = c in #t110.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t111 = let final self::Class #t112 = let final self::Class #t113 = new self::Class::•() in let final void #t114 = self::Extension|set#field(new self::Class::•(), #t113) in #t113 in let final void #t115 = self::Extension|set#field(new self::Class::•(), #t112) in #t112 in let final void #t116 = self::Extension|set#field(#t110{self::Class}, #t111) in #t111;
-  let final self::Class #t117 = c{self::Class} in #t117.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t117, let final self::Class #t118 = self::Extension|method(new self::Class::•()) in let final void #t119 = self::Extension|set#field(new self::Class::•(), #t118) in #t118);
-  c = let final self::Class #t120 = c{self::Class} in #t120.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t121 = let final self::Class #t122 = self::Extension|method(new self::Class::•()) in let final void #t123 = self::Extension|set#field(new self::Class::•(), #t122) in #t122 in let final void #t124 = self::Extension|set#field(#t120, #t121) in #t121;
-  let final self::Class #t125 = c{self::Class} in #t125.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t125), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t126 = c{self::Class} in #t126.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t127 = self::Extension|get#field(new self::Class::•()) in let final void #t128 = self::Extension|set#field(self::Extension|method(#t126), #t127) in #t127;
-  let final self::Class? #t129 = c in #t129.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t129{self::Class}), let final self::Class #t130 = new self::Class::•() in let final void #t131 = self::Extension|set#field(new self::Class::•(), #t130) in #t130);
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t133 = let final self::Class #t134 = new self::Class::•() in let final void #t135 = self::Extension|set#field(new self::Class::•(), #t134) in #t134 in let final void #t136 = self::Extension|set#field(self::Extension|method(#t132{self::Class}), #t133) in #t133;
-  let final self::Class #t137 = c{self::Class} in #t137.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t137), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t138 = c{self::Class} in #t138.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t139 = self::Extension|method(new self::Class::•()) in let final void #t140 = self::Extension|set#field(self::Extension|method(#t138), #t139) in #t139;
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|get#property(#t141)));
-  let final self::Class #t142 = c{self::Class} in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t142)), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t144 = new self::Class::•() in let final void #t145 = self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t143)), #t144) in #t144;
-  let final self::Class #t146 = c{self::Class} in #t146.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|get#property(#t146)));
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t147, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t148 = c{self::Class} in #t148.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t149 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t150 = self::Extension|set#field(#t148, #t149) in #t149;
-  let final self::Class? #t151 = c in #t151.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t151{self::Class}, let final self::Class #t152 = new self::Class::•() in let final void #t153 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t152) in #t152);
-  c = let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t155 = let final self::Class #t156 = new self::Class::•() in let final void #t157 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t156) in #t156 in let final void #t158 = self::Extension|set#field(#t154{self::Class}, #t155) in #t155;
-  let final self::Class #t159 = c{self::Class} in #t159.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t159, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t160 = c{self::Class} in #t160.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t161 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t162 = self::Extension|set#field(#t160, #t161) in #t161;
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t163)));
-  let final self::Class #t164 = c{self::Class} in #t164.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t164)), new self::Class::•());
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t167 = self::Extension|method(#t166) in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t167);
-  let final self::Class? #t168 = let final self::Class? #t169 = let final self::Class #t170 = c{self::Class} in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t170) in #t169.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t169{self::Class}) in #t168.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t168{self::Class});
-  let final self::Class? #t171 = let final self::Class #t172 = c{self::Class} in #t172.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t172) in #t171.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t171{self::Class});
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t20 = new self::Class1::•() in let final void #t21 = self::Extension1|set#nullable1(#t19{self::Class1}, #t20) in #t20));
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t22{self::Class1})));
+  nullable1 = let final self::Class1? #t23 = n1 in #t23.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t24 = new self::Class1::•() in let final void #t25 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t23{self::Class1}), #t24) in #t24;
+  nullable1 = let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = self::Extension1|get#nullable1(#t26{self::Class1}) in #t27.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t28 = new self::Class1::•() in let final void #t29 = self::Extension1|set#nullable1(#t27{self::Class1}, #t28) in #t28;
+  nullable1 = let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t31 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t30{self::Class1})) in #t31.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t32 = new self::Class1::•() in let final void #t33 = self::Extension1|set#nullable1(#t31{self::Class1}, #t32) in #t32;
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t35 = self::Extension1|get#nullable1(#t34{self::Class1}) in #t35.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t35{self::Class1});
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t36{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t38 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t39 = self::Extension1|set#nullable1(#t37{self::Class1}, #t38) in #t38;
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t40{self::Class1}, let final self::Class1 #t41 = new self::Class1::•() in let final void #t42 = self::Extension1|set#nullable1(new self::Class1::•(), #t41) in #t41);
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t44 = let final self::Class1 #t45 = new self::Class1::•() in let final void #t46 = self::Extension1|set#nullable1(new self::Class1::•(), #t45) in #t45 in let final void #t47 = self::Extension1|set#nullable1(#t43{self::Class1}, #t44) in #t44;
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t48{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t50 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t51 = self::Extension1|set#nullable1(#t49{self::Class1}, #t50) in #t50;
+  let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t52{self::Class1}));
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t53{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t55{self::Class1})));
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t56{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t58 = new self::Class1::•() in let final void #t59 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})), #t58) in #t58;
+  let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t61 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t60{self::Class1})) in #t61.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t61{self::Class1});
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t62{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t64 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t65 = self::Extension1|set#nullable1(#t63{self::Class1}, #t64) in #t64;
+  let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t66{self::Class1}, let final self::Class1 #t67 = new self::Class1::•() in let final void #t68 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t67) in #t67);
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t70 = let final self::Class1 #t71 = new self::Class1::•() in let final void #t72 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t71) in #t71 in let final void #t73 = self::Extension1|set#nullable1(#t69{self::Class1}, #t70) in #t70;
+  let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t74{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t76 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t77 = self::Extension1|set#nullable1(#t75{self::Class1}, #t76) in #t76;
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t78{self::Class1})));
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t79{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t81{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t84 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t82{self::Class1}), #t83) in #t83;
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t85{self::Class1}), let final self::Class1 #t86 = new self::Class1::•() in let final void #t87 = self::Extension1|set#nullable1(new self::Class1::•(), #t86) in #t86);
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = let final self::Class1 #t90 = new self::Class1::•() in let final void #t91 = self::Extension1|set#nullable1(new self::Class1::•(), #t90) in #t90 in let final void #t92 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t88{self::Class1}), #t89) in #t89;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t93{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t94 = n1 in #t94.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t95 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t96 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t94{self::Class1}), #t95) in #t95;
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t97{self::Class1}, let final self::Class1? #t98 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t99 = self::Extension1|set#nullable1(new self::Class1::•(), #t98) in #t98);
+  nullable1 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t101 = let final self::Class1? #t102 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t103 = self::Extension1|set#nullable1(new self::Class1::•(), #t102) in #t102 in let final void #t104 = self::Extension1|set#nullable1(#t100{self::Class1}, #t101) in #t101;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t105{self::Class1}, let final self::Class1 #t106 = let final self::Class1 #t107 = new self::Class1::•() in let final void #t108 = self::Extension1|set#nullable1(new self::Class1::•(), #t107) in #t107 in let final void #t109 = self::Extension1|set#nullable1(new self::Class1::•(), #t106) in #t106);
+  nullable1 = let final self::Class1? #t110 = n1 in #t110.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t111 = let final self::Class1 #t112 = let final self::Class1 #t113 = new self::Class1::•() in let final void #t114 = self::Extension1|set#nullable1(new self::Class1::•(), #t113) in #t113 in let final void #t115 = self::Extension1|set#nullable1(new self::Class1::•(), #t112) in #t112 in let final void #t116 = self::Extension1|set#nullable1(#t110{self::Class1}, #t111) in #t111;
+  let final self::Class1? #t117 = n1 in #t117.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t117{self::Class1}, let final self::Class1 #t118 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t119 = self::Extension1|set#nullable1(new self::Class1::•(), #t118) in #t118);
+  nullable1 = let final self::Class1? #t120 = n1 in #t120.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t121 = let final self::Class1 #t122 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t123 = self::Extension1|set#nullable1(new self::Class1::•(), #t122) in #t122 in let final void #t124 = self::Extension1|set#nullable1(#t120{self::Class1}, #t121) in #t121;
+  let final self::Class1? #t125 = n1 in #t125.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t125{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t126 = n1 in #t126.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t127 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t128 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t126{self::Class1}), #t127) in #t127;
+  let final self::Class1? #t129 = n1 in #t129.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t129{self::Class1}), let final self::Class1 #t130 = new self::Class1::•() in let final void #t131 = self::Extension1|set#nullable1(new self::Class1::•(), #t130) in #t130);
+  nullable1 = let final self::Class1? #t132 = n1 in #t132.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t133 = let final self::Class1 #t134 = new self::Class1::•() in let final void #t135 = self::Extension1|set#nullable1(new self::Class1::•(), #t134) in #t134 in let final void #t136 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t132{self::Class1}), #t133) in #t133;
+  let final self::Class1? #t137 = n1 in #t137.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t137{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t139 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t140 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t138{self::Class1}), #t139) in #t139;
+  let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t141{self::Class1})));
+  let final self::Class1? #t142 = n1 in #t142.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t142{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t144 = new self::Class1::•() in let final void #t145 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})), #t144) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t146{self::Class1})));
+  let final self::Class1? #t147 = n1 in #t147.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t147{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t149 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t150 = self::Extension1|set#nullable1(#t148{self::Class1}, #t149) in #t149;
+  let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t151{self::Class1}, let final self::Class1 #t152 = new self::Class1::•() in let final void #t153 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t152) in #t152);
+  nullable1 = let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t155 = let final self::Class1 #t156 = new self::Class1::•() in let final void #t157 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t156) in #t156 in let final void #t158 = self::Extension1|set#nullable1(#t154{self::Class1}, #t155) in #t155;
+  let final self::Class1? #t159 = n1 in #t159.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t159{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t160 = n1 in #t160.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t161 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t162 = self::Extension1|set#nullable1(#t160{self::Class1}, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t163{self::Class1})));
+  let final self::Class1? #t164 = n1 in #t164.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t164{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t167 = self::Extension1|nonNullable1Method(#t166{self::Class1}) in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t167{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t173 = c in #t173.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t173{self::Class}, c{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t174{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t176 = self::Extension|[](#t175{self::Class}, c{self::Class}) in #t176.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t176{self::Class});
-  let final self::Class? #t177 = c in #t177.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t177{self::Class}), c{self::Class});
-  let final self::Class? #t178 = c in #t178.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t178{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t180 = self::Extension|get#field(#t179{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class #t182 = new self::Class::•() in let final void #t183 = self::Extension|[]=(#t180, #t181, #t182) in #t182;
-  let final self::Class #t184 = c{self::Class} in #t184.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t185 = self::Extension|[](self::Extension|get#field(#t184), c{self::Class}) in #t185.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t185{self::Class});
-  let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in self::Extension|[]=(#t187, #t188, self::Extension|+(self::Extension|[](#t187, #t188), 0));
-  c = let final self::Class #t189 = c{self::Class} in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = self::Extension|get#field(#t189) in let final self::Class #t191 = c{self::Class} in let final self::Class? #t192 = self::Extension|+(self::Extension|[](#t190, #t191), 0) in let final void #t193 = self::Extension|[]=(#t190, #t191, #t192) in #t192;
-  let final self::Class? #t194 = c in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in self::Extension|[](#t194{self::Class}, #t195).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t194{self::Class}, #t195, c{self::Class}) : null;
-  c = let final self::Class? #t196 = c in #t196.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t197 = c{self::Class} in let final self::Class? #t198 = self::Extension|[](#t196{self::Class}, #t197) in #t198.{core::Object::==}(null) ?{self::Class} let final self::Class #t199 = c{self::Class} in let final void #t200 = self::Extension|[]=(#t196{self::Class}, #t197, #t199) in #t199 : #t198{self::Class};
-  let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t202 = c{self::Class} in self::Extension|[]=(#t201, #t202, self::Extension|+(self::Extension|[](#t201, #t202), 0));
-  c = let final self::Class #t203 = c{self::Class} in #t203.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t204 = c{self::Class} in let final self::Class? #t205 = self::Extension|+(self::Extension|[](#t203, #t204), 0) in let final void #t206 = self::Extension|[]=(#t203, #t204, #t205) in #t205;
-  let final self::Class? #t207 = c in #t207.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t208 = c{self::Class} in self::Extension|[]=(#t207{self::Class}, #t208, self::Extension|+(self::Extension|[](#t207{self::Class}, #t208), 0));
-  c = let final self::Class? #t209 = c in #t209.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t210 = c{self::Class} in let final self::Class? #t211 = self::Extension|+(self::Extension|[](#t209{self::Class}, #t210), 0) in let final void #t212 = self::Extension|[]=(#t209{self::Class}, #t210, #t211) in #t211;
-  let final self::Class? #t213 = c in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t214 = c{self::Class} in self::Extension|[]=(#t213{self::Class}, #t214, self::Extension|+(self::Extension|[](#t213{self::Class}, #t214), 1));
-  c = let final self::Class? #t215 = c in #t215.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t216 = c{self::Class} in let final self::Class? #t217 = self::Extension|[](#t215{self::Class}, #t216) in let final void #t218 = self::Extension|[]=(#t215{self::Class}, #t216, self::Extension|+(#t217, 1)) in #t217;
-  let final self::Class? #t219 = c in #t219.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t219{self::Class}, c{self::Class});
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t168{self::Class1}, nullable1);
+  let final self::Class1? #t169 = n1 in #t169.{core::Object::==}(null) ?{void} null : self::Extension1|[]=(#t169{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t171 = self::Extension1|[](#t170{self::Class1}, nullable1) in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t171{self::Class1});
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t172{self::Class1}), nullable1);
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t173{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t175 = self::Extension1|get#nonNullable1(#t174{self::Class1}) in let final self::Class1? #t176 = nullable1 in let final self::Class1 #t177 = new self::Class1::•() in let final void #t178 = self::Extension1|[]=(#t175, #t176, #t177) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t180 = self::Extension1|[](self::Extension1|get#nonNullable1(#t179{self::Class1}), nullable1) in #t180.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t180{self::Class1});
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = self::Extension1|get#nonNullable2(#t181{self::Class1}) in let final self::Class2? #t183 = nullable2 in self::Extension2|[]=(#t182, #t183, self::Extension2|+(self::Extension2|[](#t182, #t183), 0));
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = self::Extension1|get#nonNullable2(#t184{self::Class1}) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = self::Extension2|+(self::Extension2|[](#t185, #t186), 0) in let final void #t188 = self::Extension2|[]=(#t185, #t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = nullable1 in self::Extension1|[](#t189{self::Class1}, #t190).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t189{self::Class1}, #t190, nullable1) : null;
+  nullable1 = let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in let final self::Class1? #t193 = self::Extension1|[](#t191{self::Class1}, #t192) in #t193.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t194 = nullable1 in let final void #t195 = self::Extension1|[]=(#t191{self::Class1}, #t192, #t194) in #t194 : #t193{self::Class1};
+  let final self::Class2? #t196 = n2 in #t196.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t197 = nullable2 in self::Extension2|[]=(#t196{self::Class2}, #t197, self::Extension2|+(self::Extension2|[](#t196{self::Class2}, #t197), 0));
+  nullable2 = let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in let final self::Class2 #t200 = self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0) in let final void #t201 = self::Extension2|[]=(#t198{self::Class2}, #t199, #t200) in #t200;
+  let final self::Class2? #t202 = n2 in #t202.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t203 = nullable2 in self::Extension2|[]=(#t202{self::Class2}, #t203, self::Extension2|+(self::Extension2|[](#t202{self::Class2}, #t203), 0));
+  nullable2 = let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in let final self::Class2 #t206 = self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0) in let final void #t207 = self::Extension2|[]=(#t204{self::Class2}, #t205, #t206) in #t206;
+  let final self::Class2? #t208 = n2 in #t208.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t209 = nullable2 in self::Extension2|[]=(#t208{self::Class2}, #t209, self::Extension2|+(self::Extension2|[](#t208{self::Class2}, #t209), 1));
+  nullable2 = let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in let final self::Class2 #t212 = self::Extension2|[](#t210{self::Class2}, #t211) in let final void #t213 = self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(#t212, 1)) in #t212;
+  let final self::Class2? #t214 = n2 in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in let final self::Class2 #t216 = self::Extension2|+(self::Extension2|[](#t214{self::Class2}, #t215), 1) in let final void #t217 = self::Extension2|[]=(#t214{self::Class2}, #t215, #t216) in #t216;
+  nullable2 = let final self::Class2? #t218 = n2 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = nullable2 in let final self::Class2 #t220 = self::Extension2|+(self::Extension2|[](#t218{self::Class2}, #t219), 1) in let final void #t221 = self::Extension2|[]=(#t218{self::Class2}, #t219, #t220) in #t220;
+  let final self::Class1? #t222 = n1 in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t223 = self::Extension1|get#nonNullable2(#t222{self::Class1}) in let final self::Class2? #t224 = nullable2 in self::Extension2|[]=(#t223, #t224, self::Extension2|+(self::Extension2|[](#t223, #t224), 1));
+  nullable2 = let final self::Class1? #t225 = n1 in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t226 = self::Extension1|get#nonNullable2(#t225{self::Class1}) in let final self::Class2? #t227 = nullable2 in let final self::Class2 #t228 = self::Extension2|[](#t226, #t227) in let final void #t229 = self::Extension2|[]=(#t226, #t227, self::Extension2|+(#t228, 1)) in #t228;
+  let final self::Class1? #t230 = n1 in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t231 = self::Extension1|get#nonNullable2(#t230{self::Class1}) in let final self::Class2? #t232 = nullable2 in let final self::Class2 #t233 = self::Extension2|+(self::Extension2|[](#t231, #t232), 1) in let final void #t234 = self::Extension2|[]=(#t231, #t232, #t233) in #t233;
+  nullable2 = let final self::Class1? #t235 = n1 in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t236 = self::Extension1|get#nonNullable2(#t235{self::Class1}) in let final self::Class2? #t237 = nullable2 in let final self::Class2 #t238 = self::Extension2|+(self::Extension2|[](#t236, #t237), 1) in let final void #t239 = self::Extension2|[]=(#t236, #t237, #t238) in #t238;
+  let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t240{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t241 = n1 in #t241.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t241{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2) in let final self::Class2? #t244 = nullable2 in let final self::Class2 #t245 = new self::Class2::•() in let final void #t246 = self::Extension2|[]=(#t243, #t244, #t245) in #t245;
+  let final self::Class1? #t247 = n1 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t248 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t247{self::Class1}), nullable2), nullable2) in #t248.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t248{self::Class2});
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2) in let final self::Class2? #t251 = nullable2 in self::Extension2|[]=(#t250, #t251, self::Extension2|+(self::Extension2|[](#t250, #t251), 0));
+  nullable2 = let final self::Class1? #t252 = n1 in #t252.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t253 = self::Extension2|[](self::Extension1|get#nonNullable2(#t252{self::Class1}), nullable2) in let final self::Class2? #t254 = nullable2 in let final self::Class2 #t255 = self::Extension2|+(self::Extension2|[](#t253, #t254), 0) in let final void #t256 = self::Extension2|[]=(#t253, #t254, #t255) in #t255;
+  let final self::Class1? #t257 = n1 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = self::Extension2|[](self::Extension1|get#nonNullable2(#t257{self::Class1}), nullable2) in let final self::Class2? #t259 = nullable2 in self::Extension2|[]=(#t258, #t259, self::Extension2|+(self::Extension2|[](#t258, #t259), 1));
+  nullable2 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = self::Extension2|[](self::Extension1|get#nonNullable2(#t260{self::Class1}), nullable2) in let final self::Class2? #t262 = nullable2 in let final self::Class2 #t263 = self::Extension2|[](#t261, #t262) in let final void #t264 = self::Extension2|[]=(#t261, #t262, self::Extension2|+(#t263, 1)) in #t263;
+  let final self::Class1? #t265 = n1 in #t265.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t266 = self::Extension2|[](self::Extension1|get#nonNullable2(#t265{self::Class1}), nullable2) in let final self::Class2? #t267 = nullable2 in let final self::Class2 #t268 = self::Extension2|+(self::Extension2|[](#t266, #t267), 1) in let final void #t269 = self::Extension2|[]=(#t266, #t267, #t268) in #t268;
+  nullable2 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t271 = self::Extension2|[](self::Extension1|get#nonNullable2(#t270{self::Class1}), nullable2) in let final self::Class2? #t272 = nullable2 in let final self::Class2 #t273 = self::Extension2|+(self::Extension2|[](#t271, #t272), 1) in let final void #t274 = self::Extension2|[]=(#t271, #t272, #t273) in #t273;
+  let final self::Class1? #t275 = n1 in #t275.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t276 = self::Extension1|[](#t275{self::Class1}, nullable1) in #t276.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t276{self::Class1}, nullable1);
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t278{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t281 = nullable1 in let final self::Class1 #t282 = new self::Class1::•() in let final void #t283 = self::Extension1|[]=(#t280{self::Class1}, #t281, #t282) in #t282;
+  let final self::Class1? #t284 = n1 in #t284.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t285 = self::Extension1|[](#t284{self::Class1}, nullable1) in #t285.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t286 = self::Extension1|[](#t285{self::Class1}, nullable1) in #t286.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t286{self::Class1});
+  nullable1 = let final self::Class1? #t287 = n1 in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t289 = self::Extension1|[](#t288{self::Class1}, nullable1) in #t289.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t289{self::Class1});
+  let final self::Class1? #t290 = n1 in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t292 = nullable1 in self::Extension1|[](#t291{self::Class1}, #t292).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t291{self::Class1}, #t292, nullable1) : null;
+  nullable1 = let final self::Class1? #t293 = n1 in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = self::Extension1|[](#t293{self::Class1}, nullable1) in #t294.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t295 = nullable1 in let final self::Class1? #t296 = self::Extension1|[](#t294{self::Class1}, #t295) in #t296.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t297 = nullable1 in let final void #t298 = self::Extension1|[]=(#t294{self::Class1}, #t295, #t297) in #t297 : #t296{self::Class1};
+  let final self::Class3? #t299 = n3 in #t299.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t300 = self::Extension3|[](#t299{self::Class3}, nullable3) in #t300.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t301 = nullable2 in self::Extension2|[]=(#t300{self::Class2}, #t301, self::Extension2|+(self::Extension2|[](#t300{self::Class2}, #t301), 0));
+  nullable2 = let final self::Class3? #t302 = n3 in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = self::Extension3|[](#t302{self::Class3}, nullable3) in #t303.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t304 = nullable2 in let final self::Class2 #t305 = self::Extension2|+(self::Extension2|[](#t303{self::Class2}, #t304), 0) in let final void #t306 = self::Extension2|[]=(#t303{self::Class2}, #t304, #t305) in #t305;
+  let final self::Class3? #t307 = n3 in #t307.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t308 = self::Extension3|[](#t307{self::Class3}, nullable3) in #t308.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t309 = nullable2 in self::Extension2|[]=(#t308{self::Class2}, #t309, self::Extension2|+(self::Extension2|[](#t308{self::Class2}, #t309), 1));
+  nullable2 = let final self::Class3? #t310 = n3 in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = self::Extension3|[](#t310{self::Class3}, nullable3) in #t311.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t312 = nullable2 in let final self::Class2 #t313 = self::Extension2|[](#t311{self::Class2}, #t312) in let final void #t314 = self::Extension2|[]=(#t311{self::Class2}, #t312, self::Extension2|+(#t313, 1)) in #t313;
+  let final self::Class3? #t315 = n3 in #t315.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t316 = self::Extension3|[](#t315{self::Class3}, nullable3) in #t316.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t317 = nullable2 in let final self::Class2 #t318 = self::Extension2|+(self::Extension2|[](#t316{self::Class2}, #t317), 1) in let final void #t319 = self::Extension2|[]=(#t316{self::Class2}, #t317, #t318) in #t318;
+  nullable2 = let final self::Class3? #t320 = n3 in #t320.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t321 = self::Extension3|[](#t320{self::Class3}, nullable3) in #t321.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t322 = nullable2 in let final self::Class2 #t323 = self::Extension2|+(self::Extension2|[](#t321{self::Class2}, #t322), 1) in let final void #t324 = self::Extension2|[]=(#t321{self::Class2}, #t322, #t323) in #t323;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329{self::Class}, self::Extension|+(self::Extension|get#field(#t329{self::Class}), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330{self::Class}), 0) in let final void #t332 = self::Extension|set#field(#t330{self::Class}, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339{self::Class}, self::Extension|+(self::Extension|get#field(#t339{self::Class}), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340{self::Class}) in let final self::Class? #t342 = let final self::Class? #t343 = self::Extension|+(#t341, 1) in let final void #t344 = self::Extension|set#field(#t340{self::Class}, #t343) in #t343 in #t341;
-  let final self::Class? #t345 = c in #t345.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t346 = self::Extension|+(self::Extension|get#field(#t345{self::Class}), 1) in let final void #t347 = self::Extension|set#field(#t345{self::Class}, #t346) in #t346;
-  c = let final self::Class? #t348 = c in #t348.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t349 = self::Extension|+(self::Extension|get#field(#t348{self::Class}), 1) in let final void #t350 = self::Extension|set#field(#t348{self::Class}, #t349) in #t349;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => self::Extension1|+(let final self::Class1? #t325 = n1 in #t325.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t325{self::Class1}), 0));
+  self::throws(() → self::Class1? => self::Extension1|unary-(let final self::Class1? #t326 = n1 in #t326.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t326{self::Class1})));
+  let final self::Class2? #t327 = n2 in #t327.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t327{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t327{self::Class2}), 0));
+  nullable2 = let final self::Class2? #t328 = n2 in #t328.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t329 = self::Extension2|+(self::Extension2|get#nonNullable2(#t328{self::Class2}), 0) in let final void #t330 = self::Extension2|set#nonNullable2(#t328{self::Class2}, #t329) in #t329;
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t332 = self::Extension2|get#nonNullable2(#t331{self::Class2}) in self::Extension2|set#nonNullable2(#t332, self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0));
+  nullable2 = let final self::Class2? #t333 = n2 in #t333.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t334 = self::Extension2|get#nonNullable2(#t333{self::Class2}) in let final self::Class2 #t335 = self::Extension2|+(self::Extension2|get#nonNullable2(#t334), 0) in let final void #t336 = self::Extension2|set#nonNullable2(#t334, #t335) in #t335;
+  let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t337{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t337{self::Class2}), 1));
+  nullable2 = let final self::Class2? #t338 = n2 in #t338.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t339 = self::Extension2|get#nonNullable2(#t338{self::Class2}) in let final self::Class2 #t340 = let final self::Class2 #t341 = self::Extension2|+(#t339, 1) in let final void #t342 = self::Extension2|set#nonNullable2(#t338{self::Class2}, #t341) in #t341 in #t339;
+  let final self::Class2? #t343 = n2 in #t343.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t344 = self::Extension2|+(self::Extension2|get#nonNullable2(#t343{self::Class2}), 1) in let final void #t345 = self::Extension2|set#nonNullable2(#t343{self::Class2}, #t344) in #t344;
+  nullable2 = let final self::Class2? #t346 = n2 in #t346.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t347 = self::Extension2|+(self::Extension2|get#nonNullable2(#t346{self::Class2}), 1) in let final void #t348 = self::Extension2|set#nonNullable2(#t346{self::Class2}, #t347) in #t347;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t351 = c in #t351.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t351{self::Class}).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t351{self::Class}, c{self::Class}) : null;
-  c = let final self::Class? #t352 = c in #t352.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t353 = self::Extension|get#field(#t352{self::Class}) in #t353.{core::Object::==}(null) ?{self::Class} let final self::Class #t354 = c{self::Class} in let final void #t355 = self::Extension|set#field(#t352{self::Class}, #t354) in #t354 : #t353{self::Class};
-  let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in self::Extension|get#field(#t357).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t357, c{self::Class}) : null;
-  c = let final self::Class #t358 = c{self::Class} in #t358.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t359 = self::Extension|get#property(#t358) in let final self::Class? #t360 = self::Extension|get#field(#t359) in #t360.{core::Object::==}(null) ?{self::Class} let final self::Class #t361 = c{self::Class} in let final void #t362 = self::Extension|set#field(#t359, #t361) in #t361 : #t360{self::Class};
-  let final self::Class #t363 = c{self::Class} in #t363.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t364 = self::Extension|get#field(#t363) in let final self::Class #t365 = c{self::Class} in self::Extension|[](#t364, #t365).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t364, #t365, c{self::Class}) : null;
-  c = let final self::Class #t366 = c{self::Class} in #t366.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t367 = self::Extension|get#field(#t366) in let final self::Class #t368 = c{self::Class} in let final self::Class? #t369 = self::Extension|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class} let final self::Class #t370 = c{self::Class} in let final void #t371 = self::Extension|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t349 = n1 in #t349.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t349).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t349, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t350 = n1 in #t350.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t351 = self::Extension1|get#nullable1(#t350) in #t351.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t352 = n1{self::Class1} in let final void #t353 = self::Extension1|set#nullable1(#t350, #t352) in #t352 : #t351{self::Class1};
+  let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nonNullable1(#t354{self::Class1}) in self::Extension1|get#nullable1(#t355{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t355{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t356 = n1 in #t356.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t357 = self::Extension1|get#nonNullable1(#t356{self::Class1}) in let final self::Class1? #t358 = self::Extension1|get#nullable1(#t357{self::Class1}) in #t358.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t359 = n1{self::Class1} in let final void #t360 = self::Extension1|set#nullable1(#t357{self::Class1}, #t359) in #t359 : #t358{self::Class1};
+  let final self::Class1? #t361 = n1 in #t361.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t362 = self::Extension1|get#nonNullable1(#t361{self::Class1}) in let final self::Class1 #t363 = n1{self::Class1} in self::Extension1|[](#t362, #t363).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t362, #t363, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t364 = n1 in #t364.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t365 = self::Extension1|get#nonNullable1(#t364{self::Class1}) in let final self::Class1 #t366 = n1{self::Class1} in let final self::Class1? #t367 = self::Extension1|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t368 = n1{self::Class1} in let final void #t369 = self::Extension1|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
index 7ce7211..d564c89 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.weak.transformed.expect
@@ -1,192 +1,277 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:93:59: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nullable1 = new Class1()).nullable1);
+//                                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:94:55: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (Extension1(n1)?.nonNullable1Method()).nullable1);
+//                                                       ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:250:45: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => Extension1(n1)?.nonNullable1 + 0);
+//                                             ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart:251:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart'.
+//   throws(() => -Extension1(n1)?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t35 = self::Extension|get#field(#t34) in #t35.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t35{self::Class});
-  let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t36, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t37 = c{self::Class} in #t37.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t38 = self::Extension|get#field(new self::Class::•()) in let final void #t39 = self::Extension|set#field(#t37, #t38) in #t38;
-  let final self::Class? #t40 = c in #t40.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t40{self::Class}, let final self::Class #t41 = new self::Class::•() in let final void #t42 = self::Extension|set#field(new self::Class::•(), #t41) in #t41);
-  c = let final self::Class? #t43 = c in #t43.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t44 = let final self::Class #t45 = new self::Class::•() in let final void #t46 = self::Extension|set#field(new self::Class::•(), #t45) in #t45 in let final void #t47 = self::Extension|set#field(#t43{self::Class}, #t44) in #t44;
-  let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t48, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t49 = c{self::Class} in #t49.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t50 = self::Extension|method(new self::Class::•()) in let final void #t51 = self::Extension|set#field(#t49, #t50) in #t50;
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t52));
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t53), new self::Class::•());
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t54));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t55)));
-  let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), new self::Class::•());
-  c = let final self::Class #t57 = c{self::Class} in #t57.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t58 = new self::Class::•() in let final void #t59 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t57)), #t58) in #t58;
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t60)));
-  let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t61, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t62 = c{self::Class} in #t62.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t63 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t64 = self::Extension|set#field(#t62, #t63) in #t63;
-  let final self::Class? #t65 = c in #t65.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t65{self::Class}, let final self::Class #t66 = new self::Class::•() in let final void #t67 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t66) in #t66);
-  c = let final self::Class? #t68 = c in #t68.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t69 = let final self::Class #t70 = new self::Class::•() in let final void #t71 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t70) in #t70 in let final void #t72 = self::Extension|set#field(#t68{self::Class}, #t69) in #t69;
-  let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t73, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t74 = c{self::Class} in #t74.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t75 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t76 = self::Extension|set#field(#t74, #t75) in #t75;
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t77)));
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t78)), new self::Class::•());
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t80 = self::Extension|get#field(self::Extension|method(#t79)) in #t80.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t80{self::Class});
-  let final self::Class #t81 = c{self::Class} in #t81.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t81), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t82 = c{self::Class} in #t82.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t83 = self::Extension|get#field(new self::Class::•()) in let final void #t84 = self::Extension|set#field(self::Extension|get#property(#t82), #t83) in #t83;
-  let final self::Class? #t85 = c in #t85.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t85{self::Class}), let final self::Class #t86 = new self::Class::•() in let final void #t87 = self::Extension|set#field(new self::Class::•(), #t86) in #t86);
-  c = let final self::Class? #t88 = c in #t88.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t89 = let final self::Class #t90 = new self::Class::•() in let final void #t91 = self::Extension|set#field(new self::Class::•(), #t90) in #t90 in let final void #t92 = self::Extension|set#field(self::Extension|get#property(#t88{self::Class}), #t89) in #t89;
-  let final self::Class #t93 = c{self::Class} in #t93.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t93), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t94 = c{self::Class} in #t94.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t95 = self::Extension|method(new self::Class::•()) in let final void #t96 = self::Extension|set#field(self::Extension|get#property(#t94), #t95) in #t95;
-  let final self::Class #t97 = c{self::Class} in #t97.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t97, let final self::Class? #t98 = self::Extension|get#field(new self::Class::•()) in let final void #t99 = self::Extension|set#field(new self::Class::•(), #t98) in #t98);
-  c = let final self::Class #t100 = c{self::Class} in #t100.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t101 = let final self::Class? #t102 = self::Extension|get#field(new self::Class::•()) in let final void #t103 = self::Extension|set#field(new self::Class::•(), #t102) in #t102 in let final void #t104 = self::Extension|set#field(#t100, #t101) in #t101;
-  let final self::Class? #t105 = c in #t105.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t105{self::Class}, let final self::Class #t106 = let final self::Class #t107 = new self::Class::•() in let final void #t108 = self::Extension|set#field(new self::Class::•(), #t107) in #t107 in let final void #t109 = self::Extension|set#field(new self::Class::•(), #t106) in #t106);
-  c = let final self::Class? #t110 = c in #t110.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t111 = let final self::Class #t112 = let final self::Class #t113 = new self::Class::•() in let final void #t114 = self::Extension|set#field(new self::Class::•(), #t113) in #t113 in let final void #t115 = self::Extension|set#field(new self::Class::•(), #t112) in #t112 in let final void #t116 = self::Extension|set#field(#t110{self::Class}, #t111) in #t111;
-  let final self::Class #t117 = c{self::Class} in #t117.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t117, let final self::Class #t118 = self::Extension|method(new self::Class::•()) in let final void #t119 = self::Extension|set#field(new self::Class::•(), #t118) in #t118);
-  c = let final self::Class #t120 = c{self::Class} in #t120.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t121 = let final self::Class #t122 = self::Extension|method(new self::Class::•()) in let final void #t123 = self::Extension|set#field(new self::Class::•(), #t122) in #t122 in let final void #t124 = self::Extension|set#field(#t120, #t121) in #t121;
-  let final self::Class #t125 = c{self::Class} in #t125.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t125), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t126 = c{self::Class} in #t126.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t127 = self::Extension|get#field(new self::Class::•()) in let final void #t128 = self::Extension|set#field(self::Extension|method(#t126), #t127) in #t127;
-  let final self::Class? #t129 = c in #t129.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t129{self::Class}), let final self::Class #t130 = new self::Class::•() in let final void #t131 = self::Extension|set#field(new self::Class::•(), #t130) in #t130);
-  c = let final self::Class? #t132 = c in #t132.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t133 = let final self::Class #t134 = new self::Class::•() in let final void #t135 = self::Extension|set#field(new self::Class::•(), #t134) in #t134 in let final void #t136 = self::Extension|set#field(self::Extension|method(#t132{self::Class}), #t133) in #t133;
-  let final self::Class #t137 = c{self::Class} in #t137.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t137), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t138 = c{self::Class} in #t138.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t139 = self::Extension|method(new self::Class::•()) in let final void #t140 = self::Extension|set#field(self::Extension|method(#t138), #t139) in #t139;
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|get#property(#t141)));
-  let final self::Class #t142 = c{self::Class} in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t142)), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t144 = new self::Class::•() in let final void #t145 = self::Extension|set#field(self::Extension|method(self::Extension|get#property(#t143)), #t144) in #t144;
-  let final self::Class #t146 = c{self::Class} in #t146.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|get#property(#t146)));
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t147, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t148 = c{self::Class} in #t148.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t149 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t150 = self::Extension|set#field(#t148, #t149) in #t149;
-  let final self::Class? #t151 = c in #t151.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t151{self::Class}, let final self::Class #t152 = new self::Class::•() in let final void #t153 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t152) in #t152);
-  c = let final self::Class? #t154 = c in #t154.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t155 = let final self::Class #t156 = new self::Class::•() in let final void #t157 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t156) in #t156 in let final void #t158 = self::Extension|set#field(#t154{self::Class}, #t155) in #t155;
-  let final self::Class #t159 = c{self::Class} in #t159.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t159, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t160 = c{self::Class} in #t160.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t161 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t162 = self::Extension|set#field(#t160, #t161) in #t161;
-  let final self::Class #t163 = c{self::Class} in #t163.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t163)));
-  let final self::Class #t164 = c{self::Class} in #t164.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t164)), new self::Class::•());
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t167 = self::Extension|method(#t166) in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t167);
-  let final self::Class? #t168 = let final self::Class? #t169 = let final self::Class #t170 = c{self::Class} in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t170) in #t169.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t169{self::Class}) in #t168.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t168{self::Class});
-  let final self::Class? #t171 = let final self::Class #t172 = c{self::Class} in #t172.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t172) in #t171.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t171{self::Class});
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t20 = new self::Class1::•() in let final void #t21 = self::Extension1|set#nullable1(#t19{self::Class1}, #t20) in #t20));
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t22{self::Class1})));
+  nullable1 = let final self::Class1? #t23 = n1 in #t23.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t24 = new self::Class1::•() in let final void #t25 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t23{self::Class1}), #t24) in #t24;
+  nullable1 = let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = self::Extension1|get#nullable1(#t26{self::Class1}) in #t27.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t28 = new self::Class1::•() in let final void #t29 = self::Extension1|set#nullable1(#t27{self::Class1}, #t28) in #t28;
+  nullable1 = let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t31 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t30{self::Class1})) in #t31.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t32 = new self::Class1::•() in let final void #t33 = self::Extension1|set#nullable1(#t31{self::Class1}, #t32) in #t32;
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t35 = self::Extension1|get#nullable1(#t34{self::Class1}) in #t35.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t35{self::Class1});
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t36{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t38 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t39 = self::Extension1|set#nullable1(#t37{self::Class1}, #t38) in #t38;
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t40{self::Class1}, let final self::Class1 #t41 = new self::Class1::•() in let final void #t42 = self::Extension1|set#nullable1(new self::Class1::•(), #t41) in #t41);
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t44 = let final self::Class1 #t45 = new self::Class1::•() in let final void #t46 = self::Extension1|set#nullable1(new self::Class1::•(), #t45) in #t45 in let final void #t47 = self::Extension1|set#nullable1(#t43{self::Class1}, #t44) in #t44;
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t48{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t50 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t51 = self::Extension1|set#nullable1(#t49{self::Class1}, #t50) in #t50;
+  let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t52{self::Class1}));
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t53{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t55{self::Class1})));
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t56{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t58 = new self::Class1::•() in let final void #t59 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})), #t58) in #t58;
+  let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t61 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t60{self::Class1})) in #t61.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t61{self::Class1});
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t62{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t64 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t65 = self::Extension1|set#nullable1(#t63{self::Class1}, #t64) in #t64;
+  let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t66{self::Class1}, let final self::Class1 #t67 = new self::Class1::•() in let final void #t68 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t67) in #t67);
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t70 = let final self::Class1 #t71 = new self::Class1::•() in let final void #t72 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t71) in #t71 in let final void #t73 = self::Extension1|set#nullable1(#t69{self::Class1}, #t70) in #t70;
+  let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t74{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t76 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t77 = self::Extension1|set#nullable1(#t75{self::Class1}, #t76) in #t76;
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t78{self::Class1})));
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t79{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t81{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t84 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t82{self::Class1}), #t83) in #t83;
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t85{self::Class1}), let final self::Class1 #t86 = new self::Class1::•() in let final void #t87 = self::Extension1|set#nullable1(new self::Class1::•(), #t86) in #t86);
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = let final self::Class1 #t90 = new self::Class1::•() in let final void #t91 = self::Extension1|set#nullable1(new self::Class1::•(), #t90) in #t90 in let final void #t92 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t88{self::Class1}), #t89) in #t89;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t93{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t94 = n1 in #t94.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t95 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t96 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t94{self::Class1}), #t95) in #t95;
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t97{self::Class1}, let final self::Class1? #t98 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t99 = self::Extension1|set#nullable1(new self::Class1::•(), #t98) in #t98);
+  nullable1 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t101 = let final self::Class1? #t102 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t103 = self::Extension1|set#nullable1(new self::Class1::•(), #t102) in #t102 in let final void #t104 = self::Extension1|set#nullable1(#t100{self::Class1}, #t101) in #t101;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t105{self::Class1}, let final self::Class1 #t106 = let final self::Class1 #t107 = new self::Class1::•() in let final void #t108 = self::Extension1|set#nullable1(new self::Class1::•(), #t107) in #t107 in let final void #t109 = self::Extension1|set#nullable1(new self::Class1::•(), #t106) in #t106);
+  nullable1 = let final self::Class1? #t110 = n1 in #t110.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t111 = let final self::Class1 #t112 = let final self::Class1 #t113 = new self::Class1::•() in let final void #t114 = self::Extension1|set#nullable1(new self::Class1::•(), #t113) in #t113 in let final void #t115 = self::Extension1|set#nullable1(new self::Class1::•(), #t112) in #t112 in let final void #t116 = self::Extension1|set#nullable1(#t110{self::Class1}, #t111) in #t111;
+  let final self::Class1? #t117 = n1 in #t117.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t117{self::Class1}, let final self::Class1 #t118 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t119 = self::Extension1|set#nullable1(new self::Class1::•(), #t118) in #t118);
+  nullable1 = let final self::Class1? #t120 = n1 in #t120.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t121 = let final self::Class1 #t122 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t123 = self::Extension1|set#nullable1(new self::Class1::•(), #t122) in #t122 in let final void #t124 = self::Extension1|set#nullable1(#t120{self::Class1}, #t121) in #t121;
+  let final self::Class1? #t125 = n1 in #t125.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t125{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t126 = n1 in #t126.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t127 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t128 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t126{self::Class1}), #t127) in #t127;
+  let final self::Class1? #t129 = n1 in #t129.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t129{self::Class1}), let final self::Class1 #t130 = new self::Class1::•() in let final void #t131 = self::Extension1|set#nullable1(new self::Class1::•(), #t130) in #t130);
+  nullable1 = let final self::Class1? #t132 = n1 in #t132.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t133 = let final self::Class1 #t134 = new self::Class1::•() in let final void #t135 = self::Extension1|set#nullable1(new self::Class1::•(), #t134) in #t134 in let final void #t136 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t132{self::Class1}), #t133) in #t133;
+  let final self::Class1? #t137 = n1 in #t137.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t137{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t139 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t140 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t138{self::Class1}), #t139) in #t139;
+  let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t141{self::Class1})));
+  let final self::Class1? #t142 = n1 in #t142.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t142{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t144 = new self::Class1::•() in let final void #t145 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})), #t144) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t146{self::Class1})));
+  let final self::Class1? #t147 = n1 in #t147.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t147{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t149 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t150 = self::Extension1|set#nullable1(#t148{self::Class1}, #t149) in #t149;
+  let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t151{self::Class1}, let final self::Class1 #t152 = new self::Class1::•() in let final void #t153 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t152) in #t152);
+  nullable1 = let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t155 = let final self::Class1 #t156 = new self::Class1::•() in let final void #t157 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t156) in #t156 in let final void #t158 = self::Extension1|set#nullable1(#t154{self::Class1}, #t155) in #t155;
+  let final self::Class1? #t159 = n1 in #t159.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t159{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t160 = n1 in #t160.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t161 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t162 = self::Extension1|set#nullable1(#t160{self::Class1}, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t163{self::Class1})));
+  let final self::Class1? #t164 = n1 in #t164.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t164{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t167 = self::Extension1|nonNullable1Method(#t166{self::Class1}) in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t167{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t173 = c in #t173.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t173{self::Class}, c{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t174{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t176 = self::Extension|[](#t175{self::Class}, c{self::Class}) in #t176.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t176{self::Class});
-  let final self::Class? #t177 = c in #t177.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t177{self::Class}), c{self::Class});
-  let final self::Class? #t178 = c in #t178.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t178{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t179 = c in #t179.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t180 = self::Extension|get#field(#t179{self::Class}) in let final self::Class #t181 = c{self::Class} in let final self::Class #t182 = new self::Class::•() in let final void #t183 = self::Extension|[]=(#t180, #t181, #t182) in #t182;
-  let final self::Class #t184 = c{self::Class} in #t184.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t185 = self::Extension|[](self::Extension|get#field(#t184), c{self::Class}) in #t185.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t185{self::Class});
-  let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in self::Extension|[]=(#t187, #t188, self::Extension|+(self::Extension|[](#t187, #t188), 0));
-  c = let final self::Class #t189 = c{self::Class} in #t189.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t190 = self::Extension|get#field(#t189) in let final self::Class #t191 = c{self::Class} in let final self::Class? #t192 = self::Extension|+(self::Extension|[](#t190, #t191), 0) in let final void #t193 = self::Extension|[]=(#t190, #t191, #t192) in #t192;
-  let final self::Class? #t194 = c in #t194.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t195 = c{self::Class} in self::Extension|[](#t194{self::Class}, #t195).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t194{self::Class}, #t195, c{self::Class}) : null;
-  c = let final self::Class? #t196 = c in #t196.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t197 = c{self::Class} in let final self::Class? #t198 = self::Extension|[](#t196{self::Class}, #t197) in #t198.{core::Object::==}(null) ?{self::Class} let final self::Class #t199 = c{self::Class} in let final void #t200 = self::Extension|[]=(#t196{self::Class}, #t197, #t199) in #t199 : #t198{self::Class};
-  let final self::Class #t201 = c{self::Class} in #t201.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t202 = c{self::Class} in self::Extension|[]=(#t201, #t202, self::Extension|+(self::Extension|[](#t201, #t202), 0));
-  c = let final self::Class #t203 = c{self::Class} in #t203.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t204 = c{self::Class} in let final self::Class? #t205 = self::Extension|+(self::Extension|[](#t203, #t204), 0) in let final void #t206 = self::Extension|[]=(#t203, #t204, #t205) in #t205;
-  let final self::Class? #t207 = c in #t207.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t208 = c{self::Class} in self::Extension|[]=(#t207{self::Class}, #t208, self::Extension|+(self::Extension|[](#t207{self::Class}, #t208), 0));
-  c = let final self::Class? #t209 = c in #t209.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t210 = c{self::Class} in let final self::Class? #t211 = self::Extension|+(self::Extension|[](#t209{self::Class}, #t210), 0) in let final void #t212 = self::Extension|[]=(#t209{self::Class}, #t210, #t211) in #t211;
-  let final self::Class? #t213 = c in #t213.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t214 = c{self::Class} in self::Extension|[]=(#t213{self::Class}, #t214, self::Extension|+(self::Extension|[](#t213{self::Class}, #t214), 1));
-  c = let final self::Class? #t215 = c in #t215.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t216 = c{self::Class} in let final self::Class? #t217 = self::Extension|[](#t215{self::Class}, #t216) in let final void #t218 = self::Extension|[]=(#t215{self::Class}, #t216, self::Extension|+(#t217, 1)) in #t217;
-  let final self::Class? #t219 = c in #t219.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t219{self::Class}, c{self::Class});
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t168{self::Class1}, nullable1);
+  let final self::Class1? #t169 = n1 in #t169.{core::Object::==}(null) ?{void} null : self::Extension1|[]=(#t169{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t171 = self::Extension1|[](#t170{self::Class1}, nullable1) in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t171{self::Class1});
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t172{self::Class1}), nullable1);
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t173{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t175 = self::Extension1|get#nonNullable1(#t174{self::Class1}) in let final self::Class1? #t176 = nullable1 in let final self::Class1 #t177 = new self::Class1::•() in let final void #t178 = self::Extension1|[]=(#t175, #t176, #t177) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t180 = self::Extension1|[](self::Extension1|get#nonNullable1(#t179{self::Class1}), nullable1) in #t180.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t180{self::Class1});
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = self::Extension1|get#nonNullable2(#t181{self::Class1}) in let final self::Class2? #t183 = nullable2 in self::Extension2|[]=(#t182, #t183, self::Extension2|+(self::Extension2|[](#t182, #t183), 0));
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = self::Extension1|get#nonNullable2(#t184{self::Class1}) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = self::Extension2|+(self::Extension2|[](#t185, #t186), 0) in let final void #t188 = self::Extension2|[]=(#t185, #t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = nullable1 in self::Extension1|[](#t189{self::Class1}, #t190).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t189{self::Class1}, #t190, nullable1) : null;
+  nullable1 = let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in let final self::Class1? #t193 = self::Extension1|[](#t191{self::Class1}, #t192) in #t193.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t194 = nullable1 in let final void #t195 = self::Extension1|[]=(#t191{self::Class1}, #t192, #t194) in #t194 : #t193{self::Class1};
+  let final self::Class2? #t196 = n2 in #t196.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t197 = nullable2 in self::Extension2|[]=(#t196{self::Class2}, #t197, self::Extension2|+(self::Extension2|[](#t196{self::Class2}, #t197), 0));
+  nullable2 = let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in let final self::Class2 #t200 = self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0) in let final void #t201 = self::Extension2|[]=(#t198{self::Class2}, #t199, #t200) in #t200;
+  let final self::Class2? #t202 = n2 in #t202.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t203 = nullable2 in self::Extension2|[]=(#t202{self::Class2}, #t203, self::Extension2|+(self::Extension2|[](#t202{self::Class2}, #t203), 0));
+  nullable2 = let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in let final self::Class2 #t206 = self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0) in let final void #t207 = self::Extension2|[]=(#t204{self::Class2}, #t205, #t206) in #t206;
+  let final self::Class2? #t208 = n2 in #t208.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t209 = nullable2 in self::Extension2|[]=(#t208{self::Class2}, #t209, self::Extension2|+(self::Extension2|[](#t208{self::Class2}, #t209), 1));
+  nullable2 = let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in let final self::Class2 #t212 = self::Extension2|[](#t210{self::Class2}, #t211) in let final void #t213 = self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(#t212, 1)) in #t212;
+  let final self::Class2? #t214 = n2 in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in let final self::Class2 #t216 = self::Extension2|+(self::Extension2|[](#t214{self::Class2}, #t215), 1) in let final void #t217 = self::Extension2|[]=(#t214{self::Class2}, #t215, #t216) in #t216;
+  nullable2 = let final self::Class2? #t218 = n2 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = nullable2 in let final self::Class2 #t220 = self::Extension2|+(self::Extension2|[](#t218{self::Class2}, #t219), 1) in let final void #t221 = self::Extension2|[]=(#t218{self::Class2}, #t219, #t220) in #t220;
+  let final self::Class1? #t222 = n1 in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t223 = self::Extension1|get#nonNullable2(#t222{self::Class1}) in let final self::Class2? #t224 = nullable2 in self::Extension2|[]=(#t223, #t224, self::Extension2|+(self::Extension2|[](#t223, #t224), 1));
+  nullable2 = let final self::Class1? #t225 = n1 in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t226 = self::Extension1|get#nonNullable2(#t225{self::Class1}) in let final self::Class2? #t227 = nullable2 in let final self::Class2 #t228 = self::Extension2|[](#t226, #t227) in let final void #t229 = self::Extension2|[]=(#t226, #t227, self::Extension2|+(#t228, 1)) in #t228;
+  let final self::Class1? #t230 = n1 in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t231 = self::Extension1|get#nonNullable2(#t230{self::Class1}) in let final self::Class2? #t232 = nullable2 in let final self::Class2 #t233 = self::Extension2|+(self::Extension2|[](#t231, #t232), 1) in let final void #t234 = self::Extension2|[]=(#t231, #t232, #t233) in #t233;
+  nullable2 = let final self::Class1? #t235 = n1 in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t236 = self::Extension1|get#nonNullable2(#t235{self::Class1}) in let final self::Class2? #t237 = nullable2 in let final self::Class2 #t238 = self::Extension2|+(self::Extension2|[](#t236, #t237), 1) in let final void #t239 = self::Extension2|[]=(#t236, #t237, #t238) in #t238;
+  let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t240{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t241 = n1 in #t241.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t241{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2) in let final self::Class2? #t244 = nullable2 in let final self::Class2 #t245 = new self::Class2::•() in let final void #t246 = self::Extension2|[]=(#t243, #t244, #t245) in #t245;
+  let final self::Class1? #t247 = n1 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t248 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t247{self::Class1}), nullable2), nullable2) in #t248.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t248{self::Class2});
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2) in let final self::Class2? #t251 = nullable2 in self::Extension2|[]=(#t250, #t251, self::Extension2|+(self::Extension2|[](#t250, #t251), 0));
+  nullable2 = let final self::Class1? #t252 = n1 in #t252.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t253 = self::Extension2|[](self::Extension1|get#nonNullable2(#t252{self::Class1}), nullable2) in let final self::Class2? #t254 = nullable2 in let final self::Class2 #t255 = self::Extension2|+(self::Extension2|[](#t253, #t254), 0) in let final void #t256 = self::Extension2|[]=(#t253, #t254, #t255) in #t255;
+  let final self::Class1? #t257 = n1 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = self::Extension2|[](self::Extension1|get#nonNullable2(#t257{self::Class1}), nullable2) in let final self::Class2? #t259 = nullable2 in self::Extension2|[]=(#t258, #t259, self::Extension2|+(self::Extension2|[](#t258, #t259), 1));
+  nullable2 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = self::Extension2|[](self::Extension1|get#nonNullable2(#t260{self::Class1}), nullable2) in let final self::Class2? #t262 = nullable2 in let final self::Class2 #t263 = self::Extension2|[](#t261, #t262) in let final void #t264 = self::Extension2|[]=(#t261, #t262, self::Extension2|+(#t263, 1)) in #t263;
+  let final self::Class1? #t265 = n1 in #t265.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t266 = self::Extension2|[](self::Extension1|get#nonNullable2(#t265{self::Class1}), nullable2) in let final self::Class2? #t267 = nullable2 in let final self::Class2 #t268 = self::Extension2|+(self::Extension2|[](#t266, #t267), 1) in let final void #t269 = self::Extension2|[]=(#t266, #t267, #t268) in #t268;
+  nullable2 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t271 = self::Extension2|[](self::Extension1|get#nonNullable2(#t270{self::Class1}), nullable2) in let final self::Class2? #t272 = nullable2 in let final self::Class2 #t273 = self::Extension2|+(self::Extension2|[](#t271, #t272), 1) in let final void #t274 = self::Extension2|[]=(#t271, #t272, #t273) in #t273;
+  let final self::Class1? #t275 = n1 in #t275.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t276 = self::Extension1|[](#t275{self::Class1}, nullable1) in #t276.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t276{self::Class1}, nullable1);
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t278{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t281 = nullable1 in let final self::Class1 #t282 = new self::Class1::•() in let final void #t283 = self::Extension1|[]=(#t280{self::Class1}, #t281, #t282) in #t282;
+  let final self::Class1? #t284 = n1 in #t284.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t285 = self::Extension1|[](#t284{self::Class1}, nullable1) in #t285.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t286 = self::Extension1|[](#t285{self::Class1}, nullable1) in #t286.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t286{self::Class1});
+  nullable1 = let final self::Class1? #t287 = n1 in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t289 = self::Extension1|[](#t288{self::Class1}, nullable1) in #t289.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t289{self::Class1});
+  let final self::Class1? #t290 = n1 in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t292 = nullable1 in self::Extension1|[](#t291{self::Class1}, #t292).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t291{self::Class1}, #t292, nullable1) : null;
+  nullable1 = let final self::Class1? #t293 = n1 in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = self::Extension1|[](#t293{self::Class1}, nullable1) in #t294.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t295 = nullable1 in let final self::Class1? #t296 = self::Extension1|[](#t294{self::Class1}, #t295) in #t296.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t297 = nullable1 in let final void #t298 = self::Extension1|[]=(#t294{self::Class1}, #t295, #t297) in #t297 : #t296{self::Class1};
+  let final self::Class3? #t299 = n3 in #t299.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t300 = self::Extension3|[](#t299{self::Class3}, nullable3) in #t300.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t301 = nullable2 in self::Extension2|[]=(#t300{self::Class2}, #t301, self::Extension2|+(self::Extension2|[](#t300{self::Class2}, #t301), 0));
+  nullable2 = let final self::Class3? #t302 = n3 in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = self::Extension3|[](#t302{self::Class3}, nullable3) in #t303.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t304 = nullable2 in let final self::Class2 #t305 = self::Extension2|+(self::Extension2|[](#t303{self::Class2}, #t304), 0) in let final void #t306 = self::Extension2|[]=(#t303{self::Class2}, #t304, #t305) in #t305;
+  let final self::Class3? #t307 = n3 in #t307.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t308 = self::Extension3|[](#t307{self::Class3}, nullable3) in #t308.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t309 = nullable2 in self::Extension2|[]=(#t308{self::Class2}, #t309, self::Extension2|+(self::Extension2|[](#t308{self::Class2}, #t309), 1));
+  nullable2 = let final self::Class3? #t310 = n3 in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = self::Extension3|[](#t310{self::Class3}, nullable3) in #t311.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t312 = nullable2 in let final self::Class2 #t313 = self::Extension2|[](#t311{self::Class2}, #t312) in let final void #t314 = self::Extension2|[]=(#t311{self::Class2}, #t312, self::Extension2|+(#t313, 1)) in #t313;
+  let final self::Class3? #t315 = n3 in #t315.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t316 = self::Extension3|[](#t315{self::Class3}, nullable3) in #t316.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t317 = nullable2 in let final self::Class2 #t318 = self::Extension2|+(self::Extension2|[](#t316{self::Class2}, #t317), 1) in let final void #t319 = self::Extension2|[]=(#t316{self::Class2}, #t317, #t318) in #t318;
+  nullable2 = let final self::Class3? #t320 = n3 in #t320.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t321 = self::Extension3|[](#t320{self::Class3}, nullable3) in #t321.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t322 = nullable2 in let final self::Class2 #t323 = self::Extension2|+(self::Extension2|[](#t321{self::Class2}, #t322), 1) in let final void #t324 = self::Extension2|[]=(#t321{self::Class2}, #t322, #t323) in #t323;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329{self::Class}, self::Extension|+(self::Extension|get#field(#t329{self::Class}), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330{self::Class}), 0) in let final void #t332 = self::Extension|set#field(#t330{self::Class}, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339{self::Class}, self::Extension|+(self::Extension|get#field(#t339{self::Class}), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340{self::Class}) in let final self::Class? #t342 = let final self::Class? #t343 = self::Extension|+(#t341, 1) in let final void #t344 = self::Extension|set#field(#t340{self::Class}, #t343) in #t343 in #t341;
-  let final self::Class? #t345 = c in #t345.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t346 = self::Extension|+(self::Extension|get#field(#t345{self::Class}), 1) in let final void #t347 = self::Extension|set#field(#t345{self::Class}, #t346) in #t346;
-  c = let final self::Class? #t348 = c in #t348.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t349 = self::Extension|+(self::Extension|get#field(#t348{self::Class}), 1) in let final void #t350 = self::Extension|set#field(#t348{self::Class}, #t349) in #t349;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => self::Extension1|+(let final self::Class1? #t325 = n1 in #t325.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t325{self::Class1}), 0));
+  self::throws(() → self::Class1? => self::Extension1|unary-(let final self::Class1? #t326 = n1 in #t326.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t326{self::Class1})));
+  let final self::Class2? #t327 = n2 in #t327.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t327{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t327{self::Class2}), 0));
+  nullable2 = let final self::Class2? #t328 = n2 in #t328.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t329 = self::Extension2|+(self::Extension2|get#nonNullable2(#t328{self::Class2}), 0) in let final void #t330 = self::Extension2|set#nonNullable2(#t328{self::Class2}, #t329) in #t329;
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t332 = self::Extension2|get#nonNullable2(#t331{self::Class2}) in self::Extension2|set#nonNullable2(#t332, self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0));
+  nullable2 = let final self::Class2? #t333 = n2 in #t333.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t334 = self::Extension2|get#nonNullable2(#t333{self::Class2}) in let final self::Class2 #t335 = self::Extension2|+(self::Extension2|get#nonNullable2(#t334), 0) in let final void #t336 = self::Extension2|set#nonNullable2(#t334, #t335) in #t335;
+  let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t337{self::Class2}, self::Extension2|+(self::Extension2|get#nonNullable2(#t337{self::Class2}), 1));
+  nullable2 = let final self::Class2? #t338 = n2 in #t338.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t339 = self::Extension2|get#nonNullable2(#t338{self::Class2}) in let final self::Class2 #t340 = let final self::Class2 #t341 = self::Extension2|+(#t339, 1) in let final void #t342 = self::Extension2|set#nonNullable2(#t338{self::Class2}, #t341) in #t341 in #t339;
+  let final self::Class2? #t343 = n2 in #t343.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t344 = self::Extension2|+(self::Extension2|get#nonNullable2(#t343{self::Class2}), 1) in let final void #t345 = self::Extension2|set#nonNullable2(#t343{self::Class2}, #t344) in #t344;
+  nullable2 = let final self::Class2? #t346 = n2 in #t346.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t347 = self::Extension2|+(self::Extension2|get#nonNullable2(#t346{self::Class2}), 1) in let final void #t348 = self::Extension2|set#nonNullable2(#t346{self::Class2}, #t347) in #t347;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t351 = c in #t351.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t351{self::Class}).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t351{self::Class}, c{self::Class}) : null;
-  c = let final self::Class? #t352 = c in #t352.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t353 = self::Extension|get#field(#t352{self::Class}) in #t353.{core::Object::==}(null) ?{self::Class} let final self::Class #t354 = c{self::Class} in let final void #t355 = self::Extension|set#field(#t352{self::Class}, #t354) in #t354 : #t353{self::Class};
-  let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in self::Extension|get#field(#t357).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t357, c{self::Class}) : null;
-  c = let final self::Class #t358 = c{self::Class} in #t358.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t359 = self::Extension|get#property(#t358) in let final self::Class? #t360 = self::Extension|get#field(#t359) in #t360.{core::Object::==}(null) ?{self::Class} let final self::Class #t361 = c{self::Class} in let final void #t362 = self::Extension|set#field(#t359, #t361) in #t361 : #t360{self::Class};
-  let final self::Class #t363 = c{self::Class} in #t363.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t364 = self::Extension|get#field(#t363) in let final self::Class #t365 = c{self::Class} in self::Extension|[](#t364, #t365).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t364, #t365, c{self::Class}) : null;
-  c = let final self::Class #t366 = c{self::Class} in #t366.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t367 = self::Extension|get#field(#t366) in let final self::Class #t368 = c{self::Class} in let final self::Class? #t369 = self::Extension|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class} let final self::Class #t370 = c{self::Class} in let final void #t371 = self::Extension|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t349 = n1 in #t349.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t349).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t349, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t350 = n1 in #t350.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t351 = self::Extension1|get#nullable1(#t350) in #t351.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t352 = n1{self::Class1} in let final void #t353 = self::Extension1|set#nullable1(#t350, #t352) in #t352 : #t351{self::Class1};
+  let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nonNullable1(#t354{self::Class1}) in self::Extension1|get#nullable1(#t355{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t355{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t356 = n1 in #t356.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t357 = self::Extension1|get#nonNullable1(#t356{self::Class1}) in let final self::Class1? #t358 = self::Extension1|get#nullable1(#t357{self::Class1}) in #t358.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t359 = n1{self::Class1} in let final void #t360 = self::Extension1|set#nullable1(#t357{self::Class1}, #t359) in #t359 : #t358{self::Class1};
+  let final self::Class1? #t361 = n1 in #t361.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t362 = self::Extension1|get#nonNullable1(#t361{self::Class1}) in let final self::Class1 #t363 = n1{self::Class1} in self::Extension1|[](#t362, #t363).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t362, #t363, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t364 = n1 in #t364.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t365 = self::Extension1|get#nonNullable1(#t364{self::Class1}) in let final self::Class1 #t366 = n1{self::Class1} in let final self::Class1? #t367 = self::Extension1|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t368 = n1{self::Class1} in let final void #t369 = self::Extension1|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
index 03a5b35..4ec6ad4 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart
@@ -2,195 +2,256 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-class Class {
-  Class? _field;
+class Class1 {
+  Class1? get property => null;
+
+  void set property(Class1? value) {}
+
+  Class1 get property1 => new Class1();
+
+  Class2 get property2 => new Class2();
 }
 
-extension Extension on Class {
-  Class? get field => _field;
-  void set field(Class? value) {
-    _field = value;
+extension Extension1 on Class1 {
+  Class1? get nullable1 => property1;
+
+  void set nullable1(Class1? value) {
+    property = value;
   }
 
-  Class method() => property;
+  Class1 nonNullable1Method() => nonNullable1;
 
-  Class? operator [](Class? key) => field;
-  void operator []=(Class? key, Class? value) {
-    field = value;
+  Class1? operator [](Class1? key) => nullable1;
+
+  void operator []=(Class1? key, Class1? value) {
+    property = value;
   }
 
-  Class? operator +(int value) => field;
+  Class1? operator +(int value) => nullable1;
 
-  Class? operator -() => field;
+  Class1? operator -() => nullable1;
 
-  Class get property => this;
+  Class1 get nonNullable1 => property1;
+
+  Class2 get nonNullable2 => property2;
+}
+
+class Class2 {
+  Class2 get property => this;
+
+  void set property(Class2 value) {}
+}
+
+extension Extension2 on Class2 {
+  Class2 nonNullable2Method() => nonNullable2;
+
+  Class2 operator [](Class2? key) => property;
+
+  void operator []=(Class2? key, Class2? value) => property;
+
+  Class2 operator +(int value) => property;
+
+  Class2 operator -() => property;
+
+  Class2 get nonNullable2 => property;
+
+  void set nonNullable2(Class2 value) {
+    property = value;
+  }
+}
+
+class Class3 {
+  Class2? get property => null;
+}
+
+extension Extension3 on Class3 {
+  Class2? operator [](Class3? key) => property;
 }
 
 main() {
   propertyAccess(null);
-  indexAccess(null);
-  operatorAccess(null);
+  indexAccess(null, null, null);
+  operatorAccess(null, null);
   ifNull(null);
 }
 
-void propertyAccess(Class? c) {
-  c?.field;
-  c?.field = new Class();
-  c = c?.field = new Class();
-  c?.method();
+void propertyAccess(Class1? n1) {
+  Class1? nullable1 = n1;
 
-  c?.property.field;
-  c?.field?.field;
-  c?.property.field?.field;
-  c?.property.field = new Class();
-  c?.field?.field = new Class();
-  c?.property.field?.field = new Class();
-  (c?.field)?.field;
-  throws(() => (c?.field = new Class()).field);
-  throws(() => (c?.method()).field);
-  c = c?.property.field = new Class();
-  c = c?.field?.field = new Class();
-  c = c?.property.field?.field = new Class();
-  c?.property.method();
-  c?.field = new Class().field;
-  c = c?.field = new Class().field;
-  c?.field = new Class().field = new Class();
-  c = c?.field = new Class().field = new Class();
-  c?.field = new Class().method();
-  c = c?.field = new Class().method();
-  c?.method().field;
-  c?.method().field = new Class();
-  c?.method().method();
+  n1?.nullable1;
+  n1?.nullable1 = new Class1();
+  nullable1 = n1?.nullable1 = new Class1();
+  n1?.nonNullable1Method();
 
-  c?.property.property.field;
-  c?.property.property.field = new Class();
-  c = c?.property.property.field = new Class();
-  c?.property.property.method();
-  c?.field = new Class().property.field;
-  c = c?.field = new Class().property.field;
-  c?.field = new Class().property.field = new Class();
-  c = c?.field = new Class().property.field = new Class();
-  c?.field = new Class().property.method();
-  c = c?.field = new Class().property.method();
-  c?.method().property.field;
-  c?.method().property.field = new Class();
-  c?.method().property.method();
+  n1?.nonNullable1.nullable1;
+  n1?.nullable1?.nullable1;
+  n1?.nonNullable1.nullable1?.nullable1;
+  n1?.nonNullable1.nullable1 = new Class1();
+  n1?.nullable1?.nullable1 = new Class1();
+  n1?.nonNullable1.nullable1?.nullable1 = new Class1();
+  (n1?.nullable1)?.nullable1;
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1();
+  nullable1 = n1?.nullable1?.nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nullable1?.nullable1 = new Class1();
+  n1?.nullable1?.nonNullable1Method();
+  n1?.nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nullable1;
+  n1?.nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1Method();
+  n1?.nonNullable1Method().nullable1;
+  n1?.nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1Method();
 
-  c?.property.field = new Class().field;
-  c = c?.property.field = new Class().field;
-  c?.property.field = new Class().field = new Class();
-  c = c?.property.field = new Class().field = new Class();
-  c?.property.field = new Class().method();
-  c = c?.property.field = new Class().method();
-  c?.field = new Class().field = new Class().field;
-  c = c?.field = new Class().field = new Class().field;
-  c?.field = new Class().field = new Class().field = new Class();
-  c = c?.field = new Class().field = new Class().field = new Class();
-  c?.field = new Class().field = new Class().method();
-  c = c?.field = new Class().field = new Class().method();
-  c?.method().field = new Class().field;
-  c = c?.method().field = new Class().field;
-  c?.method().field = new Class().field = new Class();
-  c = c?.method().field = new Class().field = new Class();
-  c?.method().field = new Class().method();
-  c = c?.method().field = new Class().method();
+  n1?.nonNullable1.nonNullable1.nullable1;
+  n1?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nonNullable1.nullable1 = new Class1();
+  n1?.nonNullable1.nullable1?.nonNullable1Method();
+  n1?.nullable1 = new Class1().nonNullable1.nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1.nullable1;
+  n1?.nullable1 = new Class1().nonNullable1.nullable1 = new Class1();
+  nullable1 =
+      n1?.nullable1 = new Class1().nonNullable1.nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1.nonNullable1Method();
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1.nonNullable1Method();
+  n1?.nonNullable1Method().nonNullable1.nullable1;
+  n1?.nonNullable1Method().nonNullable1.nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1.nonNullable1Method();
 
-  c?.field?.method().field;
-  c?.field?.method().field = new Class();
-  c = c?.field?.method().field = new Class();
-  c?.field?.method().method();
-  c?.field = new Class().method().field;
-  c = c?.field = new Class().method().field;
-  c?.field = new Class().method().field = new Class();
-  c = c?.field = new Class().method().field = new Class();
-  c?.field = new Class().method().method();
-  c = c?.field = new Class().method().method();
-  c?.method().method().field;
-  c?.method().method().field = new Class();
-  c?.method().method().method();
+  n1?.nonNullable1.nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1().nullable1;
+  n1?.nonNullable1.nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 =
+      n1?.nonNullable1.nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nonNullable1.nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nonNullable1.nullable1 = new Class1().nonNullable1Method();
+  n1?.nullable1 = new Class1().nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nullable1 = new Class1().nullable1;
+  n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nullable1 = new Class1().nonNullable1Method();
+  nullable1 = n1?.nullable1 =
+      new Class1().nullable1 = new Class1().nonNullable1Method();
+  n1?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  nullable1 = n1?.nonNullable1Method().nullable1 = new Class1().nullable1;
+  n1?.nonNullable1Method().nullable1 = new Class1().nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1Method().nullable1 =
+      new Class1().nullable1 = new Class1();
+  n1?.nonNullable1Method().nullable1 = new Class1().nonNullable1Method();
+  nullable1 =
+      n1?.nonNullable1Method().nullable1 = new Class1().nonNullable1Method();
 
-  c?.method()?.method();
+  n1?.nonNullable1.nonNullable1Method().nullable1;
+  n1?.nonNullable1.nonNullable1Method().nullable1 = new Class1();
+  nullable1 = n1?.nonNullable1.nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1.nonNullable1Method().nonNullable1Method();
+  n1?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  nullable1 = n1?.nullable1 = new Class1().nonNullable1Method().nullable1;
+  n1?.nullable1 = new Class1().nonNullable1Method().nullable1 = new Class1();
+  nullable1 = n1?.nullable1 =
+      new Class1().nonNullable1Method().nullable1 = new Class1();
+  n1?.nullable1 = new Class1().nonNullable1Method().nonNullable1Method();
+  nullable1 =
+      n1?.nullable1 = new Class1().nonNullable1Method().nonNullable1Method();
+  n1?.nonNullable1Method().nonNullable1Method().nullable1;
+  n1?.nonNullable1Method().nonNullable1Method().nullable1 = new Class1();
+  n1?.nonNullable1Method().nonNullable1Method().nonNullable1Method();
+
+  n1?.nonNullable1Method()?.nonNullable1Method();
 }
 
-void indexAccess(Class? c) {
-  c?.[c];
-  c?.[c] = new Class();
-  c?.[c]?.method();
-  c?.field[c];
-  c?.field[c] = new Class();
-  c = c?.field[c] = new Class();
-  c?.field[c]?.method();
-  c?.field[c] += 0;
-  c = c?.field[c] += 0;
-  c?.[c] ??= c;
-  c = c?.[c] ??= c;
-  c?.[c] += 0;
-  c = c?.[c] += 0;
-  c?.[c] += 0;
-  c = c?.[c] += 0;
-  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
-  // update.
-  c?.[c]++;
-  c = c?.[c]++;
-  ++c?.[c];
-  c = ++c?.[c];
-  c?.field[c]++;
-  c = c?.field[c]++;
-  ++c?.field[c];
-  c = ++c?.field[c];
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {
+  Class1? nullable1 = n1;
+  Class2? nullable2 = n2;
+  Class3? nullable3 = n3;
 
-  c?.field[c][c];
-  c?.field[c][c] = new Class();
-  c = c?.field[c][c] = new Class();
-  c?.field[c][c]?.method();
-  c?.field[c][c] += 0;
-  c = c?.field[c][c] += 0;
+  n1?.[nullable1];
+  n1?.[nullable1] = new Class1();
+  n1?.[nullable1]?.nonNullable1Method();
+  n1?.nonNullable1[nullable1];
+  n1?.nonNullable1[nullable1] = new Class1();
+  nullable1 = n1?.nonNullable1[nullable1] = new Class1();
+  n1?.nonNullable1[nullable1]?.nonNullable1Method();
+  n1?.nonNullable2[nullable2] += 0;
+  nullable2 = n1?.nonNullable2[nullable2] += 0;
+  n1?.[nullable1] ??= nullable1;
+  nullable1 = n1?.[nullable1] ??= nullable1;
+  n2?.[nullable2] += 0;
+  nullable2 = n2?.[nullable2] += 0;
+  n2?.[nullable2] += 0;
+  nullable2 = n2?.[nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  c?.field[c][c]++;
-  c = c?.field[c][c]++;
-  ++c?.field[c][c];
-  c = ++c?.field[c][c];
+  n2?.[nullable2]++;
+  nullable2 = n2?.[nullable2]++;
+  ++n2?.[nullable2];
+  nullable2 = ++n2?.[nullable2];
+  n1?.nonNullable2[nullable2]++;
+  nullable2 = n1?.nonNullable2[nullable2]++;
+  ++n1?.nonNullable2[nullable2];
+  nullable2 = ++n1?.nonNullable2[nullable2];
 
-  c?.[c]?.[c];
-  c?.[c]?.[c] = new Class();
-  c = c?.[c]?.[c] = new Class();
-  c?.[c]?.[c]?.method();
-  c = c?.[c]?.[c]?.method();
-  c?.[c]?.[c] ??= c;
-  c = c?.[c]?.[c] ??= c;
-  c?.[c]?.[c] += 0;
-  c = c?.[c]?.[c] += 0;
+  n1?.nonNullable2[nullable2][nullable2];
+  n1?.nonNullable2[nullable2][nullable2] = new Class2();
+  nullable2 = n1?.nonNullable2[nullable2][nullable2] = new Class2();
+  n1?.nonNullable2[nullable2][nullable2]?.nonNullable2Method();
+  n1?.nonNullable2[nullable2][nullable2] += 0;
+  nullable2 = n1?.nonNullable2[nullable2][nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
-  c?.[c]?.[c]++;
-  c = c?.[c]?.[c]++;
-  ++c?.[c]?.[c];
-  c = ++c?.[c]?.[c];
-}
+  n1?.nonNullable2[nullable2][nullable2]++;
+  nullable2 = n1?.nonNullable2[nullable2][nullable2]++;
+  ++n1?.nonNullable2[nullable2][nullable2];
+  nullable2 = ++n1?.nonNullable2[nullable2][nullable2];
 
-void operatorAccess(Class? c) {
-  throws(() => c?.field + 0);
-  throws(() => -c?.field);
-  c?.field += 0;
-  c = c?.field += 0;
-  c?.property.field += 0;
-  c = c?.property.field += 0;
+  n1?.[nullable1]?.[nullable1];
+  n1?.[nullable1]?.[nullable1] = new Class1();
+  nullable1 = n1?.[nullable1]?.[nullable1] = new Class1();
+  n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  nullable1 = n1?.[nullable1]?.[nullable1]?.nonNullable1Method();
+  n1?.[nullable1]?.[nullable1] ??= nullable1;
+  nullable1 = n1?.[nullable1]?.[nullable1] ??= nullable1;
+  n3?.[nullable3]?.[nullable2] += 0;
+  nullable2 = n3?.[nullable3]?.[nullable2] += 0;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
-  // update.
-  c?.field++;
-  c = c?.field++;
-  ++c?.field;
-  c = ++c?.field;
+  //  update.
+  n3?.[nullable3]?.[nullable2]++;
+  nullable2 = n3?.[nullable3]?.[nullable2]++;
+  ++n3?.[nullable3]?.[nullable2];
+  nullable2 = ++n3?.[nullable3]?.[nullable2];
 }
 
-void ifNull(Class? c) {
-  c?.field ??= c;
-  c = c?.field ??= c;
-  c?.property.field ??= c;
-  c = c?.property.field ??= c;
-  c?.field[c] ??= c;
-  c = c?.field[c] ??= c;
+void operatorAccess(Class1? n1, Class2? n2) {
+  Class2? nullable2 = n2;
+
+  throws(() => n1?.nonNullable1 + 0);
+  throws(() => -n1?.nonNullable1);
+  n2?.nonNullable2 += 0;
+  nullable2 = n2?.nonNullable2 += 0;
+  n2?.nonNullable2.nonNullable2 += 0;
+  nullable2 = n2?.nonNullable2.nonNullable2 += 0;
+  // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
+  //  update.
+  n2?.nonNullable2++;
+  nullable2 = n2?.nonNullable2++;
+  ++n2?.nonNullable2;
+  nullable2 = ++n2?.nonNullable2;
+}
+
+void ifNull(Class1? n1) {
+  Class1? nullable1 = n1;
+
+  n1?.nullable1 ??= n1;
+  n1 = n1?.nullable1 ??= n1;
+  n1?.nonNullable1.nullable1 ??= n1;
+  n1 = n1?.nonNullable1.nullable1 ??= n1;
+  n1?.nonNullable1[n1] ??= n1;
+  n1 = n1?.nonNullable1[n1] ??= n1;
 }
 
 void throws(void Function() f) {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
index a880ff1..32edac1 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect
@@ -2,49 +2,104 @@
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    ;
+  get property() → self::Class1?
+    ;
+  set property(self::Class1? value) → void
+    ;
+  get property1() → self::Class1
+    ;
+  get property2() → self::Class2
     ;
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    ;
+  get property() → self::Class2
+    ;
+  set property(self::Class2 value) → void
+    ;
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    ;
+  get property() → self::Class2?
+    ;
+}
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
+}
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
   ;
-static method Extension|set#field(final self::Class #this, self::Class? value) → void
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void
   ;
-static method Extension|method(final self::Class #this) → self::Class
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
   ;
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
   ;
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void
   ;
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
   ;
-static method Extension|unary-(final self::Class #this) → self::Class?
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
   ;
-static method Extension|get#property(final self::Class #this) → self::Class
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  ;
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  ;
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  ;
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  ;
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  ;
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  ;
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void
+  ;
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
   ;
 static method main() → dynamic
   ;
-static method propertyAccess(self::Class? c) → void
+static method propertyAccess(self::Class1? n1) → void
   ;
-static method indexAccess(self::Class? c) → void
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void
   ;
-static method operatorAccess(self::Class? c) → void
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void
   ;
-static method ifNull(self::Class? c) → void
+static method ifNull(self::Class1? n1) → void
   ;
 static method throws(() → void f) → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
index 029ceca..e4333bc 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect
@@ -1,190 +1,291 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(#t34));
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t35, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t37 = self::Extension|get#field(new self::Class::•()) in let final void #t38 = self::Extension|set#field(#t36, #t37) in #t37;
-  let final self::Class? #t39 = c in #t39.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t39{self::Class}, let final self::Class #t40 = new self::Class::•() in let final void #t41 = self::Extension|set#field(new self::Class::•(), #t40) in #t40);
-  c = let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t43 = let final self::Class #t44 = new self::Class::•() in let final void #t45 = self::Extension|set#field(new self::Class::•(), #t44) in #t44 in let final void #t46 = self::Extension|set#field(#t42{self::Class}, #t43) in #t43;
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t47, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t49 = self::Extension|method(new self::Class::•()) in let final void #t50 = self::Extension|set#field(#t48, #t49) in #t49;
-  let final self::Class #t51 = c{self::Class} in #t51.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t51));
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t52), new self::Class::•());
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t53));
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t54)));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t55)), new self::Class::•());
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t57 = new self::Class::•() in let final void #t58 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), #t57) in #t57;
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t59)));
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t60, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t62 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t63 = self::Extension|set#field(#t61, #t62) in #t62;
-  let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t64{self::Class}, let final self::Class #t65 = new self::Class::•() in let final void #t66 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t65) in #t65);
-  c = let final self::Class? #t67 = c in #t67.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t68 = let final self::Class #t69 = new self::Class::•() in let final void #t70 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t69) in #t69 in let final void #t71 = self::Extension|set#field(#t67{self::Class}, #t68) in #t68;
-  let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t72, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t74 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t75 = self::Extension|set#field(#t73, #t74) in #t74;
-  let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t76)));
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t77)), new self::Class::•());
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|method(#t78)));
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t79), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t81 = self::Extension|get#field(new self::Class::•()) in let final void #t82 = self::Extension|set#field(self::Extension|get#property(#t80), #t81) in #t81;
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t83{self::Class}), let final self::Class #t84 = new self::Class::•() in let final void #t85 = self::Extension|set#field(new self::Class::•(), #t84) in #t84);
-  c = let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t87 = let final self::Class #t88 = new self::Class::•() in let final void #t89 = self::Extension|set#field(new self::Class::•(), #t88) in #t88 in let final void #t90 = self::Extension|set#field(self::Extension|get#property(#t86{self::Class}), #t87) in #t87;
-  let final self::Class #t91 = c{self::Class} in #t91.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t91), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t92 = c{self::Class} in #t92.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t93 = self::Extension|method(new self::Class::•()) in let final void #t94 = self::Extension|set#field(self::Extension|get#property(#t92), #t93) in #t93;
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t95, let final self::Class? #t96 = self::Extension|get#field(new self::Class::•()) in let final void #t97 = self::Extension|set#field(new self::Class::•(), #t96) in #t96);
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = let final self::Class? #t100 = self::Extension|get#field(new self::Class::•()) in let final void #t101 = self::Extension|set#field(new self::Class::•(), #t100) in #t100 in let final void #t102 = self::Extension|set#field(#t98, #t99) in #t99;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t103{self::Class}, let final self::Class #t104 = let final self::Class #t105 = new self::Class::•() in let final void #t106 = self::Extension|set#field(new self::Class::•(), #t105) in #t105 in let final void #t107 = self::Extension|set#field(new self::Class::•(), #t104) in #t104);
-  c = let final self::Class? #t108 = c in #t108.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t109 = let final self::Class #t110 = let final self::Class #t111 = new self::Class::•() in let final void #t112 = self::Extension|set#field(new self::Class::•(), #t111) in #t111 in let final void #t113 = self::Extension|set#field(new self::Class::•(), #t110) in #t110 in let final void #t114 = self::Extension|set#field(#t108{self::Class}, #t109) in #t109;
-  let final self::Class #t115 = c{self::Class} in #t115.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t115, let final self::Class #t116 = self::Extension|method(new self::Class::•()) in let final void #t117 = self::Extension|set#field(new self::Class::•(), #t116) in #t116);
-  c = let final self::Class #t118 = c{self::Class} in #t118.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t119 = let final self::Class #t120 = self::Extension|method(new self::Class::•()) in let final void #t121 = self::Extension|set#field(new self::Class::•(), #t120) in #t120 in let final void #t122 = self::Extension|set#field(#t118, #t119) in #t119;
-  let final self::Class #t123 = c{self::Class} in #t123.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t123), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t124 = c{self::Class} in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t125 = self::Extension|get#field(new self::Class::•()) in let final void #t126 = self::Extension|set#field(self::Extension|method(#t124), #t125) in #t125;
-  let final self::Class? #t127 = c in #t127.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t127{self::Class}), let final self::Class #t128 = new self::Class::•() in let final void #t129 = self::Extension|set#field(new self::Class::•(), #t128) in #t128);
-  c = let final self::Class? #t130 = c in #t130.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t131 = let final self::Class #t132 = new self::Class::•() in let final void #t133 = self::Extension|set#field(new self::Class::•(), #t132) in #t132 in let final void #t134 = self::Extension|set#field(self::Extension|method(#t130{self::Class}), #t131) in #t131;
-  let final self::Class #t135 = c{self::Class} in #t135.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t135), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t136 = c{self::Class} in #t136.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t137 = self::Extension|method(new self::Class::•()) in let final void #t138 = self::Extension|set#field(self::Extension|method(#t136), #t137) in #t137;
-  let final self::Class #t139 = c{self::Class} in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = self::Extension|get#field(#t139) in #t140.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t140{self::Class}));
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t142 = self::Extension|get#field(#t141) in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t142{self::Class}), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t144 = self::Extension|get#field(#t143) in #t144.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t145 = new self::Class::•() in let final void #t146 = self::Extension|set#field(self::Extension|method(#t144{self::Class}), #t145) in #t145;
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t148 = self::Extension|get#field(#t147) in #t148.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t148{self::Class}));
-  let final self::Class #t149 = c{self::Class} in #t149.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t149, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t150 = c{self::Class} in #t150.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t151 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t152 = self::Extension|set#field(#t150, #t151) in #t151;
-  let final self::Class? #t153 = c in #t153.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t153{self::Class}, let final self::Class #t154 = new self::Class::•() in let final void #t155 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t154) in #t154);
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t157 = let final self::Class #t158 = new self::Class::•() in let final void #t159 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t158) in #t158 in let final void #t160 = self::Extension|set#field(#t156{self::Class}, #t157) in #t157;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t161, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t162 = c{self::Class} in #t162.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t163 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t164 = self::Extension|set#field(#t162, #t163) in #t163;
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t166)), new self::Class::•());
-  let final self::Class #t167 = c{self::Class} in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t167)));
-  let final self::Class #t168 = c{self::Class} in #t168.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t169 = self::Extension|method(#t168) in #t169.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t169);
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+                                              ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t21 = new self::Class1::•() in let final void #t22 = self::Extension1|set#nullable1(#t20{self::Class1}, #t21) in #t21));
+  self::throws(() → self::Class1? => let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+                                          ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t24{self::Class1})));
+  nullable1 = let final self::Class1? #t25 = n1 in #t25.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t26 = new self::Class1::•() in let final void #t27 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t25{self::Class1}), #t26) in #t26;
+  nullable1 = let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t29 = self::Extension1|get#nullable1(#t28{self::Class1}) in #t29.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t30 = new self::Class1::•() in let final void #t31 = self::Extension1|set#nullable1(#t29{self::Class1}, #t30) in #t30;
+  nullable1 = let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t33 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t32{self::Class1})) in #t33.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t34 = new self::Class1::•() in let final void #t35 = self::Extension1|set#nullable1(#t33{self::Class1}, #t34) in #t34;
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t37 = self::Extension1|get#nullable1(#t36{self::Class1}) in #t37.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t37{self::Class1});
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t38{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t40 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t41 = self::Extension1|set#nullable1(#t39{self::Class1}, #t40) in #t40;
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t42{self::Class1}, let final self::Class1 #t43 = new self::Class1::•() in let final void #t44 = self::Extension1|set#nullable1(new self::Class1::•(), #t43) in #t43);
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t46 = let final self::Class1 #t47 = new self::Class1::•() in let final void #t48 = self::Extension1|set#nullable1(new self::Class1::•(), #t47) in #t47 in let final void #t49 = self::Extension1|set#nullable1(#t45{self::Class1}, #t46) in #t46;
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t50{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t52 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t53 = self::Extension1|set#nullable1(#t51{self::Class1}, #t52) in #t52;
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t55{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t56{self::Class1}));
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})));
+  let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t58{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t60 = new self::Class1::•() in let final void #t61 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t59{self::Class1})), #t60) in #t60;
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t63 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t62{self::Class1})) in #t63.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t63{self::Class1});
+  let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t64{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t66 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t67 = self::Extension1|set#nullable1(#t65{self::Class1}, #t66) in #t66;
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t68{self::Class1}, let final self::Class1 #t69 = new self::Class1::•() in let final void #t70 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t69) in #t69);
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t72 = let final self::Class1 #t73 = new self::Class1::•() in let final void #t74 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t73) in #t73 in let final void #t75 = self::Extension1|set#nullable1(#t71{self::Class1}, #t72) in #t72;
+  let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t76{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t78 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t79 = self::Extension1|set#nullable1(#t77{self::Class1}, #t78) in #t78;
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t81{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t82{self::Class1})));
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t83{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t86 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t84{self::Class1}), #t85) in #t85;
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t87{self::Class1}), let final self::Class1 #t88 = new self::Class1::•() in let final void #t89 = self::Extension1|set#nullable1(new self::Class1::•(), #t88) in #t88);
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = let final self::Class1 #t92 = new self::Class1::•() in let final void #t93 = self::Extension1|set#nullable1(new self::Class1::•(), #t92) in #t92 in let final void #t94 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t90{self::Class1}), #t91) in #t91;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t95{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t96 = n1 in #t96.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t97 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t98 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t96{self::Class1}), #t97) in #t97;
+  let final self::Class1? #t99 = n1 in #t99.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t99{self::Class1}, let final self::Class1? #t100 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t101 = self::Extension1|set#nullable1(new self::Class1::•(), #t100) in #t100);
+  nullable1 = let final self::Class1? #t102 = n1 in #t102.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t103 = let final self::Class1? #t104 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t105 = self::Extension1|set#nullable1(new self::Class1::•(), #t104) in #t104 in let final void #t106 = self::Extension1|set#nullable1(#t102{self::Class1}, #t103) in #t103;
+  let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t107{self::Class1}, let final self::Class1 #t108 = let final self::Class1 #t109 = new self::Class1::•() in let final void #t110 = self::Extension1|set#nullable1(new self::Class1::•(), #t109) in #t109 in let final void #t111 = self::Extension1|set#nullable1(new self::Class1::•(), #t108) in #t108);
+  nullable1 = let final self::Class1? #t112 = n1 in #t112.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t113 = let final self::Class1 #t114 = let final self::Class1 #t115 = new self::Class1::•() in let final void #t116 = self::Extension1|set#nullable1(new self::Class1::•(), #t115) in #t115 in let final void #t117 = self::Extension1|set#nullable1(new self::Class1::•(), #t114) in #t114 in let final void #t118 = self::Extension1|set#nullable1(#t112{self::Class1}, #t113) in #t113;
+  let final self::Class1? #t119 = n1 in #t119.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t119{self::Class1}, let final self::Class1 #t120 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t121 = self::Extension1|set#nullable1(new self::Class1::•(), #t120) in #t120);
+  nullable1 = let final self::Class1? #t122 = n1 in #t122.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t123 = let final self::Class1 #t124 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t125 = self::Extension1|set#nullable1(new self::Class1::•(), #t124) in #t124 in let final void #t126 = self::Extension1|set#nullable1(#t122{self::Class1}, #t123) in #t123;
+  let final self::Class1? #t127 = n1 in #t127.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t127{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t128 = n1 in #t128.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t129 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t130 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t128{self::Class1}), #t129) in #t129;
+  let final self::Class1? #t131 = n1 in #t131.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t131{self::Class1}), let final self::Class1 #t132 = new self::Class1::•() in let final void #t133 = self::Extension1|set#nullable1(new self::Class1::•(), #t132) in #t132);
+  nullable1 = let final self::Class1? #t134 = n1 in #t134.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t135 = let final self::Class1 #t136 = new self::Class1::•() in let final void #t137 = self::Extension1|set#nullable1(new self::Class1::•(), #t136) in #t136 in let final void #t138 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t134{self::Class1}), #t135) in #t135;
+  let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t139{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t140 = n1 in #t140.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t141 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t142 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t140{self::Class1}), #t141) in #t141;
+  let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})));
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t144{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t145 = n1 in #t145.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t146 = new self::Class1::•() in let final void #t147 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t145{self::Class1})), #t146) in #t146;
+  let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t148{self::Class1})));
+  let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t149{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t150 = n1 in #t150.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t151 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t152 = self::Extension1|set#nullable1(#t150{self::Class1}, #t151) in #t151;
+  let final self::Class1? #t153 = n1 in #t153.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t153{self::Class1}, let final self::Class1 #t154 = new self::Class1::•() in let final void #t155 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t154) in #t154);
+  nullable1 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t157 = let final self::Class1 #t158 = new self::Class1::•() in let final void #t159 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t158) in #t158 in let final void #t160 = self::Extension1|set#nullable1(#t156{self::Class1}, #t157) in #t157;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t161{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t162 = n1 in #t162.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t163 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t164 = self::Extension1|set#nullable1(#t162{self::Class1}, #t163) in #t163;
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t166{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t167 = n1 in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t167{self::Class1})));
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t169 = self::Extension1|nonNullable1Method(#t168{self::Class1}) in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t169{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t170 = c in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t170{self::Class}, c{self::Class});
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t171{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t172 = c in #t172.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t173 = self::Extension|[](#t172{self::Class}, c{self::Class}) in #t173.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t173{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t174{self::Class}), c{self::Class});
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t175{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t176 = c in #t176.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t177 = self::Extension|get#field(#t176{self::Class}) in let final self::Class #t178 = c{self::Class} in let final self::Class #t179 = new self::Class::•() in let final void #t180 = self::Extension|[]=(#t177, #t178, #t179) in #t179;
-  let final self::Class #t181 = c{self::Class} in #t181.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t182 = self::Extension|[](self::Extension|get#field(#t181), c{self::Class}) in #t182.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t182{self::Class});
-  let final self::Class #t183 = c{self::Class} in #t183.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t184 = self::Extension|get#field(#t183) in let final self::Class #t185 = c{self::Class} in self::Extension|[]=(#t184, #t185, self::Extension|+(self::Extension|[](#t184, #t185), 0));
-  c = let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in let final self::Class? #t189 = self::Extension|+(self::Extension|[](#t187, #t188), 0) in let final void #t190 = self::Extension|[]=(#t187, #t188, #t189) in #t189;
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t192 = c{self::Class} in self::Extension|[](#t191{self::Class}, #t192).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t191{self::Class}, #t192, c{self::Class}) : null;
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t194 = c{self::Class} in let final self::Class? #t195 = self::Extension|[](#t193{self::Class}, #t194) in #t195.{core::Object::==}(null) ?{self::Class} let final self::Class #t196 = c{self::Class} in let final void #t197 = self::Extension|[]=(#t193{self::Class}, #t194, #t196) in #t196 : #t195{self::Class};
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t199 = c{self::Class} in self::Extension|[]=(#t198, #t199, self::Extension|+(self::Extension|[](#t198, #t199), 0));
-  c = let final self::Class #t200 = c{self::Class} in #t200.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t201 = c{self::Class} in let final self::Class? #t202 = self::Extension|+(self::Extension|[](#t200, #t201), 0) in let final void #t203 = self::Extension|[]=(#t200, #t201, #t202) in #t202;
-  let final self::Class? #t204 = c in #t204.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t205 = c{self::Class} in self::Extension|[]=(#t204{self::Class}, #t205, self::Extension|+(self::Extension|[](#t204{self::Class}, #t205), 0));
-  c = let final self::Class? #t206 = c in #t206.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t207 = c{self::Class} in let final self::Class? #t208 = self::Extension|+(self::Extension|[](#t206{self::Class}, #t207), 0) in let final void #t209 = self::Extension|[]=(#t206{self::Class}, #t207, #t208) in #t208;
-  let final self::Class? #t210 = c in #t210.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t211 = c{self::Class} in self::Extension|[]=(#t210{self::Class}, #t211, self::Extension|+(self::Extension|[](#t210{self::Class}, #t211), 1));
-  c = let final self::Class? #t212 = c in #t212.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t213 = c{self::Class} in let final self::Class? #t214 = self::Extension|[](#t212{self::Class}, #t213) in let final void #t215 = self::Extension|[]=(#t212{self::Class}, #t213, self::Extension|+(#t214, 1)) in #t214;
-  let final self::Class? #t216 = c in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t217 = c{self::Class} in let final self::Class? #t218 = self::Extension|+(self::Extension|[](#t216{self::Class}, #t217), 1) in let final void #t219 = self::Extension|[]=(#t216{self::Class}, #t217, #t218) in #t218;
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t170{self::Class1}, nullable1);
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t171{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t173 = self::Extension1|[](#t172{self::Class1}, nullable1) in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t173{self::Class1});
+  let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t174{self::Class1}), nullable1);
+  let final self::Class1? #t175 = n1 in #t175.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t175{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t177 = self::Extension1|get#nonNullable1(#t176{self::Class1}) in let final self::Class1? #t178 = nullable1 in let final self::Class1 #t179 = new self::Class1::•() in let final void #t180 = self::Extension1|[]=(#t177, #t178, #t179) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t182 = self::Extension1|[](self::Extension1|get#nonNullable1(#t181{self::Class1}), nullable1) in #t182.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t182{self::Class1});
+  let final self::Class1? #t183 = n1 in #t183.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t184 = self::Extension1|get#nonNullable2(#t183{self::Class1}) in let final self::Class2? #t185 = nullable2 in self::Extension2|[]=(#t184, #t185, self::Extension2|+(self::Extension2|[](#t184, #t185), 0));
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = self::Extension1|get#nonNullable2(#t186{self::Class1}) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = self::Extension2|+(self::Extension2|[](#t187, #t188), 0) in let final void #t190 = self::Extension2|[]=(#t187, #t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in self::Extension1|[](#t191{self::Class1}, #t192).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t191{self::Class1}, #t192, nullable1) : null;
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = nullable1 in let final self::Class1? #t195 = self::Extension1|[](#t193{self::Class1}, #t194) in #t195.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t196 = nullable1 in let final void #t197 = self::Extension1|[]=(#t193{self::Class1}, #t194, #t196) in #t196 : #t195{self::Class1};
+  let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in self::Extension2|[]=(#t198{self::Class2}, #t199, self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0));
+  nullable2 = let final self::Class2? #t200 = n2 in #t200.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t201 = nullable2 in let final self::Class2 #t202 = self::Extension2|+(self::Extension2|[](#t200{self::Class2}, #t201), 0) in let final void #t203 = self::Extension2|[]=(#t200{self::Class2}, #t201, #t202) in #t202;
+  let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in self::Extension2|[]=(#t204{self::Class2}, #t205, self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0));
+  nullable2 = let final self::Class2? #t206 = n2 in #t206.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t207 = nullable2 in let final self::Class2 #t208 = self::Extension2|+(self::Extension2|[](#t206{self::Class2}, #t207), 0) in let final void #t209 = self::Extension2|[]=(#t206{self::Class2}, #t207, #t208) in #t208;
+  let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(self::Extension2|[](#t210{self::Class2}, #t211), 1));
+  nullable2 = let final self::Class2? #t212 = n2 in #t212.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t213 = nullable2 in let final self::Class2 #t214 = self::Extension2|[](#t212{self::Class2}, #t213) in let final void #t215 = self::Extension2|[]=(#t212{self::Class2}, #t213, self::Extension2|+(#t214, 1)) in #t214;
+  let final self::Class2? #t216 = n2 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in let final self::Class2 #t218 = self::Extension2|+(self::Extension2|[](#t216{self::Class2}, #t217), 1) in let final void #t219 = self::Extension2|[]=(#t216{self::Class2}, #t217, #t218) in #t218;
+  nullable2 = let final self::Class2? #t220 = n2 in #t220.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t221 = nullable2 in let final self::Class2 #t222 = self::Extension2|+(self::Extension2|[](#t220{self::Class2}, #t221), 1) in let final void #t223 = self::Extension2|[]=(#t220{self::Class2}, #t221, #t222) in #t222;
+  let final self::Class1? #t224 = n1 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t225 = self::Extension1|get#nonNullable2(#t224{self::Class1}) in let final self::Class2? #t226 = nullable2 in self::Extension2|[]=(#t225, #t226, self::Extension2|+(self::Extension2|[](#t225, #t226), 1));
+  nullable2 = let final self::Class1? #t227 = n1 in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t228 = self::Extension1|get#nonNullable2(#t227{self::Class1}) in let final self::Class2? #t229 = nullable2 in let final self::Class2 #t230 = self::Extension2|[](#t228, #t229) in let final void #t231 = self::Extension2|[]=(#t228, #t229, self::Extension2|+(#t230, 1)) in #t230;
+  let final self::Class1? #t232 = n1 in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t233 = self::Extension1|get#nonNullable2(#t232{self::Class1}) in let final self::Class2? #t234 = nullable2 in let final self::Class2 #t235 = self::Extension2|+(self::Extension2|[](#t233, #t234), 1) in let final void #t236 = self::Extension2|[]=(#t233, #t234, #t235) in #t235;
+  nullable2 = let final self::Class1? #t237 = n1 in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t238 = self::Extension1|get#nonNullable2(#t237{self::Class1}) in let final self::Class2? #t239 = nullable2 in let final self::Class2 #t240 = self::Extension2|+(self::Extension2|[](#t238, #t239), 1) in let final void #t241 = self::Extension2|[]=(#t238, #t239, #t240) in #t240;
+  let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t243 = n1 in #t243.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t243{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t245 = self::Extension2|[](self::Extension1|get#nonNullable2(#t244{self::Class1}), nullable2) in let final self::Class2? #t246 = nullable2 in let final self::Class2 #t247 = new self::Class2::•() in let final void #t248 = self::Extension2|[]=(#t245, #t246, #t247) in #t247;
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t250 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2), nullable2) in #t250.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t250{self::Class2});
+  let final self::Class1? #t251 = n1 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = self::Extension2|[](self::Extension1|get#nonNullable2(#t251{self::Class1}), nullable2) in let final self::Class2? #t253 = nullable2 in self::Extension2|[]=(#t252, #t253, self::Extension2|+(self::Extension2|[](#t252, #t253), 0));
+  nullable2 = let final self::Class1? #t254 = n1 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = self::Extension2|[](self::Extension1|get#nonNullable2(#t254{self::Class1}), nullable2) in let final self::Class2? #t256 = nullable2 in let final self::Class2 #t257 = self::Extension2|+(self::Extension2|[](#t255, #t256), 0) in let final void #t258 = self::Extension2|[]=(#t255, #t256, #t257) in #t257;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t260 = self::Extension2|[](self::Extension1|get#nonNullable2(#t259{self::Class1}), nullable2) in let final self::Class2? #t261 = nullable2 in self::Extension2|[]=(#t260, #t261, self::Extension2|+(self::Extension2|[](#t260, #t261), 1));
+  nullable2 = let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t263 = self::Extension2|[](self::Extension1|get#nonNullable2(#t262{self::Class1}), nullable2) in let final self::Class2? #t264 = nullable2 in let final self::Class2 #t265 = self::Extension2|[](#t263, #t264) in let final void #t266 = self::Extension2|[]=(#t263, #t264, self::Extension2|+(#t265, 1)) in #t265;
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t268 = self::Extension2|[](self::Extension1|get#nonNullable2(#t267{self::Class1}), nullable2) in let final self::Class2? #t269 = nullable2 in let final self::Class2 #t270 = self::Extension2|+(self::Extension2|[](#t268, #t269), 1) in let final void #t271 = self::Extension2|[]=(#t268, #t269, #t270) in #t270;
+  nullable2 = let final self::Class1? #t272 = n1 in #t272.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t273 = self::Extension2|[](self::Extension1|get#nonNullable2(#t272{self::Class1}), nullable2) in let final self::Class2? #t274 = nullable2 in let final self::Class2 #t275 = self::Extension2|+(self::Extension2|[](#t273, #t274), 1) in let final void #t276 = self::Extension2|[]=(#t273, #t274, #t275) in #t275;
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t278{self::Class1}, nullable1);
+  let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t280{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t281 = n1 in #t281.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t282 = self::Extension1|[](#t281{self::Class1}, nullable1) in #t282.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t283 = nullable1 in let final self::Class1 #t284 = new self::Class1::•() in let final void #t285 = self::Extension1|[]=(#t282{self::Class1}, #t283, #t284) in #t284;
+  let final self::Class1? #t286 = n1 in #t286.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t287 = self::Extension1|[](#t286{self::Class1}, nullable1) in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t288{self::Class1});
+  nullable1 = let final self::Class1? #t289 = n1 in #t289.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t290 = self::Extension1|[](#t289{self::Class1}, nullable1) in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t291{self::Class1});
+  let final self::Class1? #t292 = n1 in #t292.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t293 = self::Extension1|[](#t292{self::Class1}, nullable1) in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = nullable1 in self::Extension1|[](#t293{self::Class1}, #t294).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t293{self::Class1}, #t294, nullable1) : null;
+  nullable1 = let final self::Class1? #t295 = n1 in #t295.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t296 = self::Extension1|[](#t295{self::Class1}, nullable1) in #t296.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t297 = nullable1 in let final self::Class1? #t298 = self::Extension1|[](#t296{self::Class1}, #t297) in #t298.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t299 = nullable1 in let final void #t300 = self::Extension1|[]=(#t296{self::Class1}, #t297, #t299) in #t299 : #t298{self::Class1};
+  let final self::Class3? #t301 = n3 in #t301.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t302 = self::Extension3|[](#t301{self::Class3}, nullable3) in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = nullable2 in self::Extension2|[]=(#t302{self::Class2}, #t303, self::Extension2|+(self::Extension2|[](#t302{self::Class2}, #t303), 0));
+  nullable2 = let final self::Class3? #t304 = n3 in #t304.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t305 = self::Extension3|[](#t304{self::Class3}, nullable3) in #t305.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t306 = nullable2 in let final self::Class2 #t307 = self::Extension2|+(self::Extension2|[](#t305{self::Class2}, #t306), 0) in let final void #t308 = self::Extension2|[]=(#t305{self::Class2}, #t306, #t307) in #t307;
+  let final self::Class3? #t309 = n3 in #t309.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t310 = self::Extension3|[](#t309{self::Class3}, nullable3) in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = nullable2 in self::Extension2|[]=(#t310{self::Class2}, #t311, self::Extension2|+(self::Extension2|[](#t310{self::Class2}, #t311), 1));
+  nullable2 = let final self::Class3? #t312 = n3 in #t312.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t313 = self::Extension3|[](#t312{self::Class3}, nullable3) in #t313.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t314 = nullable2 in let final self::Class2 #t315 = self::Extension2|[](#t313{self::Class2}, #t314) in let final void #t316 = self::Extension2|[]=(#t313{self::Class2}, #t314, self::Extension2|+(#t315, 1)) in #t315;
+  let final self::Class3? #t317 = n3 in #t317.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t318 = self::Extension3|[](#t317{self::Class3}, nullable3) in #t318.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t319 = nullable2 in let final self::Class2 #t320 = self::Extension2|+(self::Extension2|[](#t318{self::Class2}, #t319), 1) in let final void #t321 = self::Extension2|[]=(#t318{self::Class2}, #t319, #t320) in #t320;
+  nullable2 = let final self::Class3? #t322 = n3 in #t322.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t323 = self::Extension3|[](#t322{self::Class3}, nullable3) in #t323.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t324 = nullable2 in let final self::Class2 #t325 = self::Extension2|+(self::Extension2|[](#t323{self::Class2}, #t324), 1) in let final void #t326 = self::Extension2|[]=(#t323{self::Class2}, #t324, #t325) in #t325;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329, self::Extension|+(self::Extension|get#field(#t329), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330), 0) in let final void #t332 = self::Extension|set#field(#t330, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339, self::Extension|+(self::Extension|get#field(#t339), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340) in let final void #t342 = self::Extension|set#field(#t340, self::Extension|+(#t341, 1)) in #t341;
-  let final self::Class? #t343 = c in #t343.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t344 = self::Extension|+(self::Extension|get#field(#t343), 1) in let final void #t345 = self::Extension|set#field(#t343, #t344) in #t344;
-  c = let final self::Class? #t346 = c in #t346.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t347 = self::Extension|+(self::Extension|get#field(#t346), 1) in let final void #t348 = self::Extension|set#field(#t346, #t347) in #t347;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t327 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+  throws(() => n1?.nonNullable1 + 0);
+                                ^" in self::Extension1|+(let final self::Class1? #t328 = n1 in #t328.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t328{self::Class1}), 0));
+  self::throws(() → self::Class1? => let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+  throws(() => -n1?.nonNullable1);
+               ^" in self::Extension1|unary-(let final self::Class1? #t330 = n1 in #t330.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t330{self::Class1})));
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t331, self::Extension2|+(self::Extension2|get#nonNullable2(#t331), 0));
+  nullable2 = let final self::Class2? #t332 = n2 in #t332.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t333 = self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0) in let final void #t334 = self::Extension2|set#nonNullable2(#t332, #t333) in #t333;
+  let final self::Class2? #t335 = n2 in #t335.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t336 = self::Extension2|get#nonNullable2(#t335{self::Class2}) in self::Extension2|set#nonNullable2(#t336, self::Extension2|+(self::Extension2|get#nonNullable2(#t336), 0));
+  nullable2 = let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t338 = self::Extension2|get#nonNullable2(#t337{self::Class2}) in let final self::Class2 #t339 = self::Extension2|+(self::Extension2|get#nonNullable2(#t338), 0) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, #t339) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t341, self::Extension2|+(self::Extension2|get#nonNullable2(#t341), 1));
+  nullable2 = let final self::Class2? #t342 = n2 in #t342.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t343 = self::Extension2|get#nonNullable2(#t342) in let final void #t344 = self::Extension2|set#nonNullable2(#t342, self::Extension2|+(#t343, 1)) in #t343;
+  let final self::Class2? #t345 = n2 in #t345.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t346 = self::Extension2|+(self::Extension2|get#nonNullable2(#t345), 1) in let final void #t347 = self::Extension2|set#nonNullable2(#t345, #t346) in #t346;
+  nullable2 = let final self::Class2? #t348 = n2 in #t348.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t349 = self::Extension2|+(self::Extension2|get#nonNullable2(#t348), 1) in let final void #t350 = self::Extension2|set#nonNullable2(#t348, #t349) in #t349;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t349 = c in #t349.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t349).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t349, c{self::Class}) : null;
-  c = let final self::Class? #t350 = c in #t350.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t351 = self::Extension|get#field(#t350) in #t351.{core::Object::==}(null) ?{self::Class} let final self::Class #t352 = c{self::Class} in let final void #t353 = self::Extension|set#field(#t350, #t352) in #t352 : #t351{self::Class};
-  let final self::Class #t354 = c{self::Class} in #t354.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t355 = self::Extension|get#property(#t354) in self::Extension|get#field(#t355).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t355, c{self::Class}) : null;
-  c = let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in let final self::Class? #t358 = self::Extension|get#field(#t357) in #t358.{core::Object::==}(null) ?{self::Class} let final self::Class #t359 = c{self::Class} in let final void #t360 = self::Extension|set#field(#t357, #t359) in #t359 : #t358{self::Class};
-  let final self::Class #t361 = c{self::Class} in #t361.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t362 = self::Extension|get#field(#t361) in let final self::Class #t363 = c{self::Class} in self::Extension|[](#t362, #t363).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t362, #t363, c{self::Class}) : null;
-  c = let final self::Class #t364 = c{self::Class} in #t364.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t365 = self::Extension|get#field(#t364) in let final self::Class #t366 = c{self::Class} in let final self::Class? #t367 = self::Extension|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class} let final self::Class #t368 = c{self::Class} in let final void #t369 = self::Extension|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t351 = n1 in #t351.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t351).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t351, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t352 = n1 in #t352.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t353 = self::Extension1|get#nullable1(#t352) in #t353.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t354 = n1{self::Class1} in let final void #t355 = self::Extension1|set#nullable1(#t352, #t354) in #t354 : #t353{self::Class1};
+  let final self::Class1? #t356 = n1 in #t356.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t357 = self::Extension1|get#nonNullable1(#t356{self::Class1}) in self::Extension1|get#nullable1(#t357{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t357{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t358 = n1 in #t358.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t359 = self::Extension1|get#nonNullable1(#t358{self::Class1}) in let final self::Class1? #t360 = self::Extension1|get#nullable1(#t359{self::Class1}) in #t360.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t361 = n1{self::Class1} in let final void #t362 = self::Extension1|set#nullable1(#t359{self::Class1}, #t361) in #t361 : #t360{self::Class1};
+  let final self::Class1? #t363 = n1 in #t363.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t364 = self::Extension1|get#nonNullable1(#t363{self::Class1}) in let final self::Class1 #t365 = n1{self::Class1} in self::Extension1|[](#t364, #t365).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t364, #t365, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t366 = n1 in #t366.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t367 = self::Extension1|get#nonNullable1(#t366{self::Class1}) in let final self::Class1 #t368 = n1{self::Class1} in let final self::Class1? #t369 = self::Extension1|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t370 = n1{self::Class1} in let final void #t371 = self::Extension1|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
index 029ceca..e4333bc 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect
@@ -1,190 +1,291 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(#t34));
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t35, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t37 = self::Extension|get#field(new self::Class::•()) in let final void #t38 = self::Extension|set#field(#t36, #t37) in #t37;
-  let final self::Class? #t39 = c in #t39.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t39{self::Class}, let final self::Class #t40 = new self::Class::•() in let final void #t41 = self::Extension|set#field(new self::Class::•(), #t40) in #t40);
-  c = let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t43 = let final self::Class #t44 = new self::Class::•() in let final void #t45 = self::Extension|set#field(new self::Class::•(), #t44) in #t44 in let final void #t46 = self::Extension|set#field(#t42{self::Class}, #t43) in #t43;
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t47, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t49 = self::Extension|method(new self::Class::•()) in let final void #t50 = self::Extension|set#field(#t48, #t49) in #t49;
-  let final self::Class #t51 = c{self::Class} in #t51.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t51));
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t52), new self::Class::•());
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t53));
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t54)));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t55)), new self::Class::•());
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t57 = new self::Class::•() in let final void #t58 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), #t57) in #t57;
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t59)));
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t60, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t62 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t63 = self::Extension|set#field(#t61, #t62) in #t62;
-  let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t64{self::Class}, let final self::Class #t65 = new self::Class::•() in let final void #t66 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t65) in #t65);
-  c = let final self::Class? #t67 = c in #t67.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t68 = let final self::Class #t69 = new self::Class::•() in let final void #t70 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t69) in #t69 in let final void #t71 = self::Extension|set#field(#t67{self::Class}, #t68) in #t68;
-  let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t72, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t74 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t75 = self::Extension|set#field(#t73, #t74) in #t74;
-  let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t76)));
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t77)), new self::Class::•());
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|method(#t78)));
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t79), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t81 = self::Extension|get#field(new self::Class::•()) in let final void #t82 = self::Extension|set#field(self::Extension|get#property(#t80), #t81) in #t81;
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t83{self::Class}), let final self::Class #t84 = new self::Class::•() in let final void #t85 = self::Extension|set#field(new self::Class::•(), #t84) in #t84);
-  c = let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t87 = let final self::Class #t88 = new self::Class::•() in let final void #t89 = self::Extension|set#field(new self::Class::•(), #t88) in #t88 in let final void #t90 = self::Extension|set#field(self::Extension|get#property(#t86{self::Class}), #t87) in #t87;
-  let final self::Class #t91 = c{self::Class} in #t91.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t91), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t92 = c{self::Class} in #t92.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t93 = self::Extension|method(new self::Class::•()) in let final void #t94 = self::Extension|set#field(self::Extension|get#property(#t92), #t93) in #t93;
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t95, let final self::Class? #t96 = self::Extension|get#field(new self::Class::•()) in let final void #t97 = self::Extension|set#field(new self::Class::•(), #t96) in #t96);
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = let final self::Class? #t100 = self::Extension|get#field(new self::Class::•()) in let final void #t101 = self::Extension|set#field(new self::Class::•(), #t100) in #t100 in let final void #t102 = self::Extension|set#field(#t98, #t99) in #t99;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t103{self::Class}, let final self::Class #t104 = let final self::Class #t105 = new self::Class::•() in let final void #t106 = self::Extension|set#field(new self::Class::•(), #t105) in #t105 in let final void #t107 = self::Extension|set#field(new self::Class::•(), #t104) in #t104);
-  c = let final self::Class? #t108 = c in #t108.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t109 = let final self::Class #t110 = let final self::Class #t111 = new self::Class::•() in let final void #t112 = self::Extension|set#field(new self::Class::•(), #t111) in #t111 in let final void #t113 = self::Extension|set#field(new self::Class::•(), #t110) in #t110 in let final void #t114 = self::Extension|set#field(#t108{self::Class}, #t109) in #t109;
-  let final self::Class #t115 = c{self::Class} in #t115.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t115, let final self::Class #t116 = self::Extension|method(new self::Class::•()) in let final void #t117 = self::Extension|set#field(new self::Class::•(), #t116) in #t116);
-  c = let final self::Class #t118 = c{self::Class} in #t118.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t119 = let final self::Class #t120 = self::Extension|method(new self::Class::•()) in let final void #t121 = self::Extension|set#field(new self::Class::•(), #t120) in #t120 in let final void #t122 = self::Extension|set#field(#t118, #t119) in #t119;
-  let final self::Class #t123 = c{self::Class} in #t123.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t123), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t124 = c{self::Class} in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t125 = self::Extension|get#field(new self::Class::•()) in let final void #t126 = self::Extension|set#field(self::Extension|method(#t124), #t125) in #t125;
-  let final self::Class? #t127 = c in #t127.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t127{self::Class}), let final self::Class #t128 = new self::Class::•() in let final void #t129 = self::Extension|set#field(new self::Class::•(), #t128) in #t128);
-  c = let final self::Class? #t130 = c in #t130.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t131 = let final self::Class #t132 = new self::Class::•() in let final void #t133 = self::Extension|set#field(new self::Class::•(), #t132) in #t132 in let final void #t134 = self::Extension|set#field(self::Extension|method(#t130{self::Class}), #t131) in #t131;
-  let final self::Class #t135 = c{self::Class} in #t135.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t135), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t136 = c{self::Class} in #t136.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t137 = self::Extension|method(new self::Class::•()) in let final void #t138 = self::Extension|set#field(self::Extension|method(#t136), #t137) in #t137;
-  let final self::Class #t139 = c{self::Class} in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = self::Extension|get#field(#t139) in #t140.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t140{self::Class}));
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t142 = self::Extension|get#field(#t141) in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t142{self::Class}), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t144 = self::Extension|get#field(#t143) in #t144.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t145 = new self::Class::•() in let final void #t146 = self::Extension|set#field(self::Extension|method(#t144{self::Class}), #t145) in #t145;
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t148 = self::Extension|get#field(#t147) in #t148.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t148{self::Class}));
-  let final self::Class #t149 = c{self::Class} in #t149.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t149, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t150 = c{self::Class} in #t150.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t151 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t152 = self::Extension|set#field(#t150, #t151) in #t151;
-  let final self::Class? #t153 = c in #t153.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t153{self::Class}, let final self::Class #t154 = new self::Class::•() in let final void #t155 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t154) in #t154);
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t157 = let final self::Class #t158 = new self::Class::•() in let final void #t159 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t158) in #t158 in let final void #t160 = self::Extension|set#field(#t156{self::Class}, #t157) in #t157;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t161, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t162 = c{self::Class} in #t162.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t163 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t164 = self::Extension|set#field(#t162, #t163) in #t163;
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t166)), new self::Class::•());
-  let final self::Class #t167 = c{self::Class} in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t167)));
-  let final self::Class #t168 = c{self::Class} in #t168.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t169 = self::Extension|method(#t168) in #t169.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t169);
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nullable1 = new Class1()).nullable1);
+                                              ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t20 = n1 in #t20.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t21 = new self::Class1::•() in let final void #t22 = self::Extension1|set#nullable1(#t20{self::Class1}, #t21) in #t21));
+  self::throws(() → self::Class1? => let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Error: Property 'nullable1' cannot be accessed on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+Try accessing using ?. instead.
+  throws(() => (n1?.nonNullable1Method()).nullable1);
+                                          ^^^^^^^^^" in self::Extension1|get#nullable1(let final self::Class1? #t24 = n1 in #t24.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t24{self::Class1})));
+  nullable1 = let final self::Class1? #t25 = n1 in #t25.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t26 = new self::Class1::•() in let final void #t27 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t25{self::Class1}), #t26) in #t26;
+  nullable1 = let final self::Class1? #t28 = n1 in #t28.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t29 = self::Extension1|get#nullable1(#t28{self::Class1}) in #t29.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t30 = new self::Class1::•() in let final void #t31 = self::Extension1|set#nullable1(#t29{self::Class1}, #t30) in #t30;
+  nullable1 = let final self::Class1? #t32 = n1 in #t32.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t33 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t32{self::Class1})) in #t33.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t34 = new self::Class1::•() in let final void #t35 = self::Extension1|set#nullable1(#t33{self::Class1}, #t34) in #t34;
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t37 = self::Extension1|get#nullable1(#t36{self::Class1}) in #t37.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t37{self::Class1});
+  let final self::Class1? #t38 = n1 in #t38.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t38{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t39 = n1 in #t39.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t40 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t41 = self::Extension1|set#nullable1(#t39{self::Class1}, #t40) in #t40;
+  let final self::Class1? #t42 = n1 in #t42.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t42{self::Class1}, let final self::Class1 #t43 = new self::Class1::•() in let final void #t44 = self::Extension1|set#nullable1(new self::Class1::•(), #t43) in #t43);
+  nullable1 = let final self::Class1? #t45 = n1 in #t45.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t46 = let final self::Class1 #t47 = new self::Class1::•() in let final void #t48 = self::Extension1|set#nullable1(new self::Class1::•(), #t47) in #t47 in let final void #t49 = self::Extension1|set#nullable1(#t45{self::Class1}, #t46) in #t46;
+  let final self::Class1? #t50 = n1 in #t50.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t50{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t51 = n1 in #t51.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t52 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t53 = self::Extension1|set#nullable1(#t51{self::Class1}, #t52) in #t52;
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t55{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t56{self::Class1}));
+  let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})));
+  let final self::Class1? #t58 = n1 in #t58.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t58{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t59 = n1 in #t59.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t60 = new self::Class1::•() in let final void #t61 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t59{self::Class1})), #t60) in #t60;
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t63 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t62{self::Class1})) in #t63.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t63{self::Class1});
+  let final self::Class1? #t64 = n1 in #t64.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t64{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t65 = n1 in #t65.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t66 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t67 = self::Extension1|set#nullable1(#t65{self::Class1}, #t66) in #t66;
+  let final self::Class1? #t68 = n1 in #t68.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t68{self::Class1}, let final self::Class1 #t69 = new self::Class1::•() in let final void #t70 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t69) in #t69);
+  nullable1 = let final self::Class1? #t71 = n1 in #t71.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t72 = let final self::Class1 #t73 = new self::Class1::•() in let final void #t74 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t73) in #t73 in let final void #t75 = self::Extension1|set#nullable1(#t71{self::Class1}, #t72) in #t72;
+  let final self::Class1? #t76 = n1 in #t76.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t76{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t77 = n1 in #t77.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t78 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t79 = self::Extension1|set#nullable1(#t77{self::Class1}, #t78) in #t78;
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t81{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t82{self::Class1})));
+  let final self::Class1? #t83 = n1 in #t83.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t83{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t84 = n1 in #t84.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t85 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t86 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t84{self::Class1}), #t85) in #t85;
+  let final self::Class1? #t87 = n1 in #t87.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t87{self::Class1}), let final self::Class1 #t88 = new self::Class1::•() in let final void #t89 = self::Extension1|set#nullable1(new self::Class1::•(), #t88) in #t88);
+  nullable1 = let final self::Class1? #t90 = n1 in #t90.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t91 = let final self::Class1 #t92 = new self::Class1::•() in let final void #t93 = self::Extension1|set#nullable1(new self::Class1::•(), #t92) in #t92 in let final void #t94 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t90{self::Class1}), #t91) in #t91;
+  let final self::Class1? #t95 = n1 in #t95.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t95{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t96 = n1 in #t96.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t97 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t98 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t96{self::Class1}), #t97) in #t97;
+  let final self::Class1? #t99 = n1 in #t99.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t99{self::Class1}, let final self::Class1? #t100 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t101 = self::Extension1|set#nullable1(new self::Class1::•(), #t100) in #t100);
+  nullable1 = let final self::Class1? #t102 = n1 in #t102.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t103 = let final self::Class1? #t104 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t105 = self::Extension1|set#nullable1(new self::Class1::•(), #t104) in #t104 in let final void #t106 = self::Extension1|set#nullable1(#t102{self::Class1}, #t103) in #t103;
+  let final self::Class1? #t107 = n1 in #t107.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t107{self::Class1}, let final self::Class1 #t108 = let final self::Class1 #t109 = new self::Class1::•() in let final void #t110 = self::Extension1|set#nullable1(new self::Class1::•(), #t109) in #t109 in let final void #t111 = self::Extension1|set#nullable1(new self::Class1::•(), #t108) in #t108);
+  nullable1 = let final self::Class1? #t112 = n1 in #t112.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t113 = let final self::Class1 #t114 = let final self::Class1 #t115 = new self::Class1::•() in let final void #t116 = self::Extension1|set#nullable1(new self::Class1::•(), #t115) in #t115 in let final void #t117 = self::Extension1|set#nullable1(new self::Class1::•(), #t114) in #t114 in let final void #t118 = self::Extension1|set#nullable1(#t112{self::Class1}, #t113) in #t113;
+  let final self::Class1? #t119 = n1 in #t119.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t119{self::Class1}, let final self::Class1 #t120 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t121 = self::Extension1|set#nullable1(new self::Class1::•(), #t120) in #t120);
+  nullable1 = let final self::Class1? #t122 = n1 in #t122.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t123 = let final self::Class1 #t124 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t125 = self::Extension1|set#nullable1(new self::Class1::•(), #t124) in #t124 in let final void #t126 = self::Extension1|set#nullable1(#t122{self::Class1}, #t123) in #t123;
+  let final self::Class1? #t127 = n1 in #t127.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t127{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t128 = n1 in #t128.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t129 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t130 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t128{self::Class1}), #t129) in #t129;
+  let final self::Class1? #t131 = n1 in #t131.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t131{self::Class1}), let final self::Class1 #t132 = new self::Class1::•() in let final void #t133 = self::Extension1|set#nullable1(new self::Class1::•(), #t132) in #t132);
+  nullable1 = let final self::Class1? #t134 = n1 in #t134.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t135 = let final self::Class1 #t136 = new self::Class1::•() in let final void #t137 = self::Extension1|set#nullable1(new self::Class1::•(), #t136) in #t136 in let final void #t138 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t134{self::Class1}), #t135) in #t135;
+  let final self::Class1? #t139 = n1 in #t139.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t139{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t140 = n1 in #t140.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t141 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t142 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t140{self::Class1}), #t141) in #t141;
+  let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})));
+  let final self::Class1? #t144 = n1 in #t144.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t144{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t145 = n1 in #t145.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t146 = new self::Class1::•() in let final void #t147 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t145{self::Class1})), #t146) in #t146;
+  let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t148{self::Class1})));
+  let final self::Class1? #t149 = n1 in #t149.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t149{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t150 = n1 in #t150.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t151 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t152 = self::Extension1|set#nullable1(#t150{self::Class1}, #t151) in #t151;
+  let final self::Class1? #t153 = n1 in #t153.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t153{self::Class1}, let final self::Class1 #t154 = new self::Class1::•() in let final void #t155 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t154) in #t154);
+  nullable1 = let final self::Class1? #t156 = n1 in #t156.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t157 = let final self::Class1 #t158 = new self::Class1::•() in let final void #t159 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t158) in #t158 in let final void #t160 = self::Extension1|set#nullable1(#t156{self::Class1}, #t157) in #t157;
+  let final self::Class1? #t161 = n1 in #t161.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t161{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t162 = n1 in #t162.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t163 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t164 = self::Extension1|set#nullable1(#t162{self::Class1}, #t163) in #t163;
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t166{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t167 = n1 in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t167{self::Class1})));
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t169 = self::Extension1|nonNullable1Method(#t168{self::Class1}) in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t169{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t170 = c in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t170{self::Class}, c{self::Class});
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t171{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t172 = c in #t172.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t173 = self::Extension|[](#t172{self::Class}, c{self::Class}) in #t173.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t173{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t174{self::Class}), c{self::Class});
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t175{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t176 = c in #t176.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t177 = self::Extension|get#field(#t176{self::Class}) in let final self::Class #t178 = c{self::Class} in let final self::Class #t179 = new self::Class::•() in let final void #t180 = self::Extension|[]=(#t177, #t178, #t179) in #t179;
-  let final self::Class #t181 = c{self::Class} in #t181.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t182 = self::Extension|[](self::Extension|get#field(#t181), c{self::Class}) in #t182.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t182{self::Class});
-  let final self::Class #t183 = c{self::Class} in #t183.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t184 = self::Extension|get#field(#t183) in let final self::Class #t185 = c{self::Class} in self::Extension|[]=(#t184, #t185, self::Extension|+(self::Extension|[](#t184, #t185), 0));
-  c = let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in let final self::Class? #t189 = self::Extension|+(self::Extension|[](#t187, #t188), 0) in let final void #t190 = self::Extension|[]=(#t187, #t188, #t189) in #t189;
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t192 = c{self::Class} in self::Extension|[](#t191{self::Class}, #t192).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t191{self::Class}, #t192, c{self::Class}) : null;
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t194 = c{self::Class} in let final self::Class? #t195 = self::Extension|[](#t193{self::Class}, #t194) in #t195.{core::Object::==}(null) ?{self::Class} let final self::Class #t196 = c{self::Class} in let final void #t197 = self::Extension|[]=(#t193{self::Class}, #t194, #t196) in #t196 : #t195{self::Class};
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t199 = c{self::Class} in self::Extension|[]=(#t198, #t199, self::Extension|+(self::Extension|[](#t198, #t199), 0));
-  c = let final self::Class #t200 = c{self::Class} in #t200.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t201 = c{self::Class} in let final self::Class? #t202 = self::Extension|+(self::Extension|[](#t200, #t201), 0) in let final void #t203 = self::Extension|[]=(#t200, #t201, #t202) in #t202;
-  let final self::Class? #t204 = c in #t204.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t205 = c{self::Class} in self::Extension|[]=(#t204{self::Class}, #t205, self::Extension|+(self::Extension|[](#t204{self::Class}, #t205), 0));
-  c = let final self::Class? #t206 = c in #t206.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t207 = c{self::Class} in let final self::Class? #t208 = self::Extension|+(self::Extension|[](#t206{self::Class}, #t207), 0) in let final void #t209 = self::Extension|[]=(#t206{self::Class}, #t207, #t208) in #t208;
-  let final self::Class? #t210 = c in #t210.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t211 = c{self::Class} in self::Extension|[]=(#t210{self::Class}, #t211, self::Extension|+(self::Extension|[](#t210{self::Class}, #t211), 1));
-  c = let final self::Class? #t212 = c in #t212.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t213 = c{self::Class} in let final self::Class? #t214 = self::Extension|[](#t212{self::Class}, #t213) in let final void #t215 = self::Extension|[]=(#t212{self::Class}, #t213, self::Extension|+(#t214, 1)) in #t214;
-  let final self::Class? #t216 = c in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t217 = c{self::Class} in let final self::Class? #t218 = self::Extension|+(self::Extension|[](#t216{self::Class}, #t217), 1) in let final void #t219 = self::Extension|[]=(#t216{self::Class}, #t217, #t218) in #t218;
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t170{self::Class1}, nullable1);
+  let final self::Class1? #t171 = n1 in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t171{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t173 = self::Extension1|[](#t172{self::Class1}, nullable1) in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t173{self::Class1});
+  let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t174{self::Class1}), nullable1);
+  let final self::Class1? #t175 = n1 in #t175.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t175{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t176 = n1 in #t176.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t177 = self::Extension1|get#nonNullable1(#t176{self::Class1}) in let final self::Class1? #t178 = nullable1 in let final self::Class1 #t179 = new self::Class1::•() in let final void #t180 = self::Extension1|[]=(#t177, #t178, #t179) in #t179;
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t182 = self::Extension1|[](self::Extension1|get#nonNullable1(#t181{self::Class1}), nullable1) in #t182.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t182{self::Class1});
+  let final self::Class1? #t183 = n1 in #t183.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t184 = self::Extension1|get#nonNullable2(#t183{self::Class1}) in let final self::Class2? #t185 = nullable2 in self::Extension2|[]=(#t184, #t185, self::Extension2|+(self::Extension2|[](#t184, #t185), 0));
+  nullable2 = let final self::Class1? #t186 = n1 in #t186.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t187 = self::Extension1|get#nonNullable2(#t186{self::Class1}) in let final self::Class2? #t188 = nullable2 in let final self::Class2 #t189 = self::Extension2|+(self::Extension2|[](#t187, #t188), 0) in let final void #t190 = self::Extension2|[]=(#t187, #t188, #t189) in #t189;
+  let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in self::Extension1|[](#t191{self::Class1}, #t192).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t191{self::Class1}, #t192, nullable1) : null;
+  nullable1 = let final self::Class1? #t193 = n1 in #t193.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t194 = nullable1 in let final self::Class1? #t195 = self::Extension1|[](#t193{self::Class1}, #t194) in #t195.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t196 = nullable1 in let final void #t197 = self::Extension1|[]=(#t193{self::Class1}, #t194, #t196) in #t196 : #t195{self::Class1};
+  let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in self::Extension2|[]=(#t198{self::Class2}, #t199, self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0));
+  nullable2 = let final self::Class2? #t200 = n2 in #t200.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t201 = nullable2 in let final self::Class2 #t202 = self::Extension2|+(self::Extension2|[](#t200{self::Class2}, #t201), 0) in let final void #t203 = self::Extension2|[]=(#t200{self::Class2}, #t201, #t202) in #t202;
+  let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in self::Extension2|[]=(#t204{self::Class2}, #t205, self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0));
+  nullable2 = let final self::Class2? #t206 = n2 in #t206.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t207 = nullable2 in let final self::Class2 #t208 = self::Extension2|+(self::Extension2|[](#t206{self::Class2}, #t207), 0) in let final void #t209 = self::Extension2|[]=(#t206{self::Class2}, #t207, #t208) in #t208;
+  let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(self::Extension2|[](#t210{self::Class2}, #t211), 1));
+  nullable2 = let final self::Class2? #t212 = n2 in #t212.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t213 = nullable2 in let final self::Class2 #t214 = self::Extension2|[](#t212{self::Class2}, #t213) in let final void #t215 = self::Extension2|[]=(#t212{self::Class2}, #t213, self::Extension2|+(#t214, 1)) in #t214;
+  let final self::Class2? #t216 = n2 in #t216.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t217 = nullable2 in let final self::Class2 #t218 = self::Extension2|+(self::Extension2|[](#t216{self::Class2}, #t217), 1) in let final void #t219 = self::Extension2|[]=(#t216{self::Class2}, #t217, #t218) in #t218;
+  nullable2 = let final self::Class2? #t220 = n2 in #t220.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t221 = nullable2 in let final self::Class2 #t222 = self::Extension2|+(self::Extension2|[](#t220{self::Class2}, #t221), 1) in let final void #t223 = self::Extension2|[]=(#t220{self::Class2}, #t221, #t222) in #t222;
+  let final self::Class1? #t224 = n1 in #t224.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t225 = self::Extension1|get#nonNullable2(#t224{self::Class1}) in let final self::Class2? #t226 = nullable2 in self::Extension2|[]=(#t225, #t226, self::Extension2|+(self::Extension2|[](#t225, #t226), 1));
+  nullable2 = let final self::Class1? #t227 = n1 in #t227.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t228 = self::Extension1|get#nonNullable2(#t227{self::Class1}) in let final self::Class2? #t229 = nullable2 in let final self::Class2 #t230 = self::Extension2|[](#t228, #t229) in let final void #t231 = self::Extension2|[]=(#t228, #t229, self::Extension2|+(#t230, 1)) in #t230;
+  let final self::Class1? #t232 = n1 in #t232.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t233 = self::Extension1|get#nonNullable2(#t232{self::Class1}) in let final self::Class2? #t234 = nullable2 in let final self::Class2 #t235 = self::Extension2|+(self::Extension2|[](#t233, #t234), 1) in let final void #t236 = self::Extension2|[]=(#t233, #t234, #t235) in #t235;
+  nullable2 = let final self::Class1? #t237 = n1 in #t237.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t238 = self::Extension1|get#nonNullable2(#t237{self::Class1}) in let final self::Class2? #t239 = nullable2 in let final self::Class2 #t240 = self::Extension2|+(self::Extension2|[](#t238, #t239), 1) in let final void #t241 = self::Extension2|[]=(#t238, #t239, #t240) in #t240;
+  let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t243 = n1 in #t243.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t243{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t244 = n1 in #t244.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t245 = self::Extension2|[](self::Extension1|get#nonNullable2(#t244{self::Class1}), nullable2) in let final self::Class2? #t246 = nullable2 in let final self::Class2 #t247 = new self::Class2::•() in let final void #t248 = self::Extension2|[]=(#t245, #t246, #t247) in #t247;
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t250 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2), nullable2) in #t250.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t250{self::Class2});
+  let final self::Class1? #t251 = n1 in #t251.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t252 = self::Extension2|[](self::Extension1|get#nonNullable2(#t251{self::Class1}), nullable2) in let final self::Class2? #t253 = nullable2 in self::Extension2|[]=(#t252, #t253, self::Extension2|+(self::Extension2|[](#t252, #t253), 0));
+  nullable2 = let final self::Class1? #t254 = n1 in #t254.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t255 = self::Extension2|[](self::Extension1|get#nonNullable2(#t254{self::Class1}), nullable2) in let final self::Class2? #t256 = nullable2 in let final self::Class2 #t257 = self::Extension2|+(self::Extension2|[](#t255, #t256), 0) in let final void #t258 = self::Extension2|[]=(#t255, #t256, #t257) in #t257;
+  let final self::Class1? #t259 = n1 in #t259.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t260 = self::Extension2|[](self::Extension1|get#nonNullable2(#t259{self::Class1}), nullable2) in let final self::Class2? #t261 = nullable2 in self::Extension2|[]=(#t260, #t261, self::Extension2|+(self::Extension2|[](#t260, #t261), 1));
+  nullable2 = let final self::Class1? #t262 = n1 in #t262.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t263 = self::Extension2|[](self::Extension1|get#nonNullable2(#t262{self::Class1}), nullable2) in let final self::Class2? #t264 = nullable2 in let final self::Class2 #t265 = self::Extension2|[](#t263, #t264) in let final void #t266 = self::Extension2|[]=(#t263, #t264, self::Extension2|+(#t265, 1)) in #t265;
+  let final self::Class1? #t267 = n1 in #t267.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t268 = self::Extension2|[](self::Extension1|get#nonNullable2(#t267{self::Class1}), nullable2) in let final self::Class2? #t269 = nullable2 in let final self::Class2 #t270 = self::Extension2|+(self::Extension2|[](#t268, #t269), 1) in let final void #t271 = self::Extension2|[]=(#t268, #t269, #t270) in #t270;
+  nullable2 = let final self::Class1? #t272 = n1 in #t272.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t273 = self::Extension2|[](self::Extension1|get#nonNullable2(#t272{self::Class1}), nullable2) in let final self::Class2? #t274 = nullable2 in let final self::Class2 #t275 = self::Extension2|+(self::Extension2|[](#t273, #t274), 1) in let final void #t276 = self::Extension2|[]=(#t273, #t274, #t275) in #t275;
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t278{self::Class1}, nullable1);
+  let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t280{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t281 = n1 in #t281.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t282 = self::Extension1|[](#t281{self::Class1}, nullable1) in #t282.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t283 = nullable1 in let final self::Class1 #t284 = new self::Class1::•() in let final void #t285 = self::Extension1|[]=(#t282{self::Class1}, #t283, #t284) in #t284;
+  let final self::Class1? #t286 = n1 in #t286.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t287 = self::Extension1|[](#t286{self::Class1}, nullable1) in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t288{self::Class1});
+  nullable1 = let final self::Class1? #t289 = n1 in #t289.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t290 = self::Extension1|[](#t289{self::Class1}, nullable1) in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t291{self::Class1});
+  let final self::Class1? #t292 = n1 in #t292.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t293 = self::Extension1|[](#t292{self::Class1}, nullable1) in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = nullable1 in self::Extension1|[](#t293{self::Class1}, #t294).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t293{self::Class1}, #t294, nullable1) : null;
+  nullable1 = let final self::Class1? #t295 = n1 in #t295.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t296 = self::Extension1|[](#t295{self::Class1}, nullable1) in #t296.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t297 = nullable1 in let final self::Class1? #t298 = self::Extension1|[](#t296{self::Class1}, #t297) in #t298.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t299 = nullable1 in let final void #t300 = self::Extension1|[]=(#t296{self::Class1}, #t297, #t299) in #t299 : #t298{self::Class1};
+  let final self::Class3? #t301 = n3 in #t301.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t302 = self::Extension3|[](#t301{self::Class3}, nullable3) in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = nullable2 in self::Extension2|[]=(#t302{self::Class2}, #t303, self::Extension2|+(self::Extension2|[](#t302{self::Class2}, #t303), 0));
+  nullable2 = let final self::Class3? #t304 = n3 in #t304.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t305 = self::Extension3|[](#t304{self::Class3}, nullable3) in #t305.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t306 = nullable2 in let final self::Class2 #t307 = self::Extension2|+(self::Extension2|[](#t305{self::Class2}, #t306), 0) in let final void #t308 = self::Extension2|[]=(#t305{self::Class2}, #t306, #t307) in #t307;
+  let final self::Class3? #t309 = n3 in #t309.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t310 = self::Extension3|[](#t309{self::Class3}, nullable3) in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = nullable2 in self::Extension2|[]=(#t310{self::Class2}, #t311, self::Extension2|+(self::Extension2|[](#t310{self::Class2}, #t311), 1));
+  nullable2 = let final self::Class3? #t312 = n3 in #t312.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t313 = self::Extension3|[](#t312{self::Class3}, nullable3) in #t313.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t314 = nullable2 in let final self::Class2 #t315 = self::Extension2|[](#t313{self::Class2}, #t314) in let final void #t316 = self::Extension2|[]=(#t313{self::Class2}, #t314, self::Extension2|+(#t315, 1)) in #t315;
+  let final self::Class3? #t317 = n3 in #t317.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t318 = self::Extension3|[](#t317{self::Class3}, nullable3) in #t318.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t319 = nullable2 in let final self::Class2 #t320 = self::Extension2|+(self::Extension2|[](#t318{self::Class2}, #t319), 1) in let final void #t321 = self::Extension2|[]=(#t318{self::Class2}, #t319, #t320) in #t320;
+  nullable2 = let final self::Class3? #t322 = n3 in #t322.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t323 = self::Extension3|[](#t322{self::Class3}, nullable3) in #t323.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t324 = nullable2 in let final self::Class2 #t325 = self::Extension2|+(self::Extension2|[](#t323{self::Class2}, #t324), 1) in let final void #t326 = self::Extension2|[]=(#t323{self::Class2}, #t324, #t325) in #t325;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329, self::Extension|+(self::Extension|get#field(#t329), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330), 0) in let final void #t332 = self::Extension|set#field(#t330, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339, self::Extension|+(self::Extension|get#field(#t339), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340) in let final void #t342 = self::Extension|set#field(#t340, self::Extension|+(#t341, 1)) in #t341;
-  let final self::Class? #t343 = c in #t343.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t344 = self::Extension|+(self::Extension|get#field(#t343), 1) in let final void #t345 = self::Extension|set#field(#t343, #t344) in #t344;
-  c = let final self::Class? #t346 = c in #t346.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t347 = self::Extension|+(self::Extension|get#field(#t346), 1) in let final void #t348 = self::Extension|set#field(#t346, #t347) in #t347;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => let final<BottomType> #t327 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Error: Operator '+' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+  throws(() => n1?.nonNullable1 + 0);
+                                ^" in self::Extension1|+(let final self::Class1? #t328 = n1 in #t328.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t328{self::Class1}), 0));
+  self::throws(() → self::Class1? => let final<BottomType> #t329 = invalid-expression "pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Error: Operator 'unary-' cannot be called on 'Class1?' because it is potentially null.
+ - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+  throws(() => -n1?.nonNullable1);
+               ^" in self::Extension1|unary-(let final self::Class1? #t330 = n1 in #t330.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t330{self::Class1})));
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t331, self::Extension2|+(self::Extension2|get#nonNullable2(#t331), 0));
+  nullable2 = let final self::Class2? #t332 = n2 in #t332.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t333 = self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0) in let final void #t334 = self::Extension2|set#nonNullable2(#t332, #t333) in #t333;
+  let final self::Class2? #t335 = n2 in #t335.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t336 = self::Extension2|get#nonNullable2(#t335{self::Class2}) in self::Extension2|set#nonNullable2(#t336, self::Extension2|+(self::Extension2|get#nonNullable2(#t336), 0));
+  nullable2 = let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t338 = self::Extension2|get#nonNullable2(#t337{self::Class2}) in let final self::Class2 #t339 = self::Extension2|+(self::Extension2|get#nonNullable2(#t338), 0) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, #t339) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t341, self::Extension2|+(self::Extension2|get#nonNullable2(#t341), 1));
+  nullable2 = let final self::Class2? #t342 = n2 in #t342.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t343 = self::Extension2|get#nonNullable2(#t342) in let final void #t344 = self::Extension2|set#nonNullable2(#t342, self::Extension2|+(#t343, 1)) in #t343;
+  let final self::Class2? #t345 = n2 in #t345.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t346 = self::Extension2|+(self::Extension2|get#nonNullable2(#t345), 1) in let final void #t347 = self::Extension2|set#nonNullable2(#t345, #t346) in #t346;
+  nullable2 = let final self::Class2? #t348 = n2 in #t348.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t349 = self::Extension2|+(self::Extension2|get#nonNullable2(#t348), 1) in let final void #t350 = self::Extension2|set#nonNullable2(#t348, #t349) in #t349;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t349 = c in #t349.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t349).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t349, c{self::Class}) : null;
-  c = let final self::Class? #t350 = c in #t350.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t351 = self::Extension|get#field(#t350) in #t351.{core::Object::==}(null) ?{self::Class} let final self::Class #t352 = c{self::Class} in let final void #t353 = self::Extension|set#field(#t350, #t352) in #t352 : #t351{self::Class};
-  let final self::Class #t354 = c{self::Class} in #t354.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t355 = self::Extension|get#property(#t354) in self::Extension|get#field(#t355).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t355, c{self::Class}) : null;
-  c = let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in let final self::Class? #t358 = self::Extension|get#field(#t357) in #t358.{core::Object::==}(null) ?{self::Class} let final self::Class #t359 = c{self::Class} in let final void #t360 = self::Extension|set#field(#t357, #t359) in #t359 : #t358{self::Class};
-  let final self::Class #t361 = c{self::Class} in #t361.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t362 = self::Extension|get#field(#t361) in let final self::Class #t363 = c{self::Class} in self::Extension|[](#t362, #t363).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t362, #t363, c{self::Class}) : null;
-  c = let final self::Class #t364 = c{self::Class} in #t364.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t365 = self::Extension|get#field(#t364) in let final self::Class #t366 = c{self::Class} in let final self::Class? #t367 = self::Extension|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class} let final self::Class #t368 = c{self::Class} in let final void #t369 = self::Extension|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t351 = n1 in #t351.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t351).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t351, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t352 = n1 in #t352.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t353 = self::Extension1|get#nullable1(#t352) in #t353.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t354 = n1{self::Class1} in let final void #t355 = self::Extension1|set#nullable1(#t352, #t354) in #t354 : #t353{self::Class1};
+  let final self::Class1? #t356 = n1 in #t356.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t357 = self::Extension1|get#nonNullable1(#t356{self::Class1}) in self::Extension1|get#nullable1(#t357{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t357{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t358 = n1 in #t358.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t359 = self::Extension1|get#nonNullable1(#t358{self::Class1}) in let final self::Class1? #t360 = self::Extension1|get#nullable1(#t359{self::Class1}) in #t360.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t361 = n1{self::Class1} in let final void #t362 = self::Extension1|set#nullable1(#t359{self::Class1}, #t361) in #t361 : #t360{self::Class1};
+  let final self::Class1? #t363 = n1 in #t363.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t364 = self::Extension1|get#nonNullable1(#t363{self::Class1}) in let final self::Class1 #t365 = n1{self::Class1} in self::Extension1|[](#t364, #t365).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t364, #t365, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t366 = n1 in #t366.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t367 = self::Extension1|get#nonNullable1(#t366{self::Class1}) in let final self::Class1 #t368 = n1{self::Class1} in let final self::Class1? #t369 = self::Extension1|[](#t367, #t368) in #t369.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t370 = n1{self::Class1} in let final void #t371 = self::Extension1|[]=(#t367, #t368, #t370) in #t370 : #t369{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
index 029ceca..1d2e7cc 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.expect
@@ -1,190 +1,277 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(#t34));
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t35, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t37 = self::Extension|get#field(new self::Class::•()) in let final void #t38 = self::Extension|set#field(#t36, #t37) in #t37;
-  let final self::Class? #t39 = c in #t39.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t39{self::Class}, let final self::Class #t40 = new self::Class::•() in let final void #t41 = self::Extension|set#field(new self::Class::•(), #t40) in #t40);
-  c = let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t43 = let final self::Class #t44 = new self::Class::•() in let final void #t45 = self::Extension|set#field(new self::Class::•(), #t44) in #t44 in let final void #t46 = self::Extension|set#field(#t42{self::Class}, #t43) in #t43;
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t47, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t49 = self::Extension|method(new self::Class::•()) in let final void #t50 = self::Extension|set#field(#t48, #t49) in #t49;
-  let final self::Class #t51 = c{self::Class} in #t51.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t51));
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t52), new self::Class::•());
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t53));
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t54)));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t55)), new self::Class::•());
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t57 = new self::Class::•() in let final void #t58 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), #t57) in #t57;
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t59)));
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t60, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t62 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t63 = self::Extension|set#field(#t61, #t62) in #t62;
-  let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t64{self::Class}, let final self::Class #t65 = new self::Class::•() in let final void #t66 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t65) in #t65);
-  c = let final self::Class? #t67 = c in #t67.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t68 = let final self::Class #t69 = new self::Class::•() in let final void #t70 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t69) in #t69 in let final void #t71 = self::Extension|set#field(#t67{self::Class}, #t68) in #t68;
-  let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t72, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t74 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t75 = self::Extension|set#field(#t73, #t74) in #t74;
-  let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t76)));
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t77)), new self::Class::•());
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|method(#t78)));
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t79), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t81 = self::Extension|get#field(new self::Class::•()) in let final void #t82 = self::Extension|set#field(self::Extension|get#property(#t80), #t81) in #t81;
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t83{self::Class}), let final self::Class #t84 = new self::Class::•() in let final void #t85 = self::Extension|set#field(new self::Class::•(), #t84) in #t84);
-  c = let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t87 = let final self::Class #t88 = new self::Class::•() in let final void #t89 = self::Extension|set#field(new self::Class::•(), #t88) in #t88 in let final void #t90 = self::Extension|set#field(self::Extension|get#property(#t86{self::Class}), #t87) in #t87;
-  let final self::Class #t91 = c{self::Class} in #t91.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t91), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t92 = c{self::Class} in #t92.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t93 = self::Extension|method(new self::Class::•()) in let final void #t94 = self::Extension|set#field(self::Extension|get#property(#t92), #t93) in #t93;
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t95, let final self::Class? #t96 = self::Extension|get#field(new self::Class::•()) in let final void #t97 = self::Extension|set#field(new self::Class::•(), #t96) in #t96);
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = let final self::Class? #t100 = self::Extension|get#field(new self::Class::•()) in let final void #t101 = self::Extension|set#field(new self::Class::•(), #t100) in #t100 in let final void #t102 = self::Extension|set#field(#t98, #t99) in #t99;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t103{self::Class}, let final self::Class #t104 = let final self::Class #t105 = new self::Class::•() in let final void #t106 = self::Extension|set#field(new self::Class::•(), #t105) in #t105 in let final void #t107 = self::Extension|set#field(new self::Class::•(), #t104) in #t104);
-  c = let final self::Class? #t108 = c in #t108.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t109 = let final self::Class #t110 = let final self::Class #t111 = new self::Class::•() in let final void #t112 = self::Extension|set#field(new self::Class::•(), #t111) in #t111 in let final void #t113 = self::Extension|set#field(new self::Class::•(), #t110) in #t110 in let final void #t114 = self::Extension|set#field(#t108{self::Class}, #t109) in #t109;
-  let final self::Class #t115 = c{self::Class} in #t115.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t115, let final self::Class #t116 = self::Extension|method(new self::Class::•()) in let final void #t117 = self::Extension|set#field(new self::Class::•(), #t116) in #t116);
-  c = let final self::Class #t118 = c{self::Class} in #t118.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t119 = let final self::Class #t120 = self::Extension|method(new self::Class::•()) in let final void #t121 = self::Extension|set#field(new self::Class::•(), #t120) in #t120 in let final void #t122 = self::Extension|set#field(#t118, #t119) in #t119;
-  let final self::Class #t123 = c{self::Class} in #t123.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t123), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t124 = c{self::Class} in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t125 = self::Extension|get#field(new self::Class::•()) in let final void #t126 = self::Extension|set#field(self::Extension|method(#t124), #t125) in #t125;
-  let final self::Class? #t127 = c in #t127.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t127{self::Class}), let final self::Class #t128 = new self::Class::•() in let final void #t129 = self::Extension|set#field(new self::Class::•(), #t128) in #t128);
-  c = let final self::Class? #t130 = c in #t130.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t131 = let final self::Class #t132 = new self::Class::•() in let final void #t133 = self::Extension|set#field(new self::Class::•(), #t132) in #t132 in let final void #t134 = self::Extension|set#field(self::Extension|method(#t130{self::Class}), #t131) in #t131;
-  let final self::Class #t135 = c{self::Class} in #t135.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t135), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t136 = c{self::Class} in #t136.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t137 = self::Extension|method(new self::Class::•()) in let final void #t138 = self::Extension|set#field(self::Extension|method(#t136), #t137) in #t137;
-  let final self::Class #t139 = c{self::Class} in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = self::Extension|get#field(#t139) in #t140.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t140{self::Class}));
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t142 = self::Extension|get#field(#t141) in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t142{self::Class}), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t144 = self::Extension|get#field(#t143) in #t144.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t145 = new self::Class::•() in let final void #t146 = self::Extension|set#field(self::Extension|method(#t144{self::Class}), #t145) in #t145;
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t148 = self::Extension|get#field(#t147) in #t148.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t148{self::Class}));
-  let final self::Class #t149 = c{self::Class} in #t149.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t149, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t150 = c{self::Class} in #t150.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t151 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t152 = self::Extension|set#field(#t150, #t151) in #t151;
-  let final self::Class? #t153 = c in #t153.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t153{self::Class}, let final self::Class #t154 = new self::Class::•() in let final void #t155 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t154) in #t154);
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t157 = let final self::Class #t158 = new self::Class::•() in let final void #t159 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t158) in #t158 in let final void #t160 = self::Extension|set#field(#t156{self::Class}, #t157) in #t157;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t161, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t162 = c{self::Class} in #t162.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t163 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t164 = self::Extension|set#field(#t162, #t163) in #t163;
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t166)), new self::Class::•());
-  let final self::Class #t167 = c{self::Class} in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t167)));
-  let final self::Class #t168 = c{self::Class} in #t168.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t169 = self::Extension|method(#t168) in #t169.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t169);
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t20 = new self::Class1::•() in let final void #t21 = self::Extension1|set#nullable1(#t19{self::Class1}, #t20) in #t20));
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t22{self::Class1})));
+  nullable1 = let final self::Class1? #t23 = n1 in #t23.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t24 = new self::Class1::•() in let final void #t25 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t23{self::Class1}), #t24) in #t24;
+  nullable1 = let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = self::Extension1|get#nullable1(#t26{self::Class1}) in #t27.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t28 = new self::Class1::•() in let final void #t29 = self::Extension1|set#nullable1(#t27{self::Class1}, #t28) in #t28;
+  nullable1 = let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t31 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t30{self::Class1})) in #t31.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t32 = new self::Class1::•() in let final void #t33 = self::Extension1|set#nullable1(#t31{self::Class1}, #t32) in #t32;
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t35 = self::Extension1|get#nullable1(#t34{self::Class1}) in #t35.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t35{self::Class1});
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t36{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t38 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t39 = self::Extension1|set#nullable1(#t37{self::Class1}, #t38) in #t38;
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t40{self::Class1}, let final self::Class1 #t41 = new self::Class1::•() in let final void #t42 = self::Extension1|set#nullable1(new self::Class1::•(), #t41) in #t41);
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t44 = let final self::Class1 #t45 = new self::Class1::•() in let final void #t46 = self::Extension1|set#nullable1(new self::Class1::•(), #t45) in #t45 in let final void #t47 = self::Extension1|set#nullable1(#t43{self::Class1}, #t44) in #t44;
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t48{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t50 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t51 = self::Extension1|set#nullable1(#t49{self::Class1}, #t50) in #t50;
+  let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t52{self::Class1}));
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t53{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t55{self::Class1})));
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t56{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t58 = new self::Class1::•() in let final void #t59 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})), #t58) in #t58;
+  let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t61 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t60{self::Class1})) in #t61.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t61{self::Class1});
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t62{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t64 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t65 = self::Extension1|set#nullable1(#t63{self::Class1}, #t64) in #t64;
+  let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t66{self::Class1}, let final self::Class1 #t67 = new self::Class1::•() in let final void #t68 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t67) in #t67);
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t70 = let final self::Class1 #t71 = new self::Class1::•() in let final void #t72 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t71) in #t71 in let final void #t73 = self::Extension1|set#nullable1(#t69{self::Class1}, #t70) in #t70;
+  let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t74{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t76 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t77 = self::Extension1|set#nullable1(#t75{self::Class1}, #t76) in #t76;
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t78{self::Class1})));
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t79{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t81{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t84 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t82{self::Class1}), #t83) in #t83;
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t85{self::Class1}), let final self::Class1 #t86 = new self::Class1::•() in let final void #t87 = self::Extension1|set#nullable1(new self::Class1::•(), #t86) in #t86);
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = let final self::Class1 #t90 = new self::Class1::•() in let final void #t91 = self::Extension1|set#nullable1(new self::Class1::•(), #t90) in #t90 in let final void #t92 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t88{self::Class1}), #t89) in #t89;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t93{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t94 = n1 in #t94.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t95 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t96 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t94{self::Class1}), #t95) in #t95;
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t97{self::Class1}, let final self::Class1? #t98 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t99 = self::Extension1|set#nullable1(new self::Class1::•(), #t98) in #t98);
+  nullable1 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t101 = let final self::Class1? #t102 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t103 = self::Extension1|set#nullable1(new self::Class1::•(), #t102) in #t102 in let final void #t104 = self::Extension1|set#nullable1(#t100{self::Class1}, #t101) in #t101;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t105{self::Class1}, let final self::Class1 #t106 = let final self::Class1 #t107 = new self::Class1::•() in let final void #t108 = self::Extension1|set#nullable1(new self::Class1::•(), #t107) in #t107 in let final void #t109 = self::Extension1|set#nullable1(new self::Class1::•(), #t106) in #t106);
+  nullable1 = let final self::Class1? #t110 = n1 in #t110.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t111 = let final self::Class1 #t112 = let final self::Class1 #t113 = new self::Class1::•() in let final void #t114 = self::Extension1|set#nullable1(new self::Class1::•(), #t113) in #t113 in let final void #t115 = self::Extension1|set#nullable1(new self::Class1::•(), #t112) in #t112 in let final void #t116 = self::Extension1|set#nullable1(#t110{self::Class1}, #t111) in #t111;
+  let final self::Class1? #t117 = n1 in #t117.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t117{self::Class1}, let final self::Class1 #t118 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t119 = self::Extension1|set#nullable1(new self::Class1::•(), #t118) in #t118);
+  nullable1 = let final self::Class1? #t120 = n1 in #t120.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t121 = let final self::Class1 #t122 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t123 = self::Extension1|set#nullable1(new self::Class1::•(), #t122) in #t122 in let final void #t124 = self::Extension1|set#nullable1(#t120{self::Class1}, #t121) in #t121;
+  let final self::Class1? #t125 = n1 in #t125.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t125{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t126 = n1 in #t126.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t127 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t128 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t126{self::Class1}), #t127) in #t127;
+  let final self::Class1? #t129 = n1 in #t129.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t129{self::Class1}), let final self::Class1 #t130 = new self::Class1::•() in let final void #t131 = self::Extension1|set#nullable1(new self::Class1::•(), #t130) in #t130);
+  nullable1 = let final self::Class1? #t132 = n1 in #t132.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t133 = let final self::Class1 #t134 = new self::Class1::•() in let final void #t135 = self::Extension1|set#nullable1(new self::Class1::•(), #t134) in #t134 in let final void #t136 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t132{self::Class1}), #t133) in #t133;
+  let final self::Class1? #t137 = n1 in #t137.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t137{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t139 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t140 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t138{self::Class1}), #t139) in #t139;
+  let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t141{self::Class1})));
+  let final self::Class1? #t142 = n1 in #t142.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t142{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t144 = new self::Class1::•() in let final void #t145 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})), #t144) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t146{self::Class1})));
+  let final self::Class1? #t147 = n1 in #t147.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t147{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t149 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t150 = self::Extension1|set#nullable1(#t148{self::Class1}, #t149) in #t149;
+  let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t151{self::Class1}, let final self::Class1 #t152 = new self::Class1::•() in let final void #t153 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t152) in #t152);
+  nullable1 = let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t155 = let final self::Class1 #t156 = new self::Class1::•() in let final void #t157 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t156) in #t156 in let final void #t158 = self::Extension1|set#nullable1(#t154{self::Class1}, #t155) in #t155;
+  let final self::Class1? #t159 = n1 in #t159.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t159{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t160 = n1 in #t160.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t161 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t162 = self::Extension1|set#nullable1(#t160{self::Class1}, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t163{self::Class1})));
+  let final self::Class1? #t164 = n1 in #t164.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t164{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t167 = self::Extension1|nonNullable1Method(#t166{self::Class1}) in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t167{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t170 = c in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t170{self::Class}, c{self::Class});
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t171{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t172 = c in #t172.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t173 = self::Extension|[](#t172{self::Class}, c{self::Class}) in #t173.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t173{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t174{self::Class}), c{self::Class});
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t175{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t176 = c in #t176.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t177 = self::Extension|get#field(#t176{self::Class}) in let final self::Class #t178 = c{self::Class} in let final self::Class #t179 = new self::Class::•() in let final void #t180 = self::Extension|[]=(#t177, #t178, #t179) in #t179;
-  let final self::Class #t181 = c{self::Class} in #t181.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t182 = self::Extension|[](self::Extension|get#field(#t181), c{self::Class}) in #t182.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t182{self::Class});
-  let final self::Class #t183 = c{self::Class} in #t183.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t184 = self::Extension|get#field(#t183) in let final self::Class #t185 = c{self::Class} in self::Extension|[]=(#t184, #t185, self::Extension|+(self::Extension|[](#t184, #t185), 0));
-  c = let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in let final self::Class? #t189 = self::Extension|+(self::Extension|[](#t187, #t188), 0) in let final void #t190 = self::Extension|[]=(#t187, #t188, #t189) in #t189;
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t192 = c{self::Class} in self::Extension|[](#t191{self::Class}, #t192).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t191{self::Class}, #t192, c{self::Class}) : null;
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t194 = c{self::Class} in let final self::Class? #t195 = self::Extension|[](#t193{self::Class}, #t194) in #t195.{core::Object::==}(null) ?{self::Class} let final self::Class #t196 = c{self::Class} in let final void #t197 = self::Extension|[]=(#t193{self::Class}, #t194, #t196) in #t196 : #t195{self::Class};
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t199 = c{self::Class} in self::Extension|[]=(#t198, #t199, self::Extension|+(self::Extension|[](#t198, #t199), 0));
-  c = let final self::Class #t200 = c{self::Class} in #t200.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t201 = c{self::Class} in let final self::Class? #t202 = self::Extension|+(self::Extension|[](#t200, #t201), 0) in let final void #t203 = self::Extension|[]=(#t200, #t201, #t202) in #t202;
-  let final self::Class? #t204 = c in #t204.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t205 = c{self::Class} in self::Extension|[]=(#t204{self::Class}, #t205, self::Extension|+(self::Extension|[](#t204{self::Class}, #t205), 0));
-  c = let final self::Class? #t206 = c in #t206.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t207 = c{self::Class} in let final self::Class? #t208 = self::Extension|+(self::Extension|[](#t206{self::Class}, #t207), 0) in let final void #t209 = self::Extension|[]=(#t206{self::Class}, #t207, #t208) in #t208;
-  let final self::Class? #t210 = c in #t210.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t211 = c{self::Class} in self::Extension|[]=(#t210{self::Class}, #t211, self::Extension|+(self::Extension|[](#t210{self::Class}, #t211), 1));
-  c = let final self::Class? #t212 = c in #t212.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t213 = c{self::Class} in let final self::Class? #t214 = self::Extension|[](#t212{self::Class}, #t213) in let final void #t215 = self::Extension|[]=(#t212{self::Class}, #t213, self::Extension|+(#t214, 1)) in #t214;
-  let final self::Class? #t216 = c in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t217 = c{self::Class} in let final self::Class? #t218 = self::Extension|+(self::Extension|[](#t216{self::Class}, #t217), 1) in let final void #t219 = self::Extension|[]=(#t216{self::Class}, #t217, #t218) in #t218;
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t168{self::Class1}, nullable1);
+  let final self::Class1? #t169 = n1 in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t169{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t171 = self::Extension1|[](#t170{self::Class1}, nullable1) in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t171{self::Class1});
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t172{self::Class1}), nullable1);
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t173{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t175 = self::Extension1|get#nonNullable1(#t174{self::Class1}) in let final self::Class1? #t176 = nullable1 in let final self::Class1 #t177 = new self::Class1::•() in let final void #t178 = self::Extension1|[]=(#t175, #t176, #t177) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t180 = self::Extension1|[](self::Extension1|get#nonNullable1(#t179{self::Class1}), nullable1) in #t180.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t180{self::Class1});
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = self::Extension1|get#nonNullable2(#t181{self::Class1}) in let final self::Class2? #t183 = nullable2 in self::Extension2|[]=(#t182, #t183, self::Extension2|+(self::Extension2|[](#t182, #t183), 0));
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = self::Extension1|get#nonNullable2(#t184{self::Class1}) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = self::Extension2|+(self::Extension2|[](#t185, #t186), 0) in let final void #t188 = self::Extension2|[]=(#t185, #t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = nullable1 in self::Extension1|[](#t189{self::Class1}, #t190).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t189{self::Class1}, #t190, nullable1) : null;
+  nullable1 = let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in let final self::Class1? #t193 = self::Extension1|[](#t191{self::Class1}, #t192) in #t193.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t194 = nullable1 in let final void #t195 = self::Extension1|[]=(#t191{self::Class1}, #t192, #t194) in #t194 : #t193{self::Class1};
+  let final self::Class2? #t196 = n2 in #t196.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t197 = nullable2 in self::Extension2|[]=(#t196{self::Class2}, #t197, self::Extension2|+(self::Extension2|[](#t196{self::Class2}, #t197), 0));
+  nullable2 = let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in let final self::Class2 #t200 = self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0) in let final void #t201 = self::Extension2|[]=(#t198{self::Class2}, #t199, #t200) in #t200;
+  let final self::Class2? #t202 = n2 in #t202.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t203 = nullable2 in self::Extension2|[]=(#t202{self::Class2}, #t203, self::Extension2|+(self::Extension2|[](#t202{self::Class2}, #t203), 0));
+  nullable2 = let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in let final self::Class2 #t206 = self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0) in let final void #t207 = self::Extension2|[]=(#t204{self::Class2}, #t205, #t206) in #t206;
+  let final self::Class2? #t208 = n2 in #t208.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t209 = nullable2 in self::Extension2|[]=(#t208{self::Class2}, #t209, self::Extension2|+(self::Extension2|[](#t208{self::Class2}, #t209), 1));
+  nullable2 = let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in let final self::Class2 #t212 = self::Extension2|[](#t210{self::Class2}, #t211) in let final void #t213 = self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(#t212, 1)) in #t212;
+  let final self::Class2? #t214 = n2 in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in let final self::Class2 #t216 = self::Extension2|+(self::Extension2|[](#t214{self::Class2}, #t215), 1) in let final void #t217 = self::Extension2|[]=(#t214{self::Class2}, #t215, #t216) in #t216;
+  nullable2 = let final self::Class2? #t218 = n2 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = nullable2 in let final self::Class2 #t220 = self::Extension2|+(self::Extension2|[](#t218{self::Class2}, #t219), 1) in let final void #t221 = self::Extension2|[]=(#t218{self::Class2}, #t219, #t220) in #t220;
+  let final self::Class1? #t222 = n1 in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t223 = self::Extension1|get#nonNullable2(#t222{self::Class1}) in let final self::Class2? #t224 = nullable2 in self::Extension2|[]=(#t223, #t224, self::Extension2|+(self::Extension2|[](#t223, #t224), 1));
+  nullable2 = let final self::Class1? #t225 = n1 in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t226 = self::Extension1|get#nonNullable2(#t225{self::Class1}) in let final self::Class2? #t227 = nullable2 in let final self::Class2 #t228 = self::Extension2|[](#t226, #t227) in let final void #t229 = self::Extension2|[]=(#t226, #t227, self::Extension2|+(#t228, 1)) in #t228;
+  let final self::Class1? #t230 = n1 in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t231 = self::Extension1|get#nonNullable2(#t230{self::Class1}) in let final self::Class2? #t232 = nullable2 in let final self::Class2 #t233 = self::Extension2|+(self::Extension2|[](#t231, #t232), 1) in let final void #t234 = self::Extension2|[]=(#t231, #t232, #t233) in #t233;
+  nullable2 = let final self::Class1? #t235 = n1 in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t236 = self::Extension1|get#nonNullable2(#t235{self::Class1}) in let final self::Class2? #t237 = nullable2 in let final self::Class2 #t238 = self::Extension2|+(self::Extension2|[](#t236, #t237), 1) in let final void #t239 = self::Extension2|[]=(#t236, #t237, #t238) in #t238;
+  let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t240{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t241 = n1 in #t241.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t241{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2) in let final self::Class2? #t244 = nullable2 in let final self::Class2 #t245 = new self::Class2::•() in let final void #t246 = self::Extension2|[]=(#t243, #t244, #t245) in #t245;
+  let final self::Class1? #t247 = n1 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t248 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t247{self::Class1}), nullable2), nullable2) in #t248.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t248{self::Class2});
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2) in let final self::Class2? #t251 = nullable2 in self::Extension2|[]=(#t250, #t251, self::Extension2|+(self::Extension2|[](#t250, #t251), 0));
+  nullable2 = let final self::Class1? #t252 = n1 in #t252.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t253 = self::Extension2|[](self::Extension1|get#nonNullable2(#t252{self::Class1}), nullable2) in let final self::Class2? #t254 = nullable2 in let final self::Class2 #t255 = self::Extension2|+(self::Extension2|[](#t253, #t254), 0) in let final void #t256 = self::Extension2|[]=(#t253, #t254, #t255) in #t255;
+  let final self::Class1? #t257 = n1 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = self::Extension2|[](self::Extension1|get#nonNullable2(#t257{self::Class1}), nullable2) in let final self::Class2? #t259 = nullable2 in self::Extension2|[]=(#t258, #t259, self::Extension2|+(self::Extension2|[](#t258, #t259), 1));
+  nullable2 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = self::Extension2|[](self::Extension1|get#nonNullable2(#t260{self::Class1}), nullable2) in let final self::Class2? #t262 = nullable2 in let final self::Class2 #t263 = self::Extension2|[](#t261, #t262) in let final void #t264 = self::Extension2|[]=(#t261, #t262, self::Extension2|+(#t263, 1)) in #t263;
+  let final self::Class1? #t265 = n1 in #t265.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t266 = self::Extension2|[](self::Extension1|get#nonNullable2(#t265{self::Class1}), nullable2) in let final self::Class2? #t267 = nullable2 in let final self::Class2 #t268 = self::Extension2|+(self::Extension2|[](#t266, #t267), 1) in let final void #t269 = self::Extension2|[]=(#t266, #t267, #t268) in #t268;
+  nullable2 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t271 = self::Extension2|[](self::Extension1|get#nonNullable2(#t270{self::Class1}), nullable2) in let final self::Class2? #t272 = nullable2 in let final self::Class2 #t273 = self::Extension2|+(self::Extension2|[](#t271, #t272), 1) in let final void #t274 = self::Extension2|[]=(#t271, #t272, #t273) in #t273;
+  let final self::Class1? #t275 = n1 in #t275.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t276 = self::Extension1|[](#t275{self::Class1}, nullable1) in #t276.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t276{self::Class1}, nullable1);
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t278{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t281 = nullable1 in let final self::Class1 #t282 = new self::Class1::•() in let final void #t283 = self::Extension1|[]=(#t280{self::Class1}, #t281, #t282) in #t282;
+  let final self::Class1? #t284 = n1 in #t284.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t285 = self::Extension1|[](#t284{self::Class1}, nullable1) in #t285.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t286 = self::Extension1|[](#t285{self::Class1}, nullable1) in #t286.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t286{self::Class1});
+  nullable1 = let final self::Class1? #t287 = n1 in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t289 = self::Extension1|[](#t288{self::Class1}, nullable1) in #t289.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t289{self::Class1});
+  let final self::Class1? #t290 = n1 in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t292 = nullable1 in self::Extension1|[](#t291{self::Class1}, #t292).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t291{self::Class1}, #t292, nullable1) : null;
+  nullable1 = let final self::Class1? #t293 = n1 in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = self::Extension1|[](#t293{self::Class1}, nullable1) in #t294.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t295 = nullable1 in let final self::Class1? #t296 = self::Extension1|[](#t294{self::Class1}, #t295) in #t296.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t297 = nullable1 in let final void #t298 = self::Extension1|[]=(#t294{self::Class1}, #t295, #t297) in #t297 : #t296{self::Class1};
+  let final self::Class3? #t299 = n3 in #t299.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t300 = self::Extension3|[](#t299{self::Class3}, nullable3) in #t300.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t301 = nullable2 in self::Extension2|[]=(#t300{self::Class2}, #t301, self::Extension2|+(self::Extension2|[](#t300{self::Class2}, #t301), 0));
+  nullable2 = let final self::Class3? #t302 = n3 in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = self::Extension3|[](#t302{self::Class3}, nullable3) in #t303.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t304 = nullable2 in let final self::Class2 #t305 = self::Extension2|+(self::Extension2|[](#t303{self::Class2}, #t304), 0) in let final void #t306 = self::Extension2|[]=(#t303{self::Class2}, #t304, #t305) in #t305;
+  let final self::Class3? #t307 = n3 in #t307.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t308 = self::Extension3|[](#t307{self::Class3}, nullable3) in #t308.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t309 = nullable2 in self::Extension2|[]=(#t308{self::Class2}, #t309, self::Extension2|+(self::Extension2|[](#t308{self::Class2}, #t309), 1));
+  nullable2 = let final self::Class3? #t310 = n3 in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = self::Extension3|[](#t310{self::Class3}, nullable3) in #t311.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t312 = nullable2 in let final self::Class2 #t313 = self::Extension2|[](#t311{self::Class2}, #t312) in let final void #t314 = self::Extension2|[]=(#t311{self::Class2}, #t312, self::Extension2|+(#t313, 1)) in #t313;
+  let final self::Class3? #t315 = n3 in #t315.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t316 = self::Extension3|[](#t315{self::Class3}, nullable3) in #t316.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t317 = nullable2 in let final self::Class2 #t318 = self::Extension2|+(self::Extension2|[](#t316{self::Class2}, #t317), 1) in let final void #t319 = self::Extension2|[]=(#t316{self::Class2}, #t317, #t318) in #t318;
+  nullable2 = let final self::Class3? #t320 = n3 in #t320.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t321 = self::Extension3|[](#t320{self::Class3}, nullable3) in #t321.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t322 = nullable2 in let final self::Class2 #t323 = self::Extension2|+(self::Extension2|[](#t321{self::Class2}, #t322), 1) in let final void #t324 = self::Extension2|[]=(#t321{self::Class2}, #t322, #t323) in #t323;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329, self::Extension|+(self::Extension|get#field(#t329), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330), 0) in let final void #t332 = self::Extension|set#field(#t330, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339, self::Extension|+(self::Extension|get#field(#t339), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340) in let final void #t342 = self::Extension|set#field(#t340, self::Extension|+(#t341, 1)) in #t341;
-  let final self::Class? #t343 = c in #t343.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t344 = self::Extension|+(self::Extension|get#field(#t343), 1) in let final void #t345 = self::Extension|set#field(#t343, #t344) in #t344;
-  c = let final self::Class? #t346 = c in #t346.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t347 = self::Extension|+(self::Extension|get#field(#t346), 1) in let final void #t348 = self::Extension|set#field(#t346, #t347) in #t347;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => self::Extension1|+(let final self::Class1? #t325 = n1 in #t325.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t325{self::Class1}), 0));
+  self::throws(() → self::Class1? => self::Extension1|unary-(let final self::Class1? #t326 = n1 in #t326.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t326{self::Class1})));
+  let final self::Class2? #t327 = n2 in #t327.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t327, self::Extension2|+(self::Extension2|get#nonNullable2(#t327), 0));
+  nullable2 = let final self::Class2? #t328 = n2 in #t328.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t329 = self::Extension2|+(self::Extension2|get#nonNullable2(#t328), 0) in let final void #t330 = self::Extension2|set#nonNullable2(#t328, #t329) in #t329;
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t332 = self::Extension2|get#nonNullable2(#t331{self::Class2}) in self::Extension2|set#nonNullable2(#t332, self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0));
+  nullable2 = let final self::Class2? #t333 = n2 in #t333.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t334 = self::Extension2|get#nonNullable2(#t333{self::Class2}) in let final self::Class2 #t335 = self::Extension2|+(self::Extension2|get#nonNullable2(#t334), 0) in let final void #t336 = self::Extension2|set#nonNullable2(#t334, #t335) in #t335;
+  let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t337, self::Extension2|+(self::Extension2|get#nonNullable2(#t337), 1));
+  nullable2 = let final self::Class2? #t338 = n2 in #t338.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t339 = self::Extension2|get#nonNullable2(#t338) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, self::Extension2|+(#t339, 1)) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t342 = self::Extension2|+(self::Extension2|get#nonNullable2(#t341), 1) in let final void #t343 = self::Extension2|set#nonNullable2(#t341, #t342) in #t342;
+  nullable2 = let final self::Class2? #t344 = n2 in #t344.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t345 = self::Extension2|+(self::Extension2|get#nonNullable2(#t344), 1) in let final void #t346 = self::Extension2|set#nonNullable2(#t344, #t345) in #t345;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t349 = c in #t349.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t349).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t349, c{self::Class}) : null;
-  c = let final self::Class? #t350 = c in #t350.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t351 = self::Extension|get#field(#t350) in #t351.{core::Object::==}(null) ?{self::Class} let final self::Class #t352 = c{self::Class} in let final void #t353 = self::Extension|set#field(#t350, #t352) in #t352 : #t351{self::Class};
-  let final self::Class #t354 = c{self::Class} in #t354.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t355 = self::Extension|get#property(#t354) in self::Extension|get#field(#t355).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t355, c{self::Class}) : null;
-  c = let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in let final self::Class? #t358 = self::Extension|get#field(#t357) in #t358.{core::Object::==}(null) ?{self::Class} let final self::Class #t359 = c{self::Class} in let final void #t360 = self::Extension|set#field(#t357, #t359) in #t359 : #t358{self::Class};
-  let final self::Class #t361 = c{self::Class} in #t361.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t362 = self::Extension|get#field(#t361) in let final self::Class #t363 = c{self::Class} in self::Extension|[](#t362, #t363).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t362, #t363, c{self::Class}) : null;
-  c = let final self::Class #t364 = c{self::Class} in #t364.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t365 = self::Extension|get#field(#t364) in let final self::Class #t366 = c{self::Class} in let final self::Class? #t367 = self::Extension|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class} let final self::Class #t368 = c{self::Class} in let final void #t369 = self::Extension|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t347 = n1 in #t347.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t347).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t347, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t348 = n1 in #t348.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t349 = self::Extension1|get#nullable1(#t348) in #t349.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t350 = n1{self::Class1} in let final void #t351 = self::Extension1|set#nullable1(#t348, #t350) in #t350 : #t349{self::Class1};
+  let final self::Class1? #t352 = n1 in #t352.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t353 = self::Extension1|get#nonNullable1(#t352{self::Class1}) in self::Extension1|get#nullable1(#t353{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t353{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nonNullable1(#t354{self::Class1}) in let final self::Class1? #t356 = self::Extension1|get#nullable1(#t355{self::Class1}) in #t356.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t357 = n1{self::Class1} in let final void #t358 = self::Extension1|set#nullable1(#t355{self::Class1}, #t357) in #t357 : #t356{self::Class1};
+  let final self::Class1? #t359 = n1 in #t359.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t360 = self::Extension1|get#nonNullable1(#t359{self::Class1}) in let final self::Class1 #t361 = n1{self::Class1} in self::Extension1|[](#t360, #t361).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t360, #t361, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t362 = n1 in #t362.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t363 = self::Extension1|get#nonNullable1(#t362{self::Class1}) in let final self::Class1 #t364 = n1{self::Class1} in let final self::Class1? #t365 = self::Extension1|[](#t363, #t364) in #t365.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t366 = n1{self::Class1} in let final void #t367 = self::Extension1|[]=(#t363, #t364, #t366) in #t366 : #t365{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
index 029ceca..1d2e7cc 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.weak.transformed.expect
@@ -1,190 +1,277 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:93:47: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nullable1 = new Class1()).nullable1);
+//                                               ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:94:43: Warning: Property 'nullable1' is accessed on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+// Try accessing using ?. instead.
+//   throws(() => (n1?.nonNullable1Method()).nullable1);
+//                                           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:232:33: Warning: Operator '+' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => n1?.nonNullable1 + 0);
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/null_shorting_extension.dart:233:16: Warning: Operator 'unary-' is called on 'Class1?' which is potentially null.
+//  - 'Class1' is from 'pkg/front_end/testcases/nnbd/null_shorting_extension.dart'.
+//   throws(() => -n1?.nonNullable1);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
-class Class extends core::Object {
-  field self::Class? _field = null;
-  synthetic constructor •() → self::Class
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
     : super core::Object::•()
     ;
+  get property() → self::Class1?
+    return null;
+  set property(self::Class1? value) → void {}
+  get property1() → self::Class1
+    return new self::Class1::•();
+  get property2() → self::Class2
+    return new self::Class2::•();
 }
-extension Extension on self::Class {
-  get field = self::Extension|get#field;
-  method method = self::Extension|method;
-  tearoff method = self::Extension|get#method;
-  operator [] = self::Extension|[];
-  operator []= = self::Extension|[]=;
-  operator + = self::Extension|+;
-  operator unary- = self::Extension|unary-;
-  get property = self::Extension|get#property;
-  set field = self::Extension|set#field;
+class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  get property() → self::Class2
+    return this;
+  set property(self::Class2 value) → void {}
 }
-static method Extension|get#field(final self::Class #this) → self::Class?
-  return #this.{self::Class::_field};
-static method Extension|set#field(final self::Class #this, self::Class? value) → void {
-  #this.{self::Class::_field} = value;
+class Class3 extends core::Object {
+  synthetic constructor •() → self::Class3
+    : super core::Object::•()
+    ;
+  get property() → self::Class2?
+    return null;
 }
-static method Extension|method(final self::Class #this) → self::Class
-  return self::Extension|get#property(#this);
-static method Extension|get#method(final self::Class #this) → () → self::Class
-  return () → self::Class => self::Extension|method(#this);
-static method Extension|[](final self::Class #this, self::Class? key) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|[]=(final self::Class #this, self::Class? key, self::Class? value) → void {
-  self::Extension|set#field(#this, value);
+extension Extension1 on self::Class1 {
+  get nullable1 = self::Extension1|get#nullable1;
+  method nonNullable1Method = self::Extension1|nonNullable1Method;
+  tearoff nonNullable1Method = self::Extension1|get#nonNullable1Method;
+  operator [] = self::Extension1|[];
+  operator []= = self::Extension1|[]=;
+  operator + = self::Extension1|+;
+  operator unary- = self::Extension1|unary-;
+  get nonNullable1 = self::Extension1|get#nonNullable1;
+  get nonNullable2 = self::Extension1|get#nonNullable2;
+  set nullable1 = self::Extension1|set#nullable1;
 }
-static method Extension|+(final self::Class #this, core::int value) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|unary-(final self::Class #this) → self::Class?
-  return self::Extension|get#field(#this);
-static method Extension|get#property(final self::Class #this) → self::Class
-  return #this;
+extension Extension2 on self::Class2 {
+  method nonNullable2Method = self::Extension2|nonNullable2Method;
+  tearoff nonNullable2Method = self::Extension2|get#nonNullable2Method;
+  operator [] = self::Extension2|[];
+  operator []= = self::Extension2|[]=;
+  operator + = self::Extension2|+;
+  operator unary- = self::Extension2|unary-;
+  get nonNullable2 = self::Extension2|get#nonNullable2;
+  set nonNullable2 = self::Extension2|set#nonNullable2;
+}
+extension Extension3 on self::Class3 {
+  operator [] = self::Extension3|[];
+}
+static method Extension1|get#nullable1(final self::Class1 #this) → self::Class1?
+  return #this.{self::Class1::property1};
+static method Extension1|set#nullable1(final self::Class1 #this, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|nonNullable1Method(final self::Class1 #this) → self::Class1
+  return self::Extension1|get#nonNullable1(#this);
+static method Extension1|get#nonNullable1Method(final self::Class1 #this) → () → self::Class1
+  return () → self::Class1 => self::Extension1|nonNullable1Method(#this);
+static method Extension1|[](final self::Class1 #this, self::Class1? key) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|[]=(final self::Class1 #this, self::Class1? key, self::Class1? value) → void {
+  #this.{self::Class1::property} = value;
+}
+static method Extension1|+(final self::Class1 #this, core::int value) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|unary-(final self::Class1 #this) → self::Class1?
+  return self::Extension1|get#nullable1(#this);
+static method Extension1|get#nonNullable1(final self::Class1 #this) → self::Class1
+  return #this.{self::Class1::property1};
+static method Extension1|get#nonNullable2(final self::Class1 #this) → self::Class2
+  return #this.{self::Class1::property2};
+static method Extension2|nonNullable2Method(final self::Class2 #this) → self::Class2
+  return self::Extension2|get#nonNullable2(#this);
+static method Extension2|get#nonNullable2Method(final self::Class2 #this) → () → self::Class2
+  return () → self::Class2 => self::Extension2|nonNullable2Method(#this);
+static method Extension2|[](final self::Class2 #this, self::Class2? key) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|[]=(final self::Class2 #this, self::Class2? key, self::Class2? value) → void
+  return #this.{self::Class2::property};
+static method Extension2|+(final self::Class2 #this, core::int value) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|unary-(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|get#nonNullable2(final self::Class2 #this) → self::Class2
+  return #this.{self::Class2::property};
+static method Extension2|set#nonNullable2(final self::Class2 #this, self::Class2 value) → void {
+  #this.{self::Class2::property} = value;
+}
+static method Extension3|[](final self::Class3 #this, self::Class3? key) → self::Class2?
+  return #this.{self::Class3::property};
 static method main() → dynamic {
   self::propertyAccess(null);
-  self::indexAccess(null);
-  self::operatorAccess(null);
+  self::indexAccess(null, null, null);
+  self::operatorAccess(null, null);
   self::ifNull(null);
 }
-static method propertyAccess(self::Class? c) → void {
-  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t1{self::Class});
-  let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t2{self::Class}, new self::Class::•());
-  c = let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t4 = new self::Class::•() in let final void #t5 = self::Extension|set#field(#t3{self::Class}, #t4) in #t4;
-  let final self::Class #t6 = c{self::Class} in #t6.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t6);
-  let final self::Class #t7 = c{self::Class} in #t7.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(#t7));
-  let final self::Class #t8 = c{self::Class} in #t8.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t9 = self::Extension|get#field(#t8) in #t9.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t9{self::Class});
-  let final self::Class #t10 = c{self::Class} in #t10.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t11 = self::Extension|get#field(self::Extension|get#property(#t10)) in #t11.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t11{self::Class});
-  let final self::Class #t12 = c{self::Class} in #t12.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t12), new self::Class::•());
-  let final self::Class #t13 = c{self::Class} in #t13.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t14 = self::Extension|get#field(#t13) in #t14.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t14{self::Class}, new self::Class::•());
-  let final self::Class #t15 = c{self::Class} in #t15.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t16 = self::Extension|get#field(self::Extension|get#property(#t15)) in #t16.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t16{self::Class}, new self::Class::•());
-  let final self::Class? #t17 = let final self::Class #t18 = c{self::Class} in #t18.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t18) in #t17.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t17{self::Class});
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t20 = new self::Class::•() in let final void #t21 = self::Extension|set#field(#t19{self::Class}, #t20) in #t20));
-  self::throws(() → self::Class? => self::Extension|get#field(let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t22{self::Class})));
-  c = let final self::Class #t23 = c{self::Class} in #t23.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t24 = new self::Class::•() in let final void #t25 = self::Extension|set#field(self::Extension|get#property(#t23), #t24) in #t24;
-  c = let final self::Class #t26 = c{self::Class} in #t26.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t27 = self::Extension|get#field(#t26) in #t27.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t28 = new self::Class::•() in let final void #t29 = self::Extension|set#field(#t27{self::Class}, #t28) in #t28;
-  c = let final self::Class #t30 = c{self::Class} in #t30.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t31 = self::Extension|get#field(self::Extension|get#property(#t30)) in #t31.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t32 = new self::Class::•() in let final void #t33 = self::Extension|set#field(#t31{self::Class}, #t32) in #t32;
-  let final self::Class #t34 = c{self::Class} in #t34.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(#t34));
-  let final self::Class #t35 = c{self::Class} in #t35.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t35, self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t36 = c{self::Class} in #t36.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t37 = self::Extension|get#field(new self::Class::•()) in let final void #t38 = self::Extension|set#field(#t36, #t37) in #t37;
-  let final self::Class? #t39 = c in #t39.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t39{self::Class}, let final self::Class #t40 = new self::Class::•() in let final void #t41 = self::Extension|set#field(new self::Class::•(), #t40) in #t40);
-  c = let final self::Class? #t42 = c in #t42.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t43 = let final self::Class #t44 = new self::Class::•() in let final void #t45 = self::Extension|set#field(new self::Class::•(), #t44) in #t44 in let final void #t46 = self::Extension|set#field(#t42{self::Class}, #t43) in #t43;
-  let final self::Class #t47 = c{self::Class} in #t47.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t47, self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t48 = c{self::Class} in #t48.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t49 = self::Extension|method(new self::Class::•()) in let final void #t50 = self::Extension|set#field(#t48, #t49) in #t49;
-  let final self::Class #t51 = c{self::Class} in #t51.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t51));
-  let final self::Class #t52 = c{self::Class} in #t52.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t52), new self::Class::•());
-  let final self::Class #t53 = c{self::Class} in #t53.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t53));
-  let final self::Class #t54 = c{self::Class} in #t54.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|get#property(#t54)));
-  let final self::Class #t55 = c{self::Class} in #t55.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t55)), new self::Class::•());
-  c = let final self::Class #t56 = c{self::Class} in #t56.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t57 = new self::Class::•() in let final void #t58 = self::Extension|set#field(self::Extension|get#property(self::Extension|get#property(#t56)), #t57) in #t57;
-  let final self::Class #t59 = c{self::Class} in #t59.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|get#property(#t59)));
-  let final self::Class #t60 = c{self::Class} in #t60.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t60, self::Extension|get#field(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t61 = c{self::Class} in #t61.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t62 = self::Extension|get#field(self::Extension|get#property(new self::Class::•())) in let final void #t63 = self::Extension|set#field(#t61, #t62) in #t62;
-  let final self::Class? #t64 = c in #t64.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t64{self::Class}, let final self::Class #t65 = new self::Class::•() in let final void #t66 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t65) in #t65);
-  c = let final self::Class? #t67 = c in #t67.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t68 = let final self::Class #t69 = new self::Class::•() in let final void #t70 = self::Extension|set#field(self::Extension|get#property(new self::Class::•()), #t69) in #t69 in let final void #t71 = self::Extension|set#field(#t67{self::Class}, #t68) in #t68;
-  let final self::Class #t72 = c{self::Class} in #t72.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t72, self::Extension|method(self::Extension|get#property(new self::Class::•())));
-  c = let final self::Class #t73 = c{self::Class} in #t73.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t74 = self::Extension|method(self::Extension|get#property(new self::Class::•())) in let final void #t75 = self::Extension|set#field(#t73, #t74) in #t74;
-  let final self::Class #t76 = c{self::Class} in #t76.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|get#property(self::Extension|method(#t76)));
-  let final self::Class #t77 = c{self::Class} in #t77.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(self::Extension|method(#t77)), new self::Class::•());
-  let final self::Class #t78 = c{self::Class} in #t78.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|get#property(self::Extension|method(#t78)));
-  let final self::Class #t79 = c{self::Class} in #t79.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|get#property(#t79), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t80 = c{self::Class} in #t80.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t81 = self::Extension|get#field(new self::Class::•()) in let final void #t82 = self::Extension|set#field(self::Extension|get#property(#t80), #t81) in #t81;
-  let final self::Class? #t83 = c in #t83.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t83{self::Class}), let final self::Class #t84 = new self::Class::•() in let final void #t85 = self::Extension|set#field(new self::Class::•(), #t84) in #t84);
-  c = let final self::Class? #t86 = c in #t86.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t87 = let final self::Class #t88 = new self::Class::•() in let final void #t89 = self::Extension|set#field(new self::Class::•(), #t88) in #t88 in let final void #t90 = self::Extension|set#field(self::Extension|get#property(#t86{self::Class}), #t87) in #t87;
-  let final self::Class #t91 = c{self::Class} in #t91.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|get#property(#t91), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t92 = c{self::Class} in #t92.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t93 = self::Extension|method(new self::Class::•()) in let final void #t94 = self::Extension|set#field(self::Extension|get#property(#t92), #t93) in #t93;
-  let final self::Class #t95 = c{self::Class} in #t95.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t95, let final self::Class? #t96 = self::Extension|get#field(new self::Class::•()) in let final void #t97 = self::Extension|set#field(new self::Class::•(), #t96) in #t96);
-  c = let final self::Class #t98 = c{self::Class} in #t98.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t99 = let final self::Class? #t100 = self::Extension|get#field(new self::Class::•()) in let final void #t101 = self::Extension|set#field(new self::Class::•(), #t100) in #t100 in let final void #t102 = self::Extension|set#field(#t98, #t99) in #t99;
-  let final self::Class? #t103 = c in #t103.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t103{self::Class}, let final self::Class #t104 = let final self::Class #t105 = new self::Class::•() in let final void #t106 = self::Extension|set#field(new self::Class::•(), #t105) in #t105 in let final void #t107 = self::Extension|set#field(new self::Class::•(), #t104) in #t104);
-  c = let final self::Class? #t108 = c in #t108.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t109 = let final self::Class #t110 = let final self::Class #t111 = new self::Class::•() in let final void #t112 = self::Extension|set#field(new self::Class::•(), #t111) in #t111 in let final void #t113 = self::Extension|set#field(new self::Class::•(), #t110) in #t110 in let final void #t114 = self::Extension|set#field(#t108{self::Class}, #t109) in #t109;
-  let final self::Class #t115 = c{self::Class} in #t115.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t115, let final self::Class #t116 = self::Extension|method(new self::Class::•()) in let final void #t117 = self::Extension|set#field(new self::Class::•(), #t116) in #t116);
-  c = let final self::Class #t118 = c{self::Class} in #t118.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t119 = let final self::Class #t120 = self::Extension|method(new self::Class::•()) in let final void #t121 = self::Extension|set#field(new self::Class::•(), #t120) in #t120 in let final void #t122 = self::Extension|set#field(#t118, #t119) in #t119;
-  let final self::Class #t123 = c{self::Class} in #t123.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(self::Extension|method(#t123), self::Extension|get#field(new self::Class::•()));
-  c = let final self::Class #t124 = c{self::Class} in #t124.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t125 = self::Extension|get#field(new self::Class::•()) in let final void #t126 = self::Extension|set#field(self::Extension|method(#t124), #t125) in #t125;
-  let final self::Class? #t127 = c in #t127.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t127{self::Class}), let final self::Class #t128 = new self::Class::•() in let final void #t129 = self::Extension|set#field(new self::Class::•(), #t128) in #t128);
-  c = let final self::Class? #t130 = c in #t130.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t131 = let final self::Class #t132 = new self::Class::•() in let final void #t133 = self::Extension|set#field(new self::Class::•(), #t132) in #t132 in let final void #t134 = self::Extension|set#field(self::Extension|method(#t130{self::Class}), #t131) in #t131;
-  let final self::Class #t135 = c{self::Class} in #t135.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t135), self::Extension|method(new self::Class::•()));
-  c = let final self::Class #t136 = c{self::Class} in #t136.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t137 = self::Extension|method(new self::Class::•()) in let final void #t138 = self::Extension|set#field(self::Extension|method(#t136), #t137) in #t137;
-  let final self::Class #t139 = c{self::Class} in #t139.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t140 = self::Extension|get#field(#t139) in #t140.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(#t140{self::Class}));
-  let final self::Class #t141 = c{self::Class} in #t141.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t142 = self::Extension|get#field(#t141) in #t142.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(#t142{self::Class}), new self::Class::•());
-  c = let final self::Class #t143 = c{self::Class} in #t143.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t144 = self::Extension|get#field(#t143) in #t144.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t145 = new self::Class::•() in let final void #t146 = self::Extension|set#field(self::Extension|method(#t144{self::Class}), #t145) in #t145;
-  let final self::Class #t147 = c{self::Class} in #t147.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t148 = self::Extension|get#field(#t147) in #t148.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(#t148{self::Class}));
-  let final self::Class #t149 = c{self::Class} in #t149.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t149, self::Extension|get#field(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t150 = c{self::Class} in #t150.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t151 = self::Extension|get#field(self::Extension|method(new self::Class::•())) in let final void #t152 = self::Extension|set#field(#t150, #t151) in #t151;
-  let final self::Class? #t153 = c in #t153.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t153{self::Class}, let final self::Class #t154 = new self::Class::•() in let final void #t155 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t154) in #t154);
-  c = let final self::Class? #t156 = c in #t156.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t157 = let final self::Class #t158 = new self::Class::•() in let final void #t159 = self::Extension|set#field(self::Extension|method(new self::Class::•()), #t158) in #t158 in let final void #t160 = self::Extension|set#field(#t156{self::Class}, #t157) in #t157;
-  let final self::Class #t161 = c{self::Class} in #t161.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(#t161, self::Extension|method(self::Extension|method(new self::Class::•())));
-  c = let final self::Class #t162 = c{self::Class} in #t162.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t163 = self::Extension|method(self::Extension|method(new self::Class::•())) in let final void #t164 = self::Extension|set#field(#t162, #t163) in #t163;
-  let final self::Class #t165 = c{self::Class} in #t165.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(self::Extension|method(self::Extension|method(#t165)));
-  let final self::Class #t166 = c{self::Class} in #t166.{core::Object::==}(null) ?{self::Class} null : self::Extension|set#field(self::Extension|method(self::Extension|method(#t166)), new self::Class::•());
-  let final self::Class #t167 = c{self::Class} in #t167.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(self::Extension|method(self::Extension|method(#t167)));
-  let final self::Class #t168 = c{self::Class} in #t168.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t169 = self::Extension|method(#t168) in #t169.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t169);
+static method propertyAccess(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t1 = n1 in #t1.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t1{self::Class1});
+  let final self::Class1? #t2 = n1 in #t2.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t2{self::Class1}, new self::Class1::•());
+  nullable1 = let final self::Class1? #t3 = n1 in #t3.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t4 = new self::Class1::•() in let final void #t5 = self::Extension1|set#nullable1(#t3{self::Class1}, #t4) in #t4;
+  let final self::Class1? #t6 = n1 in #t6.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t6{self::Class1});
+  let final self::Class1? #t7 = n1 in #t7.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t7{self::Class1}));
+  let final self::Class1? #t8 = n1 in #t8.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t9 = self::Extension1|get#nullable1(#t8{self::Class1}) in #t9.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t9{self::Class1});
+  let final self::Class1? #t10 = n1 in #t10.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t11 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t10{self::Class1})) in #t11.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t11{self::Class1});
+  let final self::Class1? #t12 = n1 in #t12.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t12{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t13 = n1 in #t13.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t14 = self::Extension1|get#nullable1(#t13{self::Class1}) in #t14.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t14{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t15 = n1 in #t15.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t16 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t15{self::Class1})) in #t16.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t16{self::Class1}, new self::Class1::•());
+  let final self::Class1? #t17 = let final self::Class1? #t18 = n1 in #t18.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t18{self::Class1}) in #t17.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t17{self::Class1});
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t19 = n1 in #t19.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t20 = new self::Class1::•() in let final void #t21 = self::Extension1|set#nullable1(#t19{self::Class1}, #t20) in #t20));
+  self::throws(() → self::Class1? => self::Extension1|get#nullable1(let final self::Class1? #t22 = n1 in #t22.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t22{self::Class1})));
+  nullable1 = let final self::Class1? #t23 = n1 in #t23.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t24 = new self::Class1::•() in let final void #t25 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t23{self::Class1}), #t24) in #t24;
+  nullable1 = let final self::Class1? #t26 = n1 in #t26.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t27 = self::Extension1|get#nullable1(#t26{self::Class1}) in #t27.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t28 = new self::Class1::•() in let final void #t29 = self::Extension1|set#nullable1(#t27{self::Class1}, #t28) in #t28;
+  nullable1 = let final self::Class1? #t30 = n1 in #t30.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t31 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t30{self::Class1})) in #t31.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t32 = new self::Class1::•() in let final void #t33 = self::Extension1|set#nullable1(#t31{self::Class1}, #t32) in #t32;
+  let final self::Class1? #t34 = n1 in #t34.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t35 = self::Extension1|get#nullable1(#t34{self::Class1}) in #t35.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t35{self::Class1});
+  let final self::Class1? #t36 = n1 in #t36.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t36{self::Class1}, self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t37 = n1 in #t37.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t38 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t39 = self::Extension1|set#nullable1(#t37{self::Class1}, #t38) in #t38;
+  let final self::Class1? #t40 = n1 in #t40.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t40{self::Class1}, let final self::Class1 #t41 = new self::Class1::•() in let final void #t42 = self::Extension1|set#nullable1(new self::Class1::•(), #t41) in #t41);
+  nullable1 = let final self::Class1? #t43 = n1 in #t43.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t44 = let final self::Class1 #t45 = new self::Class1::•() in let final void #t46 = self::Extension1|set#nullable1(new self::Class1::•(), #t45) in #t45 in let final void #t47 = self::Extension1|set#nullable1(#t43{self::Class1}, #t44) in #t44;
+  let final self::Class1? #t48 = n1 in #t48.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t48{self::Class1}, self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t49 = n1 in #t49.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t50 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t51 = self::Extension1|set#nullable1(#t49{self::Class1}, #t50) in #t50;
+  let final self::Class1? #t52 = n1 in #t52.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(#t52{self::Class1}));
+  let final self::Class1? #t53 = n1 in #t53.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t53{self::Class1}), new self::Class1::•());
+  let final self::Class1? #t54 = n1 in #t54.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t54{self::Class1}));
+  let final self::Class1? #t55 = n1 in #t55.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t55{self::Class1})));
+  let final self::Class1? #t56 = n1 in #t56.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t56{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t57 = n1 in #t57.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t58 = new self::Class1::•() in let final void #t59 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|get#nonNullable1(#t57{self::Class1})), #t58) in #t58;
+  let final self::Class1? #t60 = n1 in #t60.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t61 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(#t60{self::Class1})) in #t61.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t61{self::Class1});
+  let final self::Class1? #t62 = n1 in #t62.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t62{self::Class1}, self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t63 = n1 in #t63.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t64 = self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t65 = self::Extension1|set#nullable1(#t63{self::Class1}, #t64) in #t64;
+  let final self::Class1? #t66 = n1 in #t66.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t66{self::Class1}, let final self::Class1 #t67 = new self::Class1::•() in let final void #t68 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t67) in #t67);
+  nullable1 = let final self::Class1? #t69 = n1 in #t69.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t70 = let final self::Class1 #t71 = new self::Class1::•() in let final void #t72 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(new self::Class1::•()), #t71) in #t71 in let final void #t73 = self::Extension1|set#nullable1(#t69{self::Class1}, #t70) in #t70;
+  let final self::Class1? #t74 = n1 in #t74.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t74{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t75 = n1 in #t75.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t76 = self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(new self::Class1::•())) in let final void #t77 = self::Extension1|set#nullable1(#t75{self::Class1}, #t76) in #t76;
+  let final self::Class1? #t78 = n1 in #t78.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t78{self::Class1})));
+  let final self::Class1? #t79 = n1 in #t79.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t79{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t80 = n1 in #t80.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(self::Extension1|nonNullable1Method(#t80{self::Class1})));
+  let final self::Class1? #t81 = n1 in #t81.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t81{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t82 = n1 in #t82.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t83 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t84 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t82{self::Class1}), #t83) in #t83;
+  let final self::Class1? #t85 = n1 in #t85.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t85{self::Class1}), let final self::Class1 #t86 = new self::Class1::•() in let final void #t87 = self::Extension1|set#nullable1(new self::Class1::•(), #t86) in #t86);
+  nullable1 = let final self::Class1? #t88 = n1 in #t88.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t89 = let final self::Class1 #t90 = new self::Class1::•() in let final void #t91 = self::Extension1|set#nullable1(new self::Class1::•(), #t90) in #t90 in let final void #t92 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t88{self::Class1}), #t89) in #t89;
+  let final self::Class1? #t93 = n1 in #t93.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t93{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t94 = n1 in #t94.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t95 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t96 = self::Extension1|set#nullable1(self::Extension1|get#nonNullable1(#t94{self::Class1}), #t95) in #t95;
+  let final self::Class1? #t97 = n1 in #t97.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t97{self::Class1}, let final self::Class1? #t98 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t99 = self::Extension1|set#nullable1(new self::Class1::•(), #t98) in #t98);
+  nullable1 = let final self::Class1? #t100 = n1 in #t100.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t101 = let final self::Class1? #t102 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t103 = self::Extension1|set#nullable1(new self::Class1::•(), #t102) in #t102 in let final void #t104 = self::Extension1|set#nullable1(#t100{self::Class1}, #t101) in #t101;
+  let final self::Class1? #t105 = n1 in #t105.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t105{self::Class1}, let final self::Class1 #t106 = let final self::Class1 #t107 = new self::Class1::•() in let final void #t108 = self::Extension1|set#nullable1(new self::Class1::•(), #t107) in #t107 in let final void #t109 = self::Extension1|set#nullable1(new self::Class1::•(), #t106) in #t106);
+  nullable1 = let final self::Class1? #t110 = n1 in #t110.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t111 = let final self::Class1 #t112 = let final self::Class1 #t113 = new self::Class1::•() in let final void #t114 = self::Extension1|set#nullable1(new self::Class1::•(), #t113) in #t113 in let final void #t115 = self::Extension1|set#nullable1(new self::Class1::•(), #t112) in #t112 in let final void #t116 = self::Extension1|set#nullable1(#t110{self::Class1}, #t111) in #t111;
+  let final self::Class1? #t117 = n1 in #t117.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t117{self::Class1}, let final self::Class1 #t118 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t119 = self::Extension1|set#nullable1(new self::Class1::•(), #t118) in #t118);
+  nullable1 = let final self::Class1? #t120 = n1 in #t120.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t121 = let final self::Class1 #t122 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t123 = self::Extension1|set#nullable1(new self::Class1::•(), #t122) in #t122 in let final void #t124 = self::Extension1|set#nullable1(#t120{self::Class1}, #t121) in #t121;
+  let final self::Class1? #t125 = n1 in #t125.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t125{self::Class1}), self::Extension1|get#nullable1(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t126 = n1 in #t126.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t127 = self::Extension1|get#nullable1(new self::Class1::•()) in let final void #t128 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t126{self::Class1}), #t127) in #t127;
+  let final self::Class1? #t129 = n1 in #t129.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t129{self::Class1}), let final self::Class1 #t130 = new self::Class1::•() in let final void #t131 = self::Extension1|set#nullable1(new self::Class1::•(), #t130) in #t130);
+  nullable1 = let final self::Class1? #t132 = n1 in #t132.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t133 = let final self::Class1 #t134 = new self::Class1::•() in let final void #t135 = self::Extension1|set#nullable1(new self::Class1::•(), #t134) in #t134 in let final void #t136 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t132{self::Class1}), #t133) in #t133;
+  let final self::Class1? #t137 = n1 in #t137.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t137{self::Class1}), self::Extension1|nonNullable1Method(new self::Class1::•()));
+  nullable1 = let final self::Class1? #t138 = n1 in #t138.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t139 = self::Extension1|nonNullable1Method(new self::Class1::•()) in let final void #t140 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(#t138{self::Class1}), #t139) in #t139;
+  let final self::Class1? #t141 = n1 in #t141.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t141{self::Class1})));
+  let final self::Class1? #t142 = n1 in #t142.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t142{self::Class1})), new self::Class1::•());
+  nullable1 = let final self::Class1? #t143 = n1 in #t143.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t144 = new self::Class1::•() in let final void #t145 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t143{self::Class1})), #t144) in #t144;
+  let final self::Class1? #t146 = n1 in #t146.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|get#nonNullable1(#t146{self::Class1})));
+  let final self::Class1? #t147 = n1 in #t147.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t147{self::Class1}, self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t148 = n1 in #t148.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t149 = self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t150 = self::Extension1|set#nullable1(#t148{self::Class1}, #t149) in #t149;
+  let final self::Class1? #t151 = n1 in #t151.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t151{self::Class1}, let final self::Class1 #t152 = new self::Class1::•() in let final void #t153 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t152) in #t152);
+  nullable1 = let final self::Class1? #t154 = n1 in #t154.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t155 = let final self::Class1 #t156 = new self::Class1::•() in let final void #t157 = self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(new self::Class1::•()), #t156) in #t156 in let final void #t158 = self::Extension1|set#nullable1(#t154{self::Class1}, #t155) in #t155;
+  let final self::Class1? #t159 = n1 in #t159.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(#t159{self::Class1}, self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())));
+  nullable1 = let final self::Class1? #t160 = n1 in #t160.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t161 = self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(new self::Class1::•())) in let final void #t162 = self::Extension1|set#nullable1(#t160{self::Class1}, #t161) in #t161;
+  let final self::Class1? #t163 = n1 in #t163.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t163{self::Class1})));
+  let final self::Class1? #t164 = n1 in #t164.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|set#nullable1(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t164{self::Class1})), new self::Class1::•());
+  let final self::Class1? #t165 = n1 in #t165.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(self::Extension1|nonNullable1Method(#t165{self::Class1})));
+  let final self::Class1? #t166 = n1 in #t166.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t167 = self::Extension1|nonNullable1Method(#t166{self::Class1}) in #t167.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t167{self::Class1});
 }
-static method indexAccess(self::Class? c) → void {
-  let final self::Class? #t170 = c in #t170.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t170{self::Class}, c{self::Class});
-  let final self::Class? #t171 = c in #t171.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t171{self::Class}, c{self::Class}, new self::Class::•());
-  let final self::Class? #t172 = c in #t172.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t173 = self::Extension|[](#t172{self::Class}, c{self::Class}) in #t173.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t173{self::Class});
-  let final self::Class? #t174 = c in #t174.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|get#field(#t174{self::Class}), c{self::Class});
-  let final self::Class? #t175 = c in #t175.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|get#field(#t175{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t176 = c in #t176.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t177 = self::Extension|get#field(#t176{self::Class}) in let final self::Class #t178 = c{self::Class} in let final self::Class #t179 = new self::Class::•() in let final void #t180 = self::Extension|[]=(#t177, #t178, #t179) in #t179;
-  let final self::Class #t181 = c{self::Class} in #t181.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t182 = self::Extension|[](self::Extension|get#field(#t181), c{self::Class}) in #t182.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t182{self::Class});
-  let final self::Class #t183 = c{self::Class} in #t183.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t184 = self::Extension|get#field(#t183) in let final self::Class #t185 = c{self::Class} in self::Extension|[]=(#t184, #t185, self::Extension|+(self::Extension|[](#t184, #t185), 0));
-  c = let final self::Class #t186 = c{self::Class} in #t186.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t187 = self::Extension|get#field(#t186) in let final self::Class #t188 = c{self::Class} in let final self::Class? #t189 = self::Extension|+(self::Extension|[](#t187, #t188), 0) in let final void #t190 = self::Extension|[]=(#t187, #t188, #t189) in #t189;
-  let final self::Class? #t191 = c in #t191.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t192 = c{self::Class} in self::Extension|[](#t191{self::Class}, #t192).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t191{self::Class}, #t192, c{self::Class}) : null;
-  c = let final self::Class? #t193 = c in #t193.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t194 = c{self::Class} in let final self::Class? #t195 = self::Extension|[](#t193{self::Class}, #t194) in #t195.{core::Object::==}(null) ?{self::Class} let final self::Class #t196 = c{self::Class} in let final void #t197 = self::Extension|[]=(#t193{self::Class}, #t194, #t196) in #t196 : #t195{self::Class};
-  let final self::Class #t198 = c{self::Class} in #t198.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t199 = c{self::Class} in self::Extension|[]=(#t198, #t199, self::Extension|+(self::Extension|[](#t198, #t199), 0));
-  c = let final self::Class #t200 = c{self::Class} in #t200.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t201 = c{self::Class} in let final self::Class? #t202 = self::Extension|+(self::Extension|[](#t200, #t201), 0) in let final void #t203 = self::Extension|[]=(#t200, #t201, #t202) in #t202;
-  let final self::Class? #t204 = c in #t204.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t205 = c{self::Class} in self::Extension|[]=(#t204{self::Class}, #t205, self::Extension|+(self::Extension|[](#t204{self::Class}, #t205), 0));
-  c = let final self::Class? #t206 = c in #t206.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t207 = c{self::Class} in let final self::Class? #t208 = self::Extension|+(self::Extension|[](#t206{self::Class}, #t207), 0) in let final void #t209 = self::Extension|[]=(#t206{self::Class}, #t207, #t208) in #t208;
-  let final self::Class? #t210 = c in #t210.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t211 = c{self::Class} in self::Extension|[]=(#t210{self::Class}, #t211, self::Extension|+(self::Extension|[](#t210{self::Class}, #t211), 1));
-  c = let final self::Class? #t212 = c in #t212.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t213 = c{self::Class} in let final self::Class? #t214 = self::Extension|[](#t212{self::Class}, #t213) in let final void #t215 = self::Extension|[]=(#t212{self::Class}, #t213, self::Extension|+(#t214, 1)) in #t214;
-  let final self::Class? #t216 = c in #t216.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t217 = c{self::Class} in let final self::Class? #t218 = self::Extension|+(self::Extension|[](#t216{self::Class}, #t217), 1) in let final void #t219 = self::Extension|[]=(#t216{self::Class}, #t217, #t218) in #t218;
-  c = let final self::Class? #t220 = c in #t220.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t221 = c{self::Class} in let final self::Class? #t222 = self::Extension|+(self::Extension|[](#t220{self::Class}, #t221), 1) in let final void #t223 = self::Extension|[]=(#t220{self::Class}, #t221, #t222) in #t222;
-  let final self::Class? #t224 = c in #t224.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t225 = self::Extension|get#field(#t224{self::Class}) in let final self::Class #t226 = c{self::Class} in self::Extension|[]=(#t225, #t226, self::Extension|+(self::Extension|[](#t225, #t226), 1));
-  c = let final self::Class? #t227 = c in #t227.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t228 = self::Extension|get#field(#t227{self::Class}) in let final self::Class #t229 = c{self::Class} in let final self::Class? #t230 = self::Extension|[](#t228, #t229) in let final void #t231 = self::Extension|[]=(#t228, #t229, self::Extension|+(#t230, 1)) in #t230;
-  let final self::Class? #t232 = c in #t232.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t233 = self::Extension|get#field(#t232{self::Class}) in let final self::Class #t234 = c{self::Class} in let final self::Class? #t235 = self::Extension|+(self::Extension|[](#t233, #t234), 1) in let final void #t236 = self::Extension|[]=(#t233, #t234, #t235) in #t235;
-  c = let final self::Class? #t237 = c in #t237.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t238 = self::Extension|get#field(#t237{self::Class}) in let final self::Class #t239 = c{self::Class} in let final self::Class? #t240 = self::Extension|+(self::Extension|[](#t238, #t239), 1) in let final void #t241 = self::Extension|[]=(#t238, #t239, #t240) in #t240;
-  let final self::Class? #t242 = c in #t242.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](self::Extension|[](self::Extension|get#field(#t242{self::Class}), c{self::Class}), c{self::Class});
-  let final self::Class? #t243 = c in #t243.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(self::Extension|[](self::Extension|get#field(#t243{self::Class}), c{self::Class}), c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t244 = c in #t244.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t245 = self::Extension|[](self::Extension|get#field(#t244{self::Class}), c{self::Class}) in let final self::Class #t246 = c{self::Class} in let final self::Class #t247 = new self::Class::•() in let final void #t248 = self::Extension|[]=(#t245, #t246, #t247) in #t247;
-  let final self::Class #t249 = c{self::Class} in #t249.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t250 = self::Extension|[](self::Extension|[](self::Extension|get#field(#t249), c{self::Class}), c{self::Class}) in #t250.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t250{self::Class});
-  let final self::Class #t251 = c{self::Class} in #t251.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t252 = self::Extension|[](self::Extension|get#field(#t251), c{self::Class}) in let final self::Class #t253 = c{self::Class} in self::Extension|[]=(#t252, #t253, self::Extension|+(self::Extension|[](#t252, #t253), 0));
-  c = let final self::Class #t254 = c{self::Class} in #t254.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t255 = self::Extension|[](self::Extension|get#field(#t254), c{self::Class}) in let final self::Class #t256 = c{self::Class} in let final self::Class? #t257 = self::Extension|+(self::Extension|[](#t255, #t256), 0) in let final void #t258 = self::Extension|[]=(#t255, #t256, #t257) in #t257;
-  let final self::Class? #t259 = c in #t259.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t260 = self::Extension|[](self::Extension|get#field(#t259{self::Class}), c{self::Class}) in let final self::Class #t261 = c{self::Class} in self::Extension|[]=(#t260, #t261, self::Extension|+(self::Extension|[](#t260, #t261), 1));
-  c = let final self::Class? #t262 = c in #t262.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t263 = self::Extension|[](self::Extension|get#field(#t262{self::Class}), c{self::Class}) in let final self::Class #t264 = c{self::Class} in let final self::Class? #t265 = self::Extension|[](#t263, #t264) in let final void #t266 = self::Extension|[]=(#t263, #t264, self::Extension|+(#t265, 1)) in #t265;
-  let final self::Class? #t267 = c in #t267.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t268 = self::Extension|[](self::Extension|get#field(#t267{self::Class}), c{self::Class}) in let final self::Class #t269 = c{self::Class} in let final self::Class? #t270 = self::Extension|+(self::Extension|[](#t268, #t269), 1) in let final void #t271 = self::Extension|[]=(#t268, #t269, #t270) in #t270;
-  c = let final self::Class? #t272 = c in #t272.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t273 = self::Extension|[](self::Extension|get#field(#t272{self::Class}), c{self::Class}) in let final self::Class #t274 = c{self::Class} in let final self::Class? #t275 = self::Extension|+(self::Extension|[](#t273, #t274), 1) in let final void #t276 = self::Extension|[]=(#t273, #t274, #t275) in #t275;
-  let final self::Class? #t277 = c in #t277.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t278 = self::Extension|[](#t277{self::Class}, c{self::Class}) in #t278.{core::Object::==}(null) ?{self::Class?} null : self::Extension|[](#t278{self::Class}, c{self::Class});
-  let final self::Class? #t279 = c in #t279.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t280 = self::Extension|[](#t279{self::Class}, c{self::Class}) in #t280.{core::Object::==}(null) ?{self::Class} null : self::Extension|[]=(#t280{self::Class}, c{self::Class}, new self::Class::•());
-  c = let final self::Class? #t281 = c in #t281.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t282 = self::Extension|[](#t281{self::Class}, c{self::Class}) in #t282.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t283 = c{self::Class} in let final self::Class #t284 = new self::Class::•() in let final void #t285 = self::Extension|[]=(#t282{self::Class}, #t283, #t284) in #t284;
-  let final self::Class #t286 = c{self::Class} in #t286.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t287 = self::Extension|[](#t286, c{self::Class}) in #t287.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t288 = self::Extension|[](#t287{self::Class}, c{self::Class}) in #t288.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t288{self::Class});
-  c = let final self::Class #t289 = c{self::Class} in #t289.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t290 = self::Extension|[](#t289, c{self::Class}) in #t290.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t291 = self::Extension|[](#t290{self::Class}, c{self::Class}) in #t291.{core::Object::==}(null) ?{self::Class} null : self::Extension|method(#t291{self::Class});
-  let final self::Class #t292 = c{self::Class} in #t292.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t293 = self::Extension|[](#t292, c{self::Class}) in #t293.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t294 = c{self::Class} in self::Extension|[](#t293{self::Class}, #t294).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t293{self::Class}, #t294, c{self::Class}) : null;
-  c = let final self::Class #t295 = c{self::Class} in #t295.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t296 = self::Extension|[](#t295, c{self::Class}) in #t296.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t297 = c{self::Class} in let final self::Class? #t298 = self::Extension|[](#t296{self::Class}, #t297) in #t298.{core::Object::==}(null) ?{self::Class} let final self::Class #t299 = c{self::Class} in let final void #t300 = self::Extension|[]=(#t296{self::Class}, #t297, #t299) in #t299 : #t298{self::Class};
-  let final self::Class #t301 = c{self::Class} in #t301.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t302 = self::Extension|[](#t301, c{self::Class}) in #t302.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t303 = c{self::Class} in self::Extension|[]=(#t302{self::Class}, #t303, self::Extension|+(self::Extension|[](#t302{self::Class}, #t303), 0));
-  c = let final self::Class #t304 = c{self::Class} in #t304.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t305 = self::Extension|[](#t304, c{self::Class}) in #t305.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t306 = c{self::Class} in let final self::Class? #t307 = self::Extension|+(self::Extension|[](#t305{self::Class}, #t306), 0) in let final void #t308 = self::Extension|[]=(#t305{self::Class}, #t306, #t307) in #t307;
-  let final self::Class? #t309 = c in #t309.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t310 = self::Extension|[](#t309{self::Class}, c{self::Class}) in #t310.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t311 = c{self::Class} in self::Extension|[]=(#t310{self::Class}, #t311, self::Extension|+(self::Extension|[](#t310{self::Class}, #t311), 1));
-  c = let final self::Class? #t312 = c in #t312.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t313 = self::Extension|[](#t312{self::Class}, c{self::Class}) in #t313.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t314 = c{self::Class} in let final self::Class? #t315 = self::Extension|[](#t313{self::Class}, #t314) in let final void #t316 = self::Extension|[]=(#t313{self::Class}, #t314, self::Extension|+(#t315, 1)) in #t315;
-  let final self::Class? #t317 = c in #t317.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t318 = self::Extension|[](#t317{self::Class}, c{self::Class}) in #t318.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t319 = c{self::Class} in let final self::Class? #t320 = self::Extension|+(self::Extension|[](#t318{self::Class}, #t319), 1) in let final void #t321 = self::Extension|[]=(#t318{self::Class}, #t319, #t320) in #t320;
-  c = let final self::Class? #t322 = c in #t322.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t323 = self::Extension|[](#t322{self::Class}, c{self::Class}) in #t323.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t324 = c{self::Class} in let final self::Class? #t325 = self::Extension|+(self::Extension|[](#t323{self::Class}, #t324), 1) in let final void #t326 = self::Extension|[]=(#t323{self::Class}, #t324, #t325) in #t325;
+static method indexAccess(self::Class1? n1, self::Class2? n2, self::Class3? n3) → void {
+  self::Class1? nullable1 = n1;
+  self::Class2? nullable2 = n2;
+  self::Class3? nullable3 = n3;
+  let final self::Class1? #t168 = n1 in #t168.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t168{self::Class1}, nullable1);
+  let final self::Class1? #t169 = n1 in #t169.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t169{self::Class1}, nullable1, new self::Class1::•());
+  let final self::Class1? #t170 = n1 in #t170.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t171 = self::Extension1|[](#t170{self::Class1}, nullable1) in #t171.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t171{self::Class1});
+  let final self::Class1? #t172 = n1 in #t172.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](self::Extension1|get#nonNullable1(#t172{self::Class1}), nullable1);
+  let final self::Class1? #t173 = n1 in #t173.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(self::Extension1|get#nonNullable1(#t173{self::Class1}), nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t174 = n1 in #t174.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t175 = self::Extension1|get#nonNullable1(#t174{self::Class1}) in let final self::Class1? #t176 = nullable1 in let final self::Class1 #t177 = new self::Class1::•() in let final void #t178 = self::Extension1|[]=(#t175, #t176, #t177) in #t177;
+  let final self::Class1? #t179 = n1 in #t179.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t180 = self::Extension1|[](self::Extension1|get#nonNullable1(#t179{self::Class1}), nullable1) in #t180.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t180{self::Class1});
+  let final self::Class1? #t181 = n1 in #t181.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t182 = self::Extension1|get#nonNullable2(#t181{self::Class1}) in let final self::Class2? #t183 = nullable2 in self::Extension2|[]=(#t182, #t183, self::Extension2|+(self::Extension2|[](#t182, #t183), 0));
+  nullable2 = let final self::Class1? #t184 = n1 in #t184.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t185 = self::Extension1|get#nonNullable2(#t184{self::Class1}) in let final self::Class2? #t186 = nullable2 in let final self::Class2 #t187 = self::Extension2|+(self::Extension2|[](#t185, #t186), 0) in let final void #t188 = self::Extension2|[]=(#t185, #t186, #t187) in #t187;
+  let final self::Class1? #t189 = n1 in #t189.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t190 = nullable1 in self::Extension1|[](#t189{self::Class1}, #t190).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t189{self::Class1}, #t190, nullable1) : null;
+  nullable1 = let final self::Class1? #t191 = n1 in #t191.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t192 = nullable1 in let final self::Class1? #t193 = self::Extension1|[](#t191{self::Class1}, #t192) in #t193.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t194 = nullable1 in let final void #t195 = self::Extension1|[]=(#t191{self::Class1}, #t192, #t194) in #t194 : #t193{self::Class1};
+  let final self::Class2? #t196 = n2 in #t196.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t197 = nullable2 in self::Extension2|[]=(#t196{self::Class2}, #t197, self::Extension2|+(self::Extension2|[](#t196{self::Class2}, #t197), 0));
+  nullable2 = let final self::Class2? #t198 = n2 in #t198.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t199 = nullable2 in let final self::Class2 #t200 = self::Extension2|+(self::Extension2|[](#t198{self::Class2}, #t199), 0) in let final void #t201 = self::Extension2|[]=(#t198{self::Class2}, #t199, #t200) in #t200;
+  let final self::Class2? #t202 = n2 in #t202.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t203 = nullable2 in self::Extension2|[]=(#t202{self::Class2}, #t203, self::Extension2|+(self::Extension2|[](#t202{self::Class2}, #t203), 0));
+  nullable2 = let final self::Class2? #t204 = n2 in #t204.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t205 = nullable2 in let final self::Class2 #t206 = self::Extension2|+(self::Extension2|[](#t204{self::Class2}, #t205), 0) in let final void #t207 = self::Extension2|[]=(#t204{self::Class2}, #t205, #t206) in #t206;
+  let final self::Class2? #t208 = n2 in #t208.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t209 = nullable2 in self::Extension2|[]=(#t208{self::Class2}, #t209, self::Extension2|+(self::Extension2|[](#t208{self::Class2}, #t209), 1));
+  nullable2 = let final self::Class2? #t210 = n2 in #t210.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t211 = nullable2 in let final self::Class2 #t212 = self::Extension2|[](#t210{self::Class2}, #t211) in let final void #t213 = self::Extension2|[]=(#t210{self::Class2}, #t211, self::Extension2|+(#t212, 1)) in #t212;
+  let final self::Class2? #t214 = n2 in #t214.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t215 = nullable2 in let final self::Class2 #t216 = self::Extension2|+(self::Extension2|[](#t214{self::Class2}, #t215), 1) in let final void #t217 = self::Extension2|[]=(#t214{self::Class2}, #t215, #t216) in #t216;
+  nullable2 = let final self::Class2? #t218 = n2 in #t218.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t219 = nullable2 in let final self::Class2 #t220 = self::Extension2|+(self::Extension2|[](#t218{self::Class2}, #t219), 1) in let final void #t221 = self::Extension2|[]=(#t218{self::Class2}, #t219, #t220) in #t220;
+  let final self::Class1? #t222 = n1 in #t222.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t223 = self::Extension1|get#nonNullable2(#t222{self::Class1}) in let final self::Class2? #t224 = nullable2 in self::Extension2|[]=(#t223, #t224, self::Extension2|+(self::Extension2|[](#t223, #t224), 1));
+  nullable2 = let final self::Class1? #t225 = n1 in #t225.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t226 = self::Extension1|get#nonNullable2(#t225{self::Class1}) in let final self::Class2? #t227 = nullable2 in let final self::Class2 #t228 = self::Extension2|[](#t226, #t227) in let final void #t229 = self::Extension2|[]=(#t226, #t227, self::Extension2|+(#t228, 1)) in #t228;
+  let final self::Class1? #t230 = n1 in #t230.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t231 = self::Extension1|get#nonNullable2(#t230{self::Class1}) in let final self::Class2? #t232 = nullable2 in let final self::Class2 #t233 = self::Extension2|+(self::Extension2|[](#t231, #t232), 1) in let final void #t234 = self::Extension2|[]=(#t231, #t232, #t233) in #t233;
+  nullable2 = let final self::Class1? #t235 = n1 in #t235.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t236 = self::Extension1|get#nonNullable2(#t235{self::Class1}) in let final self::Class2? #t237 = nullable2 in let final self::Class2 #t238 = self::Extension2|+(self::Extension2|[](#t236, #t237), 1) in let final void #t239 = self::Extension2|[]=(#t236, #t237, #t238) in #t238;
+  let final self::Class1? #t240 = n1 in #t240.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t240{self::Class1}), nullable2), nullable2);
+  let final self::Class1? #t241 = n1 in #t241.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|[]=(self::Extension2|[](self::Extension1|get#nonNullable2(#t241{self::Class1}), nullable2), nullable2, new self::Class2::•());
+  nullable2 = let final self::Class1? #t242 = n1 in #t242.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t243 = self::Extension2|[](self::Extension1|get#nonNullable2(#t242{self::Class1}), nullable2) in let final self::Class2? #t244 = nullable2 in let final self::Class2 #t245 = new self::Class2::•() in let final void #t246 = self::Extension2|[]=(#t243, #t244, #t245) in #t245;
+  let final self::Class1? #t247 = n1 in #t247.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t248 = self::Extension2|[](self::Extension2|[](self::Extension1|get#nonNullable2(#t247{self::Class1}), nullable2), nullable2) in #t248.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|nonNullable2Method(#t248{self::Class2});
+  let final self::Class1? #t249 = n1 in #t249.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t250 = self::Extension2|[](self::Extension1|get#nonNullable2(#t249{self::Class1}), nullable2) in let final self::Class2? #t251 = nullable2 in self::Extension2|[]=(#t250, #t251, self::Extension2|+(self::Extension2|[](#t250, #t251), 0));
+  nullable2 = let final self::Class1? #t252 = n1 in #t252.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t253 = self::Extension2|[](self::Extension1|get#nonNullable2(#t252{self::Class1}), nullable2) in let final self::Class2? #t254 = nullable2 in let final self::Class2 #t255 = self::Extension2|+(self::Extension2|[](#t253, #t254), 0) in let final void #t256 = self::Extension2|[]=(#t253, #t254, #t255) in #t255;
+  let final self::Class1? #t257 = n1 in #t257.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t258 = self::Extension2|[](self::Extension1|get#nonNullable2(#t257{self::Class1}), nullable2) in let final self::Class2? #t259 = nullable2 in self::Extension2|[]=(#t258, #t259, self::Extension2|+(self::Extension2|[](#t258, #t259), 1));
+  nullable2 = let final self::Class1? #t260 = n1 in #t260.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t261 = self::Extension2|[](self::Extension1|get#nonNullable2(#t260{self::Class1}), nullable2) in let final self::Class2? #t262 = nullable2 in let final self::Class2 #t263 = self::Extension2|[](#t261, #t262) in let final void #t264 = self::Extension2|[]=(#t261, #t262, self::Extension2|+(#t263, 1)) in #t263;
+  let final self::Class1? #t265 = n1 in #t265.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t266 = self::Extension2|[](self::Extension1|get#nonNullable2(#t265{self::Class1}), nullable2) in let final self::Class2? #t267 = nullable2 in let final self::Class2 #t268 = self::Extension2|+(self::Extension2|[](#t266, #t267), 1) in let final void #t269 = self::Extension2|[]=(#t266, #t267, #t268) in #t268;
+  nullable2 = let final self::Class1? #t270 = n1 in #t270.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t271 = self::Extension2|[](self::Extension1|get#nonNullable2(#t270{self::Class1}), nullable2) in let final self::Class2? #t272 = nullable2 in let final self::Class2 #t273 = self::Extension2|+(self::Extension2|[](#t271, #t272), 1) in let final void #t274 = self::Extension2|[]=(#t271, #t272, #t273) in #t273;
+  let final self::Class1? #t275 = n1 in #t275.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t276 = self::Extension1|[](#t275{self::Class1}, nullable1) in #t276.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[](#t276{self::Class1}, nullable1);
+  let final self::Class1? #t277 = n1 in #t277.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t278 = self::Extension1|[](#t277{self::Class1}, nullable1) in #t278.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|[]=(#t278{self::Class1}, nullable1, new self::Class1::•());
+  nullable1 = let final self::Class1? #t279 = n1 in #t279.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t280 = self::Extension1|[](#t279{self::Class1}, nullable1) in #t280.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t281 = nullable1 in let final self::Class1 #t282 = new self::Class1::•() in let final void #t283 = self::Extension1|[]=(#t280{self::Class1}, #t281, #t282) in #t282;
+  let final self::Class1? #t284 = n1 in #t284.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t285 = self::Extension1|[](#t284{self::Class1}, nullable1) in #t285.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t286 = self::Extension1|[](#t285{self::Class1}, nullable1) in #t286.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t286{self::Class1});
+  nullable1 = let final self::Class1? #t287 = n1 in #t287.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t288 = self::Extension1|[](#t287{self::Class1}, nullable1) in #t288.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t289 = self::Extension1|[](#t288{self::Class1}, nullable1) in #t289.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|nonNullable1Method(#t289{self::Class1});
+  let final self::Class1? #t290 = n1 in #t290.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t291 = self::Extension1|[](#t290{self::Class1}, nullable1) in #t291.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t292 = nullable1 in self::Extension1|[](#t291{self::Class1}, #t292).{core::Object::==}(null) ?{self::Class1?} self::Extension1|[]=(#t291{self::Class1}, #t292, nullable1) : null;
+  nullable1 = let final self::Class1? #t293 = n1 in #t293.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t294 = self::Extension1|[](#t293{self::Class1}, nullable1) in #t294.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t295 = nullable1 in let final self::Class1? #t296 = self::Extension1|[](#t294{self::Class1}, #t295) in #t296.{core::Object::==}(null) ?{self::Class1?} let final self::Class1? #t297 = nullable1 in let final void #t298 = self::Extension1|[]=(#t294{self::Class1}, #t295, #t297) in #t297 : #t296{self::Class1};
+  let final self::Class3? #t299 = n3 in #t299.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t300 = self::Extension3|[](#t299{self::Class3}, nullable3) in #t300.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t301 = nullable2 in self::Extension2|[]=(#t300{self::Class2}, #t301, self::Extension2|+(self::Extension2|[](#t300{self::Class2}, #t301), 0));
+  nullable2 = let final self::Class3? #t302 = n3 in #t302.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t303 = self::Extension3|[](#t302{self::Class3}, nullable3) in #t303.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t304 = nullable2 in let final self::Class2 #t305 = self::Extension2|+(self::Extension2|[](#t303{self::Class2}, #t304), 0) in let final void #t306 = self::Extension2|[]=(#t303{self::Class2}, #t304, #t305) in #t305;
+  let final self::Class3? #t307 = n3 in #t307.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t308 = self::Extension3|[](#t307{self::Class3}, nullable3) in #t308.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t309 = nullable2 in self::Extension2|[]=(#t308{self::Class2}, #t309, self::Extension2|+(self::Extension2|[](#t308{self::Class2}, #t309), 1));
+  nullable2 = let final self::Class3? #t310 = n3 in #t310.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t311 = self::Extension3|[](#t310{self::Class3}, nullable3) in #t311.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t312 = nullable2 in let final self::Class2 #t313 = self::Extension2|[](#t311{self::Class2}, #t312) in let final void #t314 = self::Extension2|[]=(#t311{self::Class2}, #t312, self::Extension2|+(#t313, 1)) in #t313;
+  let final self::Class3? #t315 = n3 in #t315.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t316 = self::Extension3|[](#t315{self::Class3}, nullable3) in #t316.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t317 = nullable2 in let final self::Class2 #t318 = self::Extension2|+(self::Extension2|[](#t316{self::Class2}, #t317), 1) in let final void #t319 = self::Extension2|[]=(#t316{self::Class2}, #t317, #t318) in #t318;
+  nullable2 = let final self::Class3? #t320 = n3 in #t320.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t321 = self::Extension3|[](#t320{self::Class3}, nullable3) in #t321.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2? #t322 = nullable2 in let final self::Class2 #t323 = self::Extension2|+(self::Extension2|[](#t321{self::Class2}, #t322), 1) in let final void #t324 = self::Extension2|[]=(#t321{self::Class2}, #t322, #t323) in #t323;
 }
-static method operatorAccess(self::Class? c) → void {
-  self::throws(() → self::Class? => self::Extension|+(let final self::Class? #t327 = c in #t327.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t327{self::Class}), 0));
-  self::throws(() → self::Class? => self::Extension|unary-(let final self::Class? #t328 = c in #t328.{core::Object::==}(null) ?{self::Class?} null : self::Extension|get#field(#t328{self::Class})));
-  let final self::Class? #t329 = c in #t329.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t329, self::Extension|+(self::Extension|get#field(#t329), 0));
-  c = let final self::Class? #t330 = c in #t330.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t331 = self::Extension|+(self::Extension|get#field(#t330), 0) in let final void #t332 = self::Extension|set#field(#t330, #t331) in #t331;
-  let final self::Class? #t333 = c in #t333.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t334 = self::Extension|get#property(#t333{self::Class}) in self::Extension|set#field(#t334, self::Extension|+(self::Extension|get#field(#t334), 0));
-  c = let final self::Class? #t335 = c in #t335.{core::Object::==}(null) ?{self::Class?} null : let final self::Class #t336 = self::Extension|get#property(#t335{self::Class}) in let final self::Class? #t337 = self::Extension|+(self::Extension|get#field(#t336), 0) in let final void #t338 = self::Extension|set#field(#t336, #t337) in #t337;
-  let final self::Class? #t339 = c in #t339.{core::Object::==}(null) ?{self::Class?} null : self::Extension|set#field(#t339, self::Extension|+(self::Extension|get#field(#t339), 1));
-  c = let final self::Class? #t340 = c in #t340.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t341 = self::Extension|get#field(#t340) in let final void #t342 = self::Extension|set#field(#t340, self::Extension|+(#t341, 1)) in #t341;
-  let final self::Class? #t343 = c in #t343.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t344 = self::Extension|+(self::Extension|get#field(#t343), 1) in let final void #t345 = self::Extension|set#field(#t343, #t344) in #t344;
-  c = let final self::Class? #t346 = c in #t346.{core::Object::==}(null) ?{self::Class?} null : let final self::Class? #t347 = self::Extension|+(self::Extension|get#field(#t346), 1) in let final void #t348 = self::Extension|set#field(#t346, #t347) in #t347;
+static method operatorAccess(self::Class1? n1, self::Class2? n2) → void {
+  self::Class2? nullable2 = n2;
+  self::throws(() → self::Class1? => self::Extension1|+(let final self::Class1? #t325 = n1 in #t325.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t325{self::Class1}), 0));
+  self::throws(() → self::Class1? => self::Extension1|unary-(let final self::Class1? #t326 = n1 in #t326.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nonNullable1(#t326{self::Class1})));
+  let final self::Class2? #t327 = n2 in #t327.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t327, self::Extension2|+(self::Extension2|get#nonNullable2(#t327), 0));
+  nullable2 = let final self::Class2? #t328 = n2 in #t328.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t329 = self::Extension2|+(self::Extension2|get#nonNullable2(#t328), 0) in let final void #t330 = self::Extension2|set#nonNullable2(#t328, #t329) in #t329;
+  let final self::Class2? #t331 = n2 in #t331.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t332 = self::Extension2|get#nonNullable2(#t331{self::Class2}) in self::Extension2|set#nonNullable2(#t332, self::Extension2|+(self::Extension2|get#nonNullable2(#t332), 0));
+  nullable2 = let final self::Class2? #t333 = n2 in #t333.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t334 = self::Extension2|get#nonNullable2(#t333{self::Class2}) in let final self::Class2 #t335 = self::Extension2|+(self::Extension2|get#nonNullable2(#t334), 0) in let final void #t336 = self::Extension2|set#nonNullable2(#t334, #t335) in #t335;
+  let final self::Class2? #t337 = n2 in #t337.{core::Object::==}(null) ?{self::Class2?} null : self::Extension2|set#nonNullable2(#t337, self::Extension2|+(self::Extension2|get#nonNullable2(#t337), 1));
+  nullable2 = let final self::Class2? #t338 = n2 in #t338.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t339 = self::Extension2|get#nonNullable2(#t338) in let final void #t340 = self::Extension2|set#nonNullable2(#t338, self::Extension2|+(#t339, 1)) in #t339;
+  let final self::Class2? #t341 = n2 in #t341.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t342 = self::Extension2|+(self::Extension2|get#nonNullable2(#t341), 1) in let final void #t343 = self::Extension2|set#nonNullable2(#t341, #t342) in #t342;
+  nullable2 = let final self::Class2? #t344 = n2 in #t344.{core::Object::==}(null) ?{self::Class2?} null : let final self::Class2 #t345 = self::Extension2|+(self::Extension2|get#nonNullable2(#t344), 1) in let final void #t346 = self::Extension2|set#nonNullable2(#t344, #t345) in #t345;
 }
-static method ifNull(self::Class? c) → void {
-  let final self::Class? #t349 = c in #t349.{core::Object::==}(null) ?{self::Class} null : self::Extension|get#field(#t349).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t349, c{self::Class}) : null;
-  c = let final self::Class? #t350 = c in #t350.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t351 = self::Extension|get#field(#t350) in #t351.{core::Object::==}(null) ?{self::Class} let final self::Class #t352 = c{self::Class} in let final void #t353 = self::Extension|set#field(#t350, #t352) in #t352 : #t351{self::Class};
-  let final self::Class #t354 = c{self::Class} in #t354.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t355 = self::Extension|get#property(#t354) in self::Extension|get#field(#t355).{core::Object::==}(null) ?{self::Class} self::Extension|set#field(#t355, c{self::Class}) : null;
-  c = let final self::Class #t356 = c{self::Class} in #t356.{core::Object::==}(null) ?{self::Class} null : let final self::Class #t357 = self::Extension|get#property(#t356) in let final self::Class? #t358 = self::Extension|get#field(#t357) in #t358.{core::Object::==}(null) ?{self::Class} let final self::Class #t359 = c{self::Class} in let final void #t360 = self::Extension|set#field(#t357, #t359) in #t359 : #t358{self::Class};
-  let final self::Class #t361 = c{self::Class} in #t361.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t362 = self::Extension|get#field(#t361) in let final self::Class #t363 = c{self::Class} in self::Extension|[](#t362, #t363).{core::Object::==}(null) ?{self::Class} self::Extension|[]=(#t362, #t363, c{self::Class}) : null;
-  c = let final self::Class #t364 = c{self::Class} in #t364.{core::Object::==}(null) ?{self::Class} null : let final self::Class? #t365 = self::Extension|get#field(#t364) in let final self::Class #t366 = c{self::Class} in let final self::Class? #t367 = self::Extension|[](#t365, #t366) in #t367.{core::Object::==}(null) ?{self::Class} let final self::Class #t368 = c{self::Class} in let final void #t369 = self::Extension|[]=(#t365, #t366, #t368) in #t368 : #t367{self::Class};
+static method ifNull(self::Class1? n1) → void {
+  self::Class1? nullable1 = n1;
+  let final self::Class1? #t347 = n1 in #t347.{core::Object::==}(null) ?{self::Class1?} null : self::Extension1|get#nullable1(#t347).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t347, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t348 = n1 in #t348.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t349 = self::Extension1|get#nullable1(#t348) in #t349.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t350 = n1{self::Class1} in let final void #t351 = self::Extension1|set#nullable1(#t348, #t350) in #t350 : #t349{self::Class1};
+  let final self::Class1? #t352 = n1 in #t352.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t353 = self::Extension1|get#nonNullable1(#t352{self::Class1}) in self::Extension1|get#nullable1(#t353{self::Class1}).{core::Object::==}(null) ?{self::Class1} self::Extension1|set#nullable1(#t353{self::Class1}, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t354 = n1 in #t354.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1? #t355 = self::Extension1|get#nonNullable1(#t354{self::Class1}) in let final self::Class1? #t356 = self::Extension1|get#nullable1(#t355{self::Class1}) in #t356.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t357 = n1{self::Class1} in let final void #t358 = self::Extension1|set#nullable1(#t355{self::Class1}, #t357) in #t357 : #t356{self::Class1};
+  let final self::Class1? #t359 = n1 in #t359.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t360 = self::Extension1|get#nonNullable1(#t359{self::Class1}) in let final self::Class1 #t361 = n1{self::Class1} in self::Extension1|[](#t360, #t361).{core::Object::==}(null) ?{self::Class1} self::Extension1|[]=(#t360, #t361, n1{self::Class1}) : null;
+  n1 = let final self::Class1? #t362 = n1 in #t362.{core::Object::==}(null) ?{self::Class1?} null : let final self::Class1 #t363 = self::Extension1|get#nonNullable1(#t362{self::Class1}) in let final self::Class1 #t364 = n1{self::Class1} in let final self::Class1? #t365 = self::Extension1|[](#t363, #t364) in #t365.{core::Object::==}(null) ?{self::Class1} let final self::Class1 #t366 = n1{self::Class1} in let final void #t367 = self::Extension1|[]=(#t363, #t364, #t366) in #t366 : #t365{self::Class1};
 }
 static method throws(() → void f) → void {
   try {
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart b/pkg/front_end/testcases/nnbd/null_shorting_index.dart
index a5804b5..13812c5 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart
@@ -72,13 +72,13 @@
 
   Extension(c1?.field)?.[0];
   Extension(c1?.field)?.[0] = 1;
-  Extension(c1?.field)?.[0] = 1 + Extension(c2)?.[0];
+  Extension(c1?.field)?.[0] = 1 + Extension(c2)?.[0]!;
   Extension(c1?.field)?.[0] += 1;
-  Extension(c1?.field)?.[0] += 1 + Extension(c2)?.[0];
+  Extension(c1?.field)?.[0] += 1 + Extension(c2)?.[0]!;
   // TODO(johnniwinther): ++ should probably not be null-shorted, awaiting spec
   //  update.
   ++Extension(c1?.field)?.[0];
   Extension(c1?.field)?.[0]++;
   Extension(c1?.field)?.[0] ??= 1;
-  Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1];
+  Extension(c1?.field)?.[0] ??= 1 + Extension(c2)?.[1]!;
 }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
index 2f1374e..d147132 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect
@@ -29,50 +29,50 @@
 }
 static method main() → dynamic {
   self::Class1? c1;
-  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int} null : #t1{self::Class1}.{self::Class1::[]}(0);
-  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
-  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
-  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
-  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
-  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
-  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class1}.{self::Class1::[]}(0);
+  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
+  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
+  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int?} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int?} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
+  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int?} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
+  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int?} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
+  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int?} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
   self::Class2? c2;
-  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t18{self::Class2}, 0);
-  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
-  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
-  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
-  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
-  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
-  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t35{self::Class2}, 0);
+  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t18{self::Class2}, 0);
+  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
+  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
+  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int?} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
+  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int?} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int?} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
+  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int?} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
+  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int?} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
+  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int?} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t35{self::Class2}, 0);
   let final self::Class2? #t36 = c2 in #t36.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t36{self::Class2}, 0, 1);
   let final self::Class2? #t37 = c2 in #t37.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t37{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
-  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
-  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
-  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
-  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t53{self::Class2}, 0);
-  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
-  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
-  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
-  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
-  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
-  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
-  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t79{self::Class2}, 0);
+  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int?} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
+  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int?} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int?} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
+  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int?} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
+  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int?} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
+  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int?} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t53{self::Class2}, 0);
+  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
+  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int?} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
+  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int?} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int?} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
+  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int?} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
+  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int?} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
+  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int?} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t79{self::Class2}, 0);
   let final self::Class1? #t80 = c1 in #t80.{core::Object::==}(null) ?{void} null : let final self::Class2? #t81 = #t80{self::Class1}.{self::Class1::field} in #t81.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t81{self::Class2}, 0, 1);
-  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t84{self::Class2}, 0)));
-  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
-  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}(let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t91{self::Class2}, 0))));
-  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
-  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
-  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
-  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}(let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t106{self::Class2}, 1))) : null;
+  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}((let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t84{self::Class2}, 0))!));
+  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int?} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
+  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int?} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}((let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t91{self::Class2}, 0))!)));
+  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int?} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
+  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int?} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
+  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int?} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
+  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int?} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}((let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t106{self::Class2}, 1))!)) : null;
 }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
index 2f1374e..d147132 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect
@@ -29,50 +29,50 @@
 }
 static method main() → dynamic {
   self::Class1? c1;
-  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int} null : #t1{self::Class1}.{self::Class1::[]}(0);
-  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
-  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
-  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
-  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
-  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
-  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class1}.{self::Class1::[]}(0);
+  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
+  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
+  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int?} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int?} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
+  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int?} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
+  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int?} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
+  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int?} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
   self::Class2? c2;
-  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t18{self::Class2}, 0);
-  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
-  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
-  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
-  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
-  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
-  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t35{self::Class2}, 0);
+  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t18{self::Class2}, 0);
+  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
+  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
+  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int?} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
+  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int?} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int?} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
+  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int?} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
+  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int?} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
+  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int?} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t35{self::Class2}, 0);
   let final self::Class2? #t36 = c2 in #t36.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t36{self::Class2}, 0, 1);
   let final self::Class2? #t37 = c2 in #t37.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t37{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
-  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
-  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
-  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
-  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t53{self::Class2}, 0);
-  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
-  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
-  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
-  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
-  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
-  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
-  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t79{self::Class2}, 0);
+  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int?} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
+  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int?} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int?} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
+  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int?} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
+  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int?} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
+  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int?} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t53{self::Class2}, 0);
+  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
+  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int?} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
+  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int?} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int?} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
+  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int?} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
+  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int?} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
+  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int?} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t79{self::Class2}, 0);
   let final self::Class1? #t80 = c1 in #t80.{core::Object::==}(null) ?{void} null : let final self::Class2? #t81 = #t80{self::Class1}.{self::Class1::field} in #t81.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t81{self::Class2}, 0, 1);
-  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t84{self::Class2}, 0)));
-  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
-  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}(let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t91{self::Class2}, 0))));
-  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
-  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
-  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
-  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}(let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t106{self::Class2}, 1))) : null;
+  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}((let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t84{self::Class2}, 0))!));
+  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int?} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
+  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int?} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}((let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t91{self::Class2}, 0))!)));
+  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int?} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
+  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int?} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
+  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int?} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
+  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int?} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}((let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t106{self::Class2}, 1))!)) : null;
 }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
index 2f1374e..d147132 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.expect
@@ -29,50 +29,50 @@
 }
 static method main() → dynamic {
   self::Class1? c1;
-  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int} null : #t1{self::Class1}.{self::Class1::[]}(0);
-  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
-  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
-  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
-  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
-  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
-  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class1}.{self::Class1::[]}(0);
+  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
+  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
+  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int?} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int?} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
+  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int?} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
+  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int?} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
+  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int?} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
   self::Class2? c2;
-  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t18{self::Class2}, 0);
-  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
-  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
-  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
-  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
-  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
-  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t35{self::Class2}, 0);
+  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t18{self::Class2}, 0);
+  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
+  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
+  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int?} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
+  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int?} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int?} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
+  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int?} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
+  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int?} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
+  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int?} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t35{self::Class2}, 0);
   let final self::Class2? #t36 = c2 in #t36.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t36{self::Class2}, 0, 1);
   let final self::Class2? #t37 = c2 in #t37.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t37{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
-  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
-  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
-  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
-  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t53{self::Class2}, 0);
-  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
-  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
-  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
-  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
-  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
-  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
-  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t79{self::Class2}, 0);
+  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int?} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
+  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int?} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int?} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
+  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int?} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
+  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int?} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
+  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int?} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t53{self::Class2}, 0);
+  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
+  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int?} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
+  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int?} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int?} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
+  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int?} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
+  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int?} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
+  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int?} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t79{self::Class2}, 0);
   let final self::Class1? #t80 = c1 in #t80.{core::Object::==}(null) ?{void} null : let final self::Class2? #t81 = #t80{self::Class1}.{self::Class1::field} in #t81.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t81{self::Class2}, 0, 1);
-  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t84{self::Class2}, 0)));
-  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
-  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}(let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t91{self::Class2}, 0))));
-  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
-  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
-  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
-  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}(let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t106{self::Class2}, 1))) : null;
+  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}((let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t84{self::Class2}, 0))!));
+  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int?} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
+  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int?} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}((let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t91{self::Class2}, 0))!)));
+  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int?} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
+  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int?} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
+  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int?} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
+  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int?} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}((let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t106{self::Class2}, 1))!)) : null;
 }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
index 2f1374e..d147132 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.weak.transformed.expect
@@ -29,50 +29,50 @@
 }
 static method main() → dynamic {
   self::Class1? c1;
-  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int} null : #t1{self::Class1}.{self::Class1::[]}(0);
-  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
-  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
-  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
-  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
-  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
-  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class1}.{self::Class1::[]}(0);
+  let final self::Class1? #t2 = c1 in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class1}.{self::Class1::[]=}(0, 1);
+  let final self::Class1? #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class1}.{self::Class1::[]=}(0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t4 = c1 in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = 0 in #t4{self::Class1}.{self::Class1::[]=}(#t5, #t4{self::Class1}.{self::Class1::[]}(#t5).{core::num::+}(1));
+  let final self::Class1? #t6 = c1 in #t6.{core::Object::==}(null) ?{core::int?} null : let final core::int #t7 = 0 in #t6{self::Class1}.{self::Class1::[]=}(#t7, #t6{self::Class1}.{self::Class1::[]}(#t7).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t8 = c1 in #t8.{core::Object::==}(null) ?{core::int?} null : let final core::int #t9 = 0 in let final core::int #t10 = #t8{self::Class1}.{self::Class1::[]}(#t9).{core::num::+}(1) in let final void #t11 = #t8{self::Class1}.{self::Class1::[]=}(#t9, #t10) in #t10;
+  let final self::Class1? #t12 = c1 in #t12.{core::Object::==}(null) ?{core::int?} null : let final core::int #t13 = 0 in #t12{self::Class1}.{self::Class1::[]=}(#t13, #t12{self::Class1}.{self::Class1::[]}(#t13).{core::num::+}(1));
+  let final self::Class1? #t14 = c1 in #t14.{core::Object::==}(null) ?{core::int?} null : let final core::int #t15 = 0 in #t14{self::Class1}.{self::Class1::[]}(#t15).{core::num::==}(null) ?{core::int} #t14{self::Class1}.{self::Class1::[]=}(#t15, 1) : null;
+  let final self::Class1? #t16 = c1 in #t16.{core::Object::==}(null) ?{core::int?} null : let final core::int #t17 = 0 in #t16{self::Class1}.{self::Class1::[]}(#t17).{core::num::==}(null) ?{core::int} #t16{self::Class1}.{self::Class1::[]=}(#t17, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
   self::Class2? c2;
-  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t18{self::Class2}, 0);
-  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
-  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
-  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
-  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
-  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
-  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t35{self::Class2}, 0);
+  let final self::Class2? #t18 = c2 in #t18.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t18{self::Class2}, 0);
+  let final self::Class2? #t19 = c2 in #t19.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t19{self::Class2}, 0, 1);
+  let final self::Class2? #t20 = c2 in #t20.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t20{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
+  let final self::Class2? #t21 = c2 in #t21.{core::Object::==}(null) ?{core::int?} null : let final core::int #t22 = 0 in self::Extension|[]=(#t21{self::Class2}, #t22, self::Extension|[](#t21{self::Class2}, #t22).{core::num::+}(1));
+  let final self::Class2? #t23 = c2 in #t23.{core::Object::==}(null) ?{core::int?} null : let final core::int #t24 = 0 in self::Extension|[]=(#t23{self::Class2}, #t24, self::Extension|[](#t23{self::Class2}, #t24).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t25 = c2 in #t25.{core::Object::==}(null) ?{core::int?} null : let final core::int #t26 = 0 in let final core::int #t27 = self::Extension|[](#t25{self::Class2}, #t26).{core::num::+}(1) in let final void #t28 = self::Extension|[]=(#t25{self::Class2}, #t26, #t27) in #t27;
+  let final self::Class2? #t29 = c2 in #t29.{core::Object::==}(null) ?{core::int?} null : let final core::int #t30 = 0 in self::Extension|[]=(#t29{self::Class2}, #t30, self::Extension|[](#t29{self::Class2}, #t30).{core::num::+}(1));
+  let final self::Class2? #t31 = c2 in #t31.{core::Object::==}(null) ?{core::int?} null : let final core::int #t32 = 0 in self::Extension|[](#t31{self::Class2}, #t32).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t31{self::Class2}, #t32, 1) : null;
+  let final self::Class2? #t33 = c2 in #t33.{core::Object::==}(null) ?{core::int?} null : let final core::int #t34 = 0 in self::Extension|[](#t33{self::Class2}, #t34).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t33{self::Class2}, #t34, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class2? #t35 = c2 in #t35.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t35{self::Class2}, 0);
   let final self::Class2? #t36 = c2 in #t36.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t36{self::Class2}, 0, 1);
   let final self::Class2? #t37 = c2 in #t37.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t37{self::Class2}, 0, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0)));
-  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
-  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
-  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
-  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
-  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
-  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
-  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t53{self::Class2}, 0);
-  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
-  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
-  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
-  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
-  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
-  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
-  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
-  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
-  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t79{self::Class2}, 0);
+  let final self::Class2? #t38 = c2 in #t38.{core::Object::==}(null) ?{core::int?} null : let final core::int #t39 = 0 in self::Extension|[]=(#t38{self::Class2}, #t39, self::Extension|[](#t38{self::Class2}, #t39).{core::num::+}(1));
+  let final self::Class2? #t40 = c2 in #t40.{core::Object::==}(null) ?{core::int?} null : let final core::int #t41 = 0 in self::Extension|[]=(#t40{self::Class2}, #t41, self::Extension|[](#t40{self::Class2}, #t41).{core::num::+}(1.{core::num::+}(self::Extension|[](c2{self::Class2}, 0))));
+  let final self::Class2? #t42 = c2 in #t42.{core::Object::==}(null) ?{core::int?} null : let final core::int #t43 = 0 in let final core::int #t44 = self::Extension|[](#t42{self::Class2}, #t43).{core::num::+}(1) in let final void #t45 = self::Extension|[]=(#t42{self::Class2}, #t43, #t44) in #t44;
+  let final self::Class2? #t46 = c2 in #t46.{core::Object::==}(null) ?{core::int?} null : let final core::int #t47 = 0 in self::Extension|[]=(#t46{self::Class2}, #t47, self::Extension|[](#t46{self::Class2}, #t47).{core::num::+}(1));
+  let final self::Class2? #t48 = c2 in #t48.{core::Object::==}(null) ?{core::int?} null : let final core::int #t49 = 0 in self::Extension|[](#t48{self::Class2}, #t49).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t48{self::Class2}, #t49, 1) : null;
+  let final self::Class2? #t50 = c2 in #t50.{core::Object::==}(null) ?{core::int?} null : let final core::int #t51 = 0 in self::Extension|[](#t50{self::Class2}, #t51).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t50{self::Class2}, #t51, 1.{core::num::+}(self::Extension|[](c2{self::Class2}, 1))) : null;
+  let final self::Class1? #t52 = c1 in #t52.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t53 = #t52{self::Class1}.{self::Class1::field} in #t53.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t53{self::Class2}, 0);
+  let final self::Class1? #t54 = c1 in #t54.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t55 = #t54{self::Class1}.{self::Class1::field} in #t55.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t55{self::Class2}, 0, 1);
+  let final self::Class1? #t56 = c1 in #t56.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t57 = #t56{self::Class1}.{self::Class1::field} in #t57.{core::Object::==}(null) ?{core::int?} null : self::Extension|[]=(#t57{self::Class2}, 0, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0)));
+  let final self::Class1? #t58 = c1 in #t58.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t59 = #t58{self::Class1}.{self::Class1::field} in #t59.{core::Object::==}(null) ?{core::int?} null : let final core::int #t60 = 0 in self::Extension|[]=(#t59{self::Class2}, #t60, self::Extension|[](#t59{self::Class2}, #t60).{core::num::+}(1));
+  let final self::Class1? #t61 = c1 in #t61.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t62 = #t61{self::Class1}.{self::Class1::field} in #t62.{core::Object::==}(null) ?{core::int?} null : let final core::int #t63 = 0 in self::Extension|[]=(#t62{self::Class2}, #t63, self::Extension|[](#t62{self::Class2}, #t63).{core::num::+}(1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(0))));
+  let final self::Class1? #t64 = c1 in #t64.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t65 = #t64{self::Class1}.{self::Class1::field} in #t65.{core::Object::==}(null) ?{core::int?} null : let final core::int #t66 = 0 in let final core::int #t67 = self::Extension|[](#t65{self::Class2}, #t66).{core::num::+}(1) in let final void #t68 = self::Extension|[]=(#t65{self::Class2}, #t66, #t67) in #t67;
+  let final self::Class1? #t69 = c1 in #t69.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t70 = #t69{self::Class1}.{self::Class1::field} in #t70.{core::Object::==}(null) ?{core::int?} null : let final core::int #t71 = 0 in self::Extension|[]=(#t70{self::Class2}, #t71, self::Extension|[](#t70{self::Class2}, #t71).{core::num::+}(1));
+  let final self::Class1? #t72 = c1 in #t72.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t73 = #t72{self::Class1}.{self::Class1::field} in #t73.{core::Object::==}(null) ?{core::int?} null : let final core::int #t74 = 0 in self::Extension|[](#t73{self::Class2}, #t74).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t73{self::Class2}, #t74, 1) : null;
+  let final self::Class1? #t75 = c1 in #t75.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t76 = #t75{self::Class1}.{self::Class1::field} in #t76.{core::Object::==}(null) ?{core::int?} null : let final core::int #t77 = 0 in self::Extension|[](#t76{self::Class2}, #t77).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t76{self::Class2}, #t77, 1.{core::num::+}(c1{self::Class1}.{self::Class1::[]}(1))) : null;
+  let final self::Class1? #t78 = c1 in #t78.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t79 = #t78{self::Class1}.{self::Class1::field} in #t79.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t79{self::Class2}, 0);
   let final self::Class1? #t80 = c1 in #t80.{core::Object::==}(null) ?{void} null : let final self::Class2? #t81 = #t80{self::Class1}.{self::Class1::field} in #t81.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t81{self::Class2}, 0, 1);
-  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}(let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t84{self::Class2}, 0)));
-  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
-  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}(let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t91{self::Class2}, 0))));
-  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
-  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
-  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
-  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}(let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int} null : self::Extension|[](#t106{self::Class2}, 1))) : null;
+  let final self::Class1? #t82 = c1 in #t82.{core::Object::==}(null) ?{void} null : let final self::Class2? #t83 = #t82{self::Class1}.{self::Class1::field} in #t83.{core::Object::==}(null) ?{void} null : self::Extension|[]=(#t83{self::Class2}, 0, 1.{core::num::+}((let final self::Class2? #t84 = c2 in #t84.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t84{self::Class2}, 0))!));
+  let final self::Class1? #t85 = c1 in #t85.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t86 = #t85{self::Class1}.{self::Class1::field} in #t86.{core::Object::==}(null) ?{core::int?} null : let final core::int #t87 = 0 in self::Extension|[]=(#t86{self::Class2}, #t87, self::Extension|[](#t86{self::Class2}, #t87).{core::num::+}(1));
+  let final self::Class1? #t88 = c1 in #t88.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t89 = #t88{self::Class1}.{self::Class1::field} in #t89.{core::Object::==}(null) ?{core::int?} null : let final core::int #t90 = 0 in self::Extension|[]=(#t89{self::Class2}, #t90, self::Extension|[](#t89{self::Class2}, #t90).{core::num::+}(1.{core::num::+}((let final self::Class2? #t91 = c2 in #t91.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t91{self::Class2}, 0))!)));
+  let final self::Class1? #t92 = c1 in #t92.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t93 = #t92{self::Class1}.{self::Class1::field} in #t93.{core::Object::==}(null) ?{core::int?} null : let final core::int #t94 = 0 in let final core::int #t95 = self::Extension|[](#t93{self::Class2}, #t94).{core::num::+}(1) in let final void #t96 = self::Extension|[]=(#t93{self::Class2}, #t94, #t95) in #t95;
+  let final self::Class1? #t97 = c1 in #t97.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t98 = #t97{self::Class1}.{self::Class1::field} in #t98.{core::Object::==}(null) ?{core::int?} null : let final core::int #t99 = 0 in self::Extension|[]=(#t98{self::Class2}, #t99, self::Extension|[](#t98{self::Class2}, #t99).{core::num::+}(1));
+  let final self::Class1? #t100 = c1 in #t100.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t101 = #t100{self::Class1}.{self::Class1::field} in #t101.{core::Object::==}(null) ?{core::int?} null : let final core::int #t102 = 0 in self::Extension|[](#t101{self::Class2}, #t102).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t101{self::Class2}, #t102, 1) : null;
+  let final self::Class1? #t103 = c1 in #t103.{core::Object::==}(null) ?{core::int?} null : let final self::Class2? #t104 = #t103{self::Class1}.{self::Class1::field} in #t104.{core::Object::==}(null) ?{core::int?} null : let final core::int #t105 = 0 in self::Extension|[](#t104{self::Class2}, #t105).{core::num::==}(null) ?{core::int} self::Extension|[]=(#t104{self::Class2}, #t105, 1.{core::num::+}((let final self::Class2? #t106 = c2 in #t106.{core::Object::==}(null) ?{core::int?} null : self::Extension|[](#t106{self::Class2}, 1))!)) : null;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.expect
index 03c7096..509f924 100644
--- a/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.expect
@@ -38,8 +38,8 @@
 Try accessing using ?. instead.
   throws(() => c.nonNullableField);
                  ^^^^^^^^^^^^^^^^" in c.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A} null : #t2{self::Class}.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::A} null : #t3{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
+  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A?} null : #t2{self::Class}.{self::Class::nonNullableField});
+  self::expect(null, let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::A?} null : #t3{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.transformed.expect
index 03c7096..509f924 100644
--- a/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.strong.transformed.expect
@@ -38,8 +38,8 @@
 Try accessing using ?. instead.
   throws(() => c.nonNullableField);
                  ^^^^^^^^^^^^^^^^" in c.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A} null : #t2{self::Class}.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::A} null : #t3{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
+  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A?} null : #t2{self::Class}.{self::Class::nonNullableField});
+  self::expect(null, let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::A?} null : #t3{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.expect
index b158ff0..ca860c8 100644
--- a/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.expect
@@ -34,8 +34,8 @@
 static method main() → dynamic {
   self::Class? c;
   self::throws(() → self::A => c.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::A} null : #t1{self::Class}.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A} null : #t2{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
+  self::expect(null, let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::A?} null : #t1{self::Class}.{self::Class::nonNullableField});
+  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A?} null : #t2{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.transformed.expect
index b158ff0..ca860c8 100644
--- a/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.weak.transformed.expect
@@ -34,8 +34,8 @@
 static method main() → dynamic {
   self::Class? c;
   self::throws(() → self::A => c.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::A} null : #t1{self::Class}.{self::Class::nonNullableField});
-  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A} null : #t2{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
+  self::expect(null, let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::A?} null : #t1{self::Class}.{self::Class::nonNullableField});
+  self::expect(null, let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::A?} null : #t2{self::Class}.{self::Class::nonNullableField}.{self::A::nonNullableProperty});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
index 063cf03..3adb898 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -16,7 +16,7 @@
   self::test_nullable_function_type_formal_param(f: () → core::int => 2);
 }
 static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
-  return let final core::int #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+  return let final core::int? #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1{core::int};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
index 063cf03..3adb898 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -16,7 +16,7 @@
   self::test_nullable_function_type_formal_param(f: () → core::int => 2);
 }
 static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
-  return let final core::int #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+  return let final core::int? #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1{core::int};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.expect
index 063cf03..3adb898 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.expect
@@ -16,7 +16,7 @@
   self::test_nullable_function_type_formal_param(f: () → core::int => 2);
 }
 static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
-  return let final core::int #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+  return let final core::int? #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1{core::int};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.transformed.expect
index 063cf03..3adb898 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.weak.transformed.expect
@@ -16,7 +16,7 @@
   self::test_nullable_function_type_formal_param(f: () → core::int => 2);
 }
 static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
-  return let final core::int #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+  return let final core::int? #t1 = let final () →? core::int #t2 = f in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{() → core::int}.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1{core::int};
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required.dart b/pkg/front_end/testcases/nnbd/required.dart
index 7ec6144..8e57d7d 100644
--- a/pkg/front_end/testcases/nnbd/required.dart
+++ b/pkg/front_end/testcases/nnbd/required.dart
@@ -19,4 +19,38 @@
 
 Function({int a, required int b}) field;
 
+abstract class A {
+  // It's ok to omit the default values in abstract members.
+  foo({int x});
+}
+
+class B extends A {
+  // This is an implementation and it should have the default value.
+  foo({x}) {}
+}
+
+class C extends A {
+  foo({x = 42}) {}
+}
+
+ok() {
+  Function({int a, required int b}) f;
+  void g({int a = 42, required int b}) {}
+  f = ({int a = 42, required int b}) {};
+
+  Function(int a, [int b = 42]) f2;
+  void g2(int a, [int b = 42]) {}
+  f2 = (int a, [int b = 42]) {};
+}
+
+error() {
+  Function({int a, required int b}) f;
+  void g({int a, required int b = 42}) {}
+  f = ({int a, required int b = 42}) {};
+
+  Function(int a = 42, [int b]) f2;
+  void g2(int a = 42, [int b]) {}
+  f2 = (int a = 42, [int b]) {};
+}
+
 main() {}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.outline.expect b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
index cf10a97..bac1604 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+//   foo({x}) {}
+//        ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,8 +17,29 @@
   method method({core::int a = 42, required core::int b, required final core::int c, required covariant final core::int d}) → dynamic
     ;
 }
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  abstract method foo({core::int x}) → dynamic;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  method foo({core::int x}) → dynamic
+    ;
+}
+class C extends self::A {
+  synthetic constructor •() → self::C
+    ;
+  method foo({core::int x = 42}) → dynamic
+    ;
+}
 static field ({a: core::int, required b: core::int}) → dynamic field;
 static method method({core::int a, required core::int b, required final core::int c}) → dynamic
   ;
+static method ok() → dynamic
+  ;
+static method error() → dynamic
+  ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
index 0347610..07ebc91 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
@@ -1,4 +1,54 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+//   foo({x}) {}
+//        ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:41:26: Error: Can't have a default value in a function type.
+//   Function(int a, [int b = 42]) f2;
+//                          ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:51:18: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   Function(int a = 42, [int b]) f2;
+//                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:17: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   void g2(int a = 42, [int b]) {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:15: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   f2 = (int a = 42, [int b]) {};
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+//   void g({int a, required int b = 42}) {}
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:31: Error: Named parameter 'b' is required and can't have a default value.
+//   void g({int a, required int b = 42}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+//   f = ({int a, required int b = 42}) {};
+//             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:29: Error: Named parameter 'b' is required and can't have a default value.
+//   f = ({int a, required int b = 42}) {};
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+//   void g2(int a = 42, [int b]) {}
+//                            ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+//   f2 = (int a = 42, [int b]) {};
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,8 +60,42 @@
     ;
   method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2, required covariant final core::int d = #C2}) → dynamic {}
 }
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract method foo({core::int x = #C2}) → dynamic;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C2}) → dynamic {}
+}
+class C extends self::A {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C1}) → dynamic {}
+}
 static field ({a: core::int, required b: core::int}) → dynamic field;
 static method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2}) → dynamic {}
+static method ok() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C1, required core::int b = #C2}) → void {}
+  f = ({core::int a = #C1, required core::int b = #C2}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a, [core::int b = #C1]) → void {}
+  f2 = (core::int a, [core::int b = #C1]) → core::Null? {};
+}
+static method error() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C2, required core::int b = #C1}) → void {}
+  f = ({core::int a = #C2, required core::int b = #C1}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a = #C1, [core::int b = #C2]) → void {}
+  f2 = (core::int a = #C1, [core::int b = #C2]) → core::Null? {};
+}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
index 0347610..07ebc91 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
@@ -1,4 +1,54 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Error: Optional parameter 'x' should have a default value because its type 'int' doesn't allow null.
+//   foo({x}) {}
+//        ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:41:26: Error: Can't have a default value in a function type.
+//   Function(int a, [int b = 42]) f2;
+//                          ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:51:18: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   Function(int a = 42, [int b]) f2;
+//                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:17: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   void g2(int a = 42, [int b]) {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:15: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   f2 = (int a = 42, [int b]) {};
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+//   void g({int a, required int b = 42}) {}
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:31: Error: Named parameter 'b' is required and can't have a default value.
+//   void g({int a, required int b = 42}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Error: Optional parameter 'a' should have a default value because its type 'int' doesn't allow null.
+//   f = ({int a, required int b = 42}) {};
+//             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:29: Error: Named parameter 'b' is required and can't have a default value.
+//   f = ({int a, required int b = 42}) {};
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+//   void g2(int a = 42, [int b]) {}
+//                            ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Error: Optional parameter 'b' should have a default value because its type 'int' doesn't allow null.
+//   f2 = (int a = 42, [int b]) {};
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,8 +60,42 @@
     ;
   method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2, required covariant final core::int d = #C2}) → dynamic {}
 }
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract method foo({core::int x = #C2}) → dynamic;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C2}) → dynamic {}
+}
+class C extends self::A {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C1}) → dynamic {}
+}
 static field ({a: core::int, required b: core::int}) → dynamic field;
 static method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2}) → dynamic {}
+static method ok() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C1, required core::int b = #C2}) → void {}
+  f = ({core::int a = #C1, required core::int b = #C2}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a, [core::int b = #C1]) → void {}
+  f2 = (core::int a, [core::int b = #C1]) → core::Null? {};
+}
+static method error() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C2, required core::int b = #C1}) → void {}
+  f = ({core::int a = #C2, required core::int b = #C1}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a = #C1, [core::int b = #C2]) → void {}
+  f2 = (core::int a = #C1, [core::int b = #C2]) → core::Null? {};
+}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required.dart.weak.expect b/pkg/front_end/testcases/nnbd/required.dart.weak.expect
index 0347610..4ae3e4f 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.weak.expect
@@ -1,4 +1,54 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Warning: Optional parameter 'x' doesn't have a default value and its type 'int' doesn't allow null.
+//   foo({x}) {}
+//        ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:41:26: Error: Can't have a default value in a function type.
+//   Function(int a, [int b = 42]) f2;
+//                          ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:51:18: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   Function(int a = 42, [int b]) f2;
+//                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:17: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   void g2(int a = 42, [int b]) {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:15: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   f2 = (int a = 42, [int b]) {};
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Warning: Optional parameter 'a' doesn't have a default value and its type 'int' doesn't allow null.
+//   void g({int a, required int b = 42}) {}
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:31: Warning: Named parameter 'b' is required and has a default value.
+//   void g({int a, required int b = 42}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Warning: Optional parameter 'a' doesn't have a default value and its type 'int' doesn't allow null.
+//   f = ({int a, required int b = 42}) {};
+//             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:29: Warning: Named parameter 'b' is required and has a default value.
+//   f = ({int a, required int b = 42}) {};
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Warning: Optional parameter 'b' doesn't have a default value and its type 'int' doesn't allow null.
+//   void g2(int a = 42, [int b]) {}
+//                            ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Warning: Optional parameter 'b' doesn't have a default value and its type 'int' doesn't allow null.
+//   f2 = (int a = 42, [int b]) {};
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,8 +60,42 @@
     ;
   method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2, required covariant final core::int d = #C2}) → dynamic {}
 }
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract method foo({core::int x = #C2}) → dynamic;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C2}) → dynamic {}
+}
+class C extends self::A {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C1}) → dynamic {}
+}
 static field ({a: core::int, required b: core::int}) → dynamic field;
 static method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2}) → dynamic {}
+static method ok() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C1, required core::int b = #C2}) → void {}
+  f = ({core::int a = #C1, required core::int b = #C2}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a, [core::int b = #C1]) → void {}
+  f2 = (core::int a, [core::int b = #C1]) → core::Null? {};
+}
+static method error() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C2, required core::int b = #C1}) → void {}
+  f = ({core::int a = #C2, required core::int b = #C1}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a = #C1, [core::int b = #C2]) → void {}
+  f2 = (core::int a = #C1, [core::int b = #C2]) → core::Null? {};
+}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
index 0347610..4ae3e4f 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.weak.transformed.expect
@@ -1,4 +1,54 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/required.dart:29:8: Warning: Optional parameter 'x' doesn't have a default value and its type 'int' doesn't allow null.
+//   foo({x}) {}
+//        ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:41:26: Error: Can't have a default value in a function type.
+//   Function(int a, [int b = 42]) f2;
+//                          ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:51:18: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   Function(int a = 42, [int b]) f2;
+//                  ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:17: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   void g2(int a = 42, [int b]) {}
+//                 ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:15: Error: Non-optional parameters can't have a default value.
+// Try removing the default value or making the parameter optional.
+//   f2 = (int a = 42, [int b]) {};
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:15: Warning: Optional parameter 'a' doesn't have a default value and its type 'int' doesn't allow null.
+//   void g({int a, required int b = 42}) {}
+//               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:48:31: Warning: Named parameter 'b' is required and has a default value.
+//   void g({int a, required int b = 42}) {}
+//                               ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:13: Warning: Optional parameter 'a' doesn't have a default value and its type 'int' doesn't allow null.
+//   f = ({int a, required int b = 42}) {};
+//             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:49:29: Warning: Named parameter 'b' is required and has a default value.
+//   f = ({int a, required int b = 42}) {};
+//                             ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:52:28: Warning: Optional parameter 'b' doesn't have a default value and its type 'int' doesn't allow null.
+//   void g2(int a = 42, [int b]) {}
+//                            ^
+//
+// pkg/front_end/testcases/nnbd/required.dart:53:26: Warning: Optional parameter 'b' doesn't have a default value and its type 'int' doesn't allow null.
+//   f2 = (int a = 42, [int b]) {};
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,8 +60,42 @@
     ;
   method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2, required covariant final core::int d = #C2}) → dynamic {}
 }
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract method foo({core::int x = #C2}) → dynamic;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C2}) → dynamic {}
+}
+class C extends self::A {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  method foo({core::int x = #C1}) → dynamic {}
+}
 static field ({a: core::int, required b: core::int}) → dynamic field;
 static method method({core::int a = #C1, required core::int b = #C2, required final core::int c = #C2}) → dynamic {}
+static method ok() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C1, required core::int b = #C2}) → void {}
+  f = ({core::int a = #C1, required core::int b = #C2}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a, [core::int b = #C1]) → void {}
+  f2 = (core::int a, [core::int b = #C1]) → core::Null? {};
+}
+static method error() → dynamic {
+  ({a: core::int, required b: core::int}) → dynamic f;
+  function g({core::int a = #C2, required core::int b = #C1}) → void {}
+  f = ({core::int a = #C2, required core::int b = #C1}) → core::Null? {};
+  (core::int, [core::int]) → dynamic f2;
+  function g2(core::int a = #C1, [core::int b = #C2]) → void {}
+  f2 = (core::int a = #C1, [core::int b = #C2]) → core::Null? {};
+}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart b/pkg/front_end/testcases/nnbd/required_named_parameter.dart
index 97f1ba3..625189d 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart
@@ -5,9 +5,11 @@
 // Should be a compile-time error / warning.
 foo({required int parameter = 42}) {}
 foo2({int parameter}) {}
+foo3([int parameter]) {}
 
 // Should be ok.
 bar({required int parameter}) {}
 bar2({int parameter = 42}) {}
+bar3([int parameter = 42]) {}
 
 main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
index a0fc817..bfd9052 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.outline.expect
@@ -2,10 +2,18 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Required named parameter 'parameter' can't have a default value.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Named parameter 'parameter' is required and can't have a default value.
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo2({int parameter}) {}
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo3([int parameter]) {}
+//           ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -13,9 +21,13 @@
   ;
 static method foo2({core::int parameter}) → dynamic
   ;
+static method foo3([core::int parameter]) → dynamic
+  ;
 static method bar({required core::int parameter}) → dynamic
   ;
 static method bar2({core::int parameter}) → dynamic
   ;
+static method bar3([core::int parameter]) → dynamic
+  ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
index ff04da2..c706ee0 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.expect
@@ -2,17 +2,27 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Required named parameter 'parameter' can't have a default value.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Named parameter 'parameter' is required and can't have a default value.
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo2({int parameter}) {}
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo3([int parameter]) {}
+//           ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
 static method foo({required core::int parameter = #C1}) → dynamic {}
 static method foo2({core::int parameter = #C2}) → dynamic {}
+static method foo3([core::int parameter = #C2]) → dynamic {}
 static method bar({required core::int parameter = #C2}) → dynamic {}
 static method bar2({core::int parameter = #C1}) → dynamic {}
+static method bar3([core::int parameter = #C1]) → dynamic {}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
index ff04da2..c706ee0 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.strong.transformed.expect
@@ -2,17 +2,27 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Required named parameter 'parameter' can't have a default value.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Error: Named parameter 'parameter' is required and can't have a default value.
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo2({int parameter}) {}
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Error: Optional parameter 'parameter' should have a default value because its type 'int' doesn't allow null.
+// foo3([int parameter]) {}
+//           ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
 static method foo({required core::int parameter = #C1}) → dynamic {}
 static method foo2({core::int parameter = #C2}) → dynamic {}
+static method foo3([core::int parameter = #C2]) → dynamic {}
 static method bar({required core::int parameter = #C2}) → dynamic {}
 static method bar2({core::int parameter = #C1}) → dynamic {}
+static method bar3([core::int parameter = #C1]) → dynamic {}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
index 1686682..f8837f9 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.expect
@@ -2,17 +2,27 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Warning: Required named parameter 'parameter' has a default value.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Warning: Named parameter 'parameter' is required and has a default value.
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Warning: Optional parameter 'parameter' doesn't have a default value and its type 'int' doesn't allow null.
+// foo2({int parameter}) {}
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Warning: Optional parameter 'parameter' doesn't have a default value and its type 'int' doesn't allow null.
+// foo3([int parameter]) {}
+//           ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
 static method foo({required core::int parameter = #C1}) → dynamic {}
 static method foo2({core::int parameter = #C2}) → dynamic {}
+static method foo3([core::int parameter = #C2]) → dynamic {}
 static method bar({required core::int parameter = #C2}) → dynamic {}
 static method bar2({core::int parameter = #C1}) → dynamic {}
+static method bar3([core::int parameter = #C1]) → dynamic {}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
index 1686682..f8837f9 100644
--- a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.weak.transformed.expect
@@ -2,17 +2,27 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Warning: Required named parameter 'parameter' has a default value.
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:6:19: Warning: Named parameter 'parameter' is required and has a default value.
 // foo({required int parameter = 42}) {}
 //                   ^^^^^^^^^
 //
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:7:11: Warning: Optional parameter 'parameter' doesn't have a default value and its type 'int' doesn't allow null.
+// foo2({int parameter}) {}
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/required_named_parameter.dart:8:11: Warning: Optional parameter 'parameter' doesn't have a default value and its type 'int' doesn't allow null.
+// foo3([int parameter]) {}
+//           ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
 static method foo({required core::int parameter = #C1}) → dynamic {}
 static method foo2({core::int parameter = #C2}) → dynamic {}
+static method foo3([core::int parameter = #C2]) → dynamic {}
 static method bar({required core::int parameter = #C2}) → dynamic {}
 static method bar2({core::int parameter = #C1}) → dynamic {}
+static method bar3([core::int parameter = #C1]) → dynamic {}
 static method main() → dynamic {}
 
 constants  {
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart b/pkg/front_end/testcases/nnbd/return_late.dart
new file mode 100644
index 0000000..04fc076
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class<E> {
+  final E field;
+
+  Class(this.field);
+
+  E returnTypeVariable() {
+    late E result = field;
+    return result;
+  }
+}
+
+int returnNonNullable(int value) {
+  late int result = value;
+  return result;
+}
+
+int? returnNullable(int? value) {
+  late int? result = value;
+  return result;
+}
+
+main() {
+  expect(42, new Class<int>(42).returnTypeVariable());
+  expect(87, new Class<int?>(87).returnTypeVariable());
+  expect(null, new Class<int?>(null).returnTypeVariable());
+  expect(42, returnNonNullable(42));
+  expect(87, returnNullable(87));
+  expect(null, returnNullable(null));
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.outline.expect b/pkg/front_end/testcases/nnbd/return_late.dart.outline.expect
new file mode 100644
index 0000000..b09c8c1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.outline.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    ;
+  method returnTypeVariable() → self::Class::E%
+    ;
+}
+static method returnNonNullable(core::int value) → core::int
+  ;
+static method returnNullable(core::int? value) → core::int?
+  ;
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_late.dart.strong.expect
new file mode 100644
index 0000000..7829fc4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.strong.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    late self::Class::E% result = this.{self::Class::field};
+    return result;
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  late core::int result = value;
+  return result;
+}
+static method returnNullable(core::int? value) → core::int? {
+  late core::int? result = value;
+  return result;
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect
new file mode 100644
index 0000000..3da0607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    function #result#initializer() → self::Class::E%
+      return this.{self::Class::field};
+    late self::Class::E% result = #result#initializer.call();
+    return result;
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  function #result#initializer() → core::int
+    return value;
+  late core::int result = #result#initializer.call();
+  return result;
+}
+static method returnNullable(core::int? value) → core::int? {
+  function #result#initializer() → core::int?
+    return value;
+  late core::int? result = #result#initializer.call();
+  return result;
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_late.dart.weak.expect
new file mode 100644
index 0000000..7829fc4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.weak.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    late self::Class::E% result = this.{self::Class::field};
+    return result;
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  late core::int result = value;
+  return result;
+}
+static method returnNullable(core::int? value) → core::int? {
+  late core::int? result = value;
+  return result;
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect
new file mode 100644
index 0000000..3da0607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.weak.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<E extends core::Object? = dynamic> extends core::Object {
+  final field self::Class::E% field;
+  constructor •(self::Class::E% field) → self::Class<self::Class::E%>
+    : self::Class::field = field, super core::Object::•()
+    ;
+  method returnTypeVariable() → self::Class::E% {
+    function #result#initializer() → self::Class::E%
+      return this.{self::Class::field};
+    late self::Class::E% result = #result#initializer.call();
+    return result;
+  }
+}
+static method returnNonNullable(core::int value) → core::int {
+  function #result#initializer() → core::int
+    return value;
+  late core::int result = #result#initializer.call();
+  return result;
+}
+static method returnNullable(core::int? value) → core::int? {
+  function #result#initializer() → core::int?
+    return value;
+  late core::int? result = #result#initializer.call();
+  return result;
+}
+static method main() → dynamic {
+  self::expect(42, new self::Class::•<core::int>(42).{self::Class::returnTypeVariable}());
+  self::expect(87, new self::Class::•<core::int?>(87).{self::Class::returnTypeVariable}());
+  self::expect(null, new self::Class::•<core::int?>(null).{self::Class::returnTypeVariable}());
+  self::expect(42, self::returnNonNullable(42));
+  self::expect(87, self::returnNullable(87));
+  self::expect(null, self::returnNullable(null));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart b/pkg/front_end/testcases/nnbd/shorting_stop.dart
new file mode 100644
index 0000000..c3b0a43
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  int field = 0;
+  Class get next => this;
+  int operator [](int key) => key;
+  void operator []=(int key, int value) {}
+}
+
+main() {
+  test(new Class());
+}
+
+test(Class? c) {
+  c?.next.field; // ok
+  throwsInStrong(() => c?.field + 2); // error
+  // TODO(johnniwinther): Stop shorting a inc/dec.
+  ++c?.field; // error
+  c?.field++; // error
+  throwsInStrong(() => (c?.next).field); // error
+
+  c?.next[0].isEven; // ok
+  throwsInStrong(() => c?.next[0] + 2); // error
+  // TODO(johnniwinther): Stop shorting a inc/dec.
+  ++c?.next[0]; // error
+  c?.next[0]++; // error
+  throwsInStrong(() => (c?.next[0]).isEven); // error
+}
+
+final bool inStrongMode = _inStrongMode();
+
+bool _inStrongMode() {
+  var f = (String? s) {
+    s.length; // This will be an invalid expression in strong mode.
+  };
+  try {
+    f("foo");
+  } catch (e) {
+    return true;
+  }
+  return false;
+}
+
+void throwsInStrong(void Function() f) {
+  if (inStrongMode) {
+    try {
+      f();
+    } catch (e) {
+      print(e);
+      return;
+    }
+    throw 'Expected exception.';
+  } else {
+    f();
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.outline.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.outline.expect
new file mode 100644
index 0000000..11c3840
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int field;
+  synthetic constructor •() → self::Class
+    ;
+  get next() → self::Class
+    ;
+  operator [](core::int key) → core::int
+    ;
+  operator []=(core::int key, core::int value) → void
+    ;
+}
+static final field core::bool inStrongMode;
+static method main() → dynamic
+  ;
+static method test(self::Class? c) → dynamic
+  ;
+static method _inStrongMode() → core::bool
+  ;
+static method throwsInStrong(() → void f) → void
+  ;
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect
new file mode 100644
index 0000000..fe0c720
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect
@@ -0,0 +1,99 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   throwsInStrong(() => c?.field + 2); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Error: Property 'field' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next).field); // error
+//                                  ^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   throwsInStrong(() => c?.next[0] + 2); // error
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next[0]).isEven); // error
+//                                     ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Error: Property 'length' cannot be accessed on 'String?' because it is potentially null.
+// Try accessing using ?. instead.
+//     s.length; // This will be an invalid expression in strong mode.
+//       ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get next() → self::Class
+    return this;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+}
+static final field core::bool inStrongMode = self::_inStrongMode();
+static method main() → dynamic {
+  self::test(new self::Class::•());
+}
+static method test(self::Class? c) → dynamic {
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
+  self::throwsInStrong(() → core::int => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  throwsInStrong(() => c?.field + 2); // error
+                                ^" in (let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class}.{self::Class::field}).{core::num::+}(2));
+  let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = #t4.{self::Class::field}.{core::num::+}(1) in let final void #t6 = #t4.{self::Class::field} = #t5 in #t5;
+  let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{core::int?} null : #t7.{self::Class::field} = #t7.{self::Class::field}.{core::num::+}(1);
+  self::throwsInStrong(() → core::int => let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Error: Property 'field' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+Try accessing using ?. instead.
+  throwsInStrong(() => (c?.next).field); // error
+                                 ^^^^^" in (let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::next}).{self::Class::field});
+  let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::bool?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
+  self::throwsInStrong(() → core::int => let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  throwsInStrong(() => c?.next[0] + 2); // error
+                                  ^" in (let final self::Class? #t12 = c in #t12.{core::Object::==}(null) ?{core::int?} null : #t12{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+  let final self::Class? #t13 = c in #t13.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t14 = #t13{self::Class}.{self::Class::next} in let final core::int #t15 = 0 in let final core::int #t16 = #t14.{self::Class::[]}(#t15).{core::num::+}(1) in let final void #t17 = #t14.{self::Class::[]=}(#t15, #t16) in #t16;
+  let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t19 = #t18{self::Class}.{self::Class::next} in let final core::int #t20 = 0 in #t19.{self::Class::[]=}(#t20, #t19.{self::Class::[]}(#t20).{core::num::+}(1));
+  self::throwsInStrong(() → core::bool* => let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+Try accessing using ?. instead.
+  throwsInStrong(() => (c?.next[0]).isEven); // error
+                                    ^^^^^^" in (let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{core::int?} null : #t22{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
+}
+static method _inStrongMode() → core::bool {
+  (core::String?) → core::Null? f = (core::String? s) → core::Null? {
+    let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Error: Property 'length' cannot be accessed on 'String?' because it is potentially null.
+Try accessing using ?. instead.
+    s.length; // This will be an invalid expression in strong mode.
+      ^^^^^^" in s.{core::String::length};
+  };
+  try {
+    f.call("foo");
+  }
+  on dynamic catch(final dynamic e) {
+    return true;
+  }
+  return false;
+}
+static method throwsInStrong(() → void f) → void {
+  if(self::inStrongMode) {
+    try {
+      f.call();
+    }
+    on dynamic catch(final dynamic e) {
+      core::print(e);
+      return;
+    }
+    throw "Expected exception.";
+  }
+  else {
+    f.call();
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect
new file mode 100644
index 0000000..fe0c720
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect
@@ -0,0 +1,99 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   throwsInStrong(() => c?.field + 2); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Error: Property 'field' cannot be accessed on 'Class?' because it is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next).field); // error
+//                                  ^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+//   throwsInStrong(() => c?.next[0] + 2); // error
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next[0]).isEven); // error
+//                                     ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Error: Property 'length' cannot be accessed on 'String?' because it is potentially null.
+// Try accessing using ?. instead.
+//     s.length; // This will be an invalid expression in strong mode.
+//       ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get next() → self::Class
+    return this;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+}
+static final field core::bool inStrongMode = self::_inStrongMode();
+static method main() → dynamic {
+  self::test(new self::Class::•());
+}
+static method test(self::Class? c) → dynamic {
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
+  self::throwsInStrong(() → core::int => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  throwsInStrong(() => c?.field + 2); // error
+                                ^" in (let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class}.{self::Class::field}).{core::num::+}(2));
+  let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = #t4.{self::Class::field}.{core::num::+}(1) in let final void #t6 = #t4.{self::Class::field} = #t5 in #t5;
+  let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{core::int?} null : #t7.{self::Class::field} = #t7.{self::Class::field}.{core::num::+}(1);
+  self::throwsInStrong(() → core::int => let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Error: Property 'field' cannot be accessed on 'Class?' because it is potentially null.
+ - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+Try accessing using ?. instead.
+  throwsInStrong(() => (c?.next).field); // error
+                                 ^^^^^" in (let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{self::Class?} null : #t9{self::Class}.{self::Class::next}).{self::Class::field});
+  let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::bool?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
+  self::throwsInStrong(() → core::int => let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+  throwsInStrong(() => c?.next[0] + 2); // error
+                                  ^" in (let final self::Class? #t12 = c in #t12.{core::Object::==}(null) ?{core::int?} null : #t12{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+  let final self::Class? #t13 = c in #t13.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t14 = #t13{self::Class}.{self::Class::next} in let final core::int #t15 = 0 in let final core::int #t16 = #t14.{self::Class::[]}(#t15).{core::num::+}(1) in let final void #t17 = #t14.{self::Class::[]=}(#t15, #t16) in #t16;
+  let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t19 = #t18{self::Class}.{self::Class::next} in let final core::int #t20 = 0 in #t19.{self::Class::[]=}(#t20, #t19.{self::Class::[]}(#t20).{core::num::+}(1));
+  self::throwsInStrong(() → core::bool* => let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+Try accessing using ?. instead.
+  throwsInStrong(() => (c?.next[0]).isEven); // error
+                                    ^^^^^^" in (let final self::Class? #t22 = c in #t22.{core::Object::==}(null) ?{core::int?} null : #t22{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
+}
+static method _inStrongMode() → core::bool {
+  (core::String?) → core::Null? f = (core::String? s) → core::Null? {
+    let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Error: Property 'length' cannot be accessed on 'String?' because it is potentially null.
+Try accessing using ?. instead.
+    s.length; // This will be an invalid expression in strong mode.
+      ^^^^^^" in s.{core::String::length};
+  };
+  try {
+    f.call("foo");
+  }
+  on dynamic catch(final dynamic e) {
+    return true;
+  }
+  return false;
+}
+static method throwsInStrong(() → void f) → void {
+  if(self::inStrongMode) {
+    try {
+      f.call();
+    }
+    on dynamic catch(final dynamic e) {
+      core::print(e);
+      return;
+    }
+    throw "Expected exception.";
+  }
+  else {
+    f.call();
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect
new file mode 100644
index 0000000..c6ea10c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect
@@ -0,0 +1,85 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   throwsInStrong(() => c?.field + 2); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Warning: Property 'field' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next).field); // error
+//                                  ^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   throwsInStrong(() => c?.next[0] + 2); // error
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Warning: Property 'isEven' is accessed on 'int?' which is potentially null.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next[0]).isEven); // error
+//                                     ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Warning: Property 'length' is accessed on 'String?' which is potentially null.
+// Try accessing using ?. instead.
+//     s.length; // This will be an invalid expression in strong mode.
+//       ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get next() → self::Class
+    return this;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+}
+static final field core::bool inStrongMode = self::_inStrongMode();
+static method main() → dynamic {
+  self::test(new self::Class::•());
+}
+static method test(self::Class? c) → dynamic {
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
+  self::throwsInStrong(() → core::int => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
+  let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : let final core::int #t4 = #t3.{self::Class::field}.{core::num::+}(1) in let final void #t5 = #t3.{self::Class::field} = #t4 in #t4;
+  let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{core::int?} null : #t6.{self::Class::field} = #t6.{self::Class::field}.{core::num::+}(1);
+  self::throwsInStrong(() → core::int => (let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::next}).{self::Class::field});
+  let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{core::bool?} null : #t8{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
+  self::throwsInStrong(() → core::int => (let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{core::int?} null : #t9{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+  let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t11 = #t10{self::Class}.{self::Class::next} in let final core::int #t12 = 0 in let final core::int #t13 = #t11.{self::Class::[]}(#t12).{core::num::+}(1) in let final void #t14 = #t11.{self::Class::[]=}(#t12, #t13) in #t13;
+  let final self::Class? #t15 = c in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::next} in let final core::int #t17 = 0 in #t16.{self::Class::[]=}(#t17, #t16.{self::Class::[]}(#t17).{core::num::+}(1));
+  self::throwsInStrong(() → core::bool* => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{core::int?} null : #t18{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
+}
+static method _inStrongMode() → core::bool {
+  (core::String?) → core::Null? f = (core::String? s) → core::Null? {
+    s.{core::String::length};
+  };
+  try {
+    f.call("foo");
+  }
+  on dynamic catch(final dynamic e) {
+    return true;
+  }
+  return false;
+}
+static method throwsInStrong(() → void f) → void {
+  if(self::inStrongMode) {
+    try {
+      f.call();
+    }
+    on dynamic catch(final dynamic e) {
+      core::print(e);
+      return;
+    }
+    throw "Expected exception.";
+  }
+  else {
+    f.call();
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect
new file mode 100644
index 0000000..c6ea10c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect
@@ -0,0 +1,85 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   throwsInStrong(() => c?.field + 2); // error
+//                                 ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:22:34: Warning: Property 'field' is accessed on 'Class?' which is potentially null.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd/shorting_stop.dart'.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next).field); // error
+//                                  ^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Warning: Operator '+' is called on 'int?' which is potentially null.
+//   throwsInStrong(() => c?.next[0] + 2); // error
+//                                   ^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:29:37: Warning: Property 'isEven' is accessed on 'int?' which is potentially null.
+// Try accessing using ?. instead.
+//   throwsInStrong(() => (c?.next[0]).isEven); // error
+//                                     ^^^^^^
+//
+// pkg/front_end/testcases/nnbd/shorting_stop.dart:36:7: Warning: Property 'length' is accessed on 'String?' which is potentially null.
+// Try accessing using ?. instead.
+//     s.length; // This will be an invalid expression in strong mode.
+//       ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  get next() → self::Class
+    return this;
+  operator [](core::int key) → core::int
+    return key;
+  operator []=(core::int key, core::int value) → void {}
+}
+static final field core::bool inStrongMode = self::_inStrongMode();
+static method main() → dynamic {
+  self::test(new self::Class::•());
+}
+static method test(self::Class? c) → dynamic {
+  let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
+  self::throwsInStrong(() → core::int => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
+  let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : let final core::int #t4 = #t3.{self::Class::field}.{core::num::+}(1) in let final void #t5 = #t3.{self::Class::field} = #t4 in #t4;
+  let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{core::int?} null : #t6.{self::Class::field} = #t6.{self::Class::field}.{core::num::+}(1);
+  self::throwsInStrong(() → core::int => (let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::next}).{self::Class::field});
+  let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{core::bool?} null : #t8{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
+  self::throwsInStrong(() → core::int => (let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{core::int?} null : #t9{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+  let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t11 = #t10{self::Class}.{self::Class::next} in let final core::int #t12 = 0 in let final core::int #t13 = #t11.{self::Class::[]}(#t12).{core::num::+}(1) in let final void #t14 = #t11.{self::Class::[]=}(#t12, #t13) in #t13;
+  let final self::Class? #t15 = c in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::next} in let final core::int #t17 = 0 in #t16.{self::Class::[]=}(#t17, #t16.{self::Class::[]}(#t17).{core::num::+}(1));
+  self::throwsInStrong(() → core::bool* => (let final self::Class? #t18 = c in #t18.{core::Object::==}(null) ?{core::int?} null : #t18{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
+}
+static method _inStrongMode() → core::bool {
+  (core::String?) → core::Null? f = (core::String? s) → core::Null? {
+    s.{core::String::length};
+  };
+  try {
+    f.call("foo");
+  }
+  on dynamic catch(final dynamic e) {
+    return true;
+  }
+  return false;
+}
+static method throwsInStrong(() → void f) → void {
+  if(self::inStrongMode) {
+    try {
+      f.call();
+    }
+    on dynamic catch(final dynamic e) {
+      core::print(e);
+      return;
+    }
+    throw "Expected exception.";
+  }
+  else {
+    f.call();
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
index 7bac66b..b0ff7b9 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 static method warning(core::String s, core::List<core::String> l) → dynamic {
-  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int*} null : #t1.{core::String::length};
+  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int?} null : #t1.{core::String::length};
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::String} null : let final void #t3 = #t2.{core::String::length} in #t2;
   let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
   s.{core::String::==}(null) ?{core::String} s = "foo" : null;
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
index ec3449a..790e145 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
 import "dart:_internal" as _in;
 
 static method warning(core::String s, core::List<core::String> l) → dynamic {
-  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int*} null : #t1.{core::String::length};
+  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int?} null : #t1.{core::String::length};
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::String} null : let final void #t3 = #t2.{core::String::length} in #t2;
   let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
   s.{core::String::==}(null) ?{core::String} s = "foo" : null;
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
index 7bac66b..b0ff7b9 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 static method warning(core::String s, core::List<core::String> l) → dynamic {
-  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int*} null : #t1.{core::String::length};
+  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int?} null : #t1.{core::String::length};
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::String} null : let final void #t3 = #t2.{core::String::length} in #t2;
   let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
   s.{core::String::==}(null) ?{core::String} s = "foo" : null;
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
index ec3449a..790e145 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 import "dart:_internal" as _in;
 
 static method warning(core::String s, core::List<core::String> l) → dynamic {
-  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int*} null : #t1.{core::String::length};
+  let final core::String #t1 = s in #t1.{core::String::==}(null) ?{core::int?} null : #t1.{core::String::length};
   let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::String} null : let final void #t3 = #t2.{core::String::length} in #t2;
   let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
   s.{core::String::==}(null) ?{core::String} s = "foo" : null;
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 6aef73b..9df9418 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -14,6 +14,7 @@
 general/override_check_basic: TypeCheckError
 general/override_check_with_covariant_modifier: TypeCheckError
 general/override_setter_with_field: TypeCheckError
+general/with_dependencies/variance_from_dill/variance_from_dill: Crash
 
 general_nnbd_opt_out/abstract_members: TypeCheckError
 general_nnbd_opt_out/bug30695: TypeCheckError
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 9db9249..f05fdc6 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -65,6 +65,7 @@
 general/unsound_promotion: TypeCheckError
 general/void_methods: RuntimeError
 general/warn_unresolved_sends: InstrumentationMismatch # Test assumes Dart 1.0 semantics
+general/with_dependencies/variance_from_dill/variance_from_dill: Crash
 general_nnbd_opt_out/abstract_members: TypeCheckError
 general_nnbd_opt_out/accessors: RuntimeError
 general_nnbd_opt_out/ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 4bf3b34..efca1d2 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -336,6 +336,7 @@
 general/var_as_type_name: TextSerializationFailure # Was: Pass
 general/void_methods: TextSerializationFailure
 general/warn_unresolved_sends: InstrumentationMismatch # Test assumes Dart 1.0 semantics
+general/with_dependencies/variance_from_dill/variance_from_dill: Crash
 general_nnbd_opt_out/DeltaBlue: TextSerializationFailure # Was: Pass
 general_nnbd_opt_out/abstract_members: TypeCheckError
 general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
@@ -1178,6 +1179,7 @@
 late_lowering/instance_nullable_field_with_initializer: TextSerializationFailure
 late_lowering/instance_nullable_field_without_initializer: TextSerializationFailure
 late_lowering/instance_nullable_final_field_without_initializer: TextSerializationFailure
+late_lowering/issue40093: TextSerializationFailure
 late_lowering/late_field_with_initializer: TextSerializationFailure
 late_lowering/late_field_without_initializer: TextSerializationFailure
 late_lowering/late_final_field_with_initializer: TextSerializationFailure
@@ -1195,19 +1197,22 @@
 late_lowering/late_nullable_local_with_initializer: TextSerializationFailure
 late_lowering/late_nullable_local_without_initializer: TextSerializationFailure
 late_lowering/override: TextSerializationFailure
+late_lowering/return_late: TextSerializationFailure
 new_const_insertion/simple: TextSerializationFailure # Was: Pass
 nnbd/assignability: TextSerializationFailure
-nnbd/definite_assignment_and_completion
+nnbd/call: TextSerializationFailure
 nnbd/definite_assignment_and_completion: TextSerializationFailure
 nnbd/forbidden_supers: TextSerializationFailure
 nnbd/forin: TextSerializationFailure
 nnbd/function_types: TextSerializationFailure
+nnbd/generic_override: TextSerializationFailure
 nnbd/infer_if_null: TextSerializationFailure
 nnbd/inheritance_from_opt_in: TypeCheckError
 nnbd/inheritance_from_opt_out: TextSerializationFailure
 nnbd/intersection_types: TextSerializationFailure
 nnbd/issue39659: TextSerializationFailure
 nnbd/issue39822: TextSerializationFailure
+nnbd/issue40093: TextSerializationFailure
 nnbd/issue40134: TextSerializationFailure
 nnbd/issue_39286: TextSerializationFailure
 nnbd/issue_39286_2: TextSerializationFailure
@@ -1223,6 +1228,7 @@
 nnbd/no_null_shorting: TextSerializationFailure
 nnbd/no_null_shorting_explicit_extension: TextSerializationFailure
 nnbd/no_null_shorting_extension: TextSerializationFailure
+nnbd/null_access: TextSerializationFailure
 nnbd/null_aware_chain: TextSerializationFailure
 nnbd/null_check: TextSerializationFailure
 nnbd/null_shorting: TextSerializationFailure
@@ -1239,6 +1245,8 @@
 nnbd/regress_null_aware: TextSerializationFailure
 nnbd/required: TextSerializationFailure
 nnbd/required_named_parameter: TextSerializationFailure
+nnbd/return_late: TextSerializationFailure
+nnbd/shorting_stop: TextSerializationFailure
 nnbd/simple_never: TextSerializationFailure
 nnbd/sink_hierarchy: TextSerializationFailure
 nnbd/strictly_non_nullable_warnings: TextSerializationFailure
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 90e2696..454d199 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -99,6 +99,8 @@
           ' option',
       defaultsTo: 'org-dartlang-root',
       hide: true)
+  ..addFlag('enable-http-uris',
+      defaultsTo: false, hide: true, help: 'Enables support for http uris.')
   ..addFlag('verbose', help: 'Enables verbose output from the compiler.')
   ..addOption('initialize-from-dill',
       help: 'Normally the output dill is used to specify which dill to '
@@ -299,8 +301,9 @@
   }) async {
     _options = options;
     _fileSystem = createFrontEndFileSystem(
-        options['filesystem-scheme'], options['filesystem-root']);
-    _mainSource = _getFileOrUri(entryPoint);
+        options['filesystem-scheme'], options['filesystem-root'],
+        allowHttp: options['enable-http-uris']);
+    _mainSource = resolveInputUri(entryPoint);
     _kernelBinaryFilenameFull = _options['output-dill'] ?? '$entryPoint.dill';
     _kernelBinaryFilenameIncremental = _options['output-incremental-dill'] ??
         (_options['output-dill'] != null
@@ -314,10 +317,12 @@
     final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
     final String platformKernelDill =
         options['platform'] ?? 'platform_strong.dill';
+    final String packagesOption = _options['packages'];
     final CompilerOptions compilerOptions = CompilerOptions()
       ..sdkRoot = sdkRoot
       ..fileSystem = _fileSystem
-      ..packagesFileUri = _getFileOrUri(_options['packages'])
+      ..packagesFileUri =
+          packagesOption != null ? resolveInputUri(packagesOption) : null
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
       ..verbose = options['verbose']
       ..embedSourceText = options['embed-source-text']
@@ -774,7 +779,7 @@
     _outputStream.writeln('result $boundaryKey');
     await invalidateIfInitializingFromDill();
     if (entryPoint != null) {
-      _mainSource = _getFileOrUri(entryPoint);
+      _mainSource = resolveInputUri(entryPoint);
     }
     errors.clear();
 
@@ -956,9 +961,6 @@
     _kernelBinaryFilename = _kernelBinaryFilenameFull;
   }
 
-  Uri _getFileOrUri(String fileOrUri) =>
-      convertFileOrUriArgumentToUri(_fileSystem, fileOrUri);
-
   IncrementalCompiler _createGenerator(Uri initializeFromDillUri) {
     return IncrementalCompiler(_compilerOptions, _mainSource,
         initializeFromDillUri: initializeFromDillUri,
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index 5c92591..b00ed73 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -66,6 +66,19 @@
     var sourceMapOffset = 0;
     final manifest = <String, Map<String, List<int>>>{};
     final Set<Uri> visited = <Uri>{};
+
+    final importToSummary = Map<Library, Component>.identity();
+    final summaryToModule = Map<Component, String>.identity();
+    for (var i = 0; i < _summaries.length; i++) {
+      var summary = _summaries[i];
+      var moduleImport = _moduleImportForSummary[_summaryUris[i]];
+      for (var l in summary.libraries) {
+        assert(!importToSummary.containsKey(l));
+        importToSummary[l] = summary;
+        summaryToModule[summary] = moduleImport;
+      }
+    }
+
     for (Library library in _originalComponent.libraries) {
       if (loadedLibraries.contains(library) ||
           library.importUri.scheme == 'dart') {
@@ -83,10 +96,12 @@
         _originalComponent,
         classHierarchy,
         SharedCompilerOptions(sourceMap: true, summarizeApi: false),
+        importToSummary,
+        summaryToModule,
         coreTypes: coreTypes,
       );
-      final jsModule = compiler.emitModule(
-          summaryComponent, _summaries, _summaryUris, _moduleImportForSummary);
+
+      final jsModule = compiler.emitModule(summaryComponent);
 
       final moduleUrl = urlForComponentUri(moduleUri);
       String sourceMapBase;
@@ -106,9 +121,6 @@
         mapUrl: '$moduleUrl.lib.js.map',
         sourceMapBase: sourceMapBase,
         customScheme: _fileSystemScheme,
-        multiRootOutputPath: moduleUri.scheme == 'package'
-            ? '/packages/${moduleUri.pathSegments.first}'
-            : null,
       );
       final codeBytes = utf8.encode(code.code);
       final sourceMapBytes = utf8.encode(json.encode(code.sourceMap));
diff --git a/pkg/frontend_server/lib/src/strong_components.dart b/pkg/frontend_server/lib/src/strong_components.dart
index ef24a10..a631c30 100644
--- a/pkg/frontend_server/lib/src/strong_components.dart
+++ b/pkg/frontend_server/lib/src/strong_components.dart
@@ -80,7 +80,10 @@
         computeStrongComponents(_LibraryGraph(entrypoint, loadedLibraries));
     for (List<Library> component in results) {
       assert(component.length > 0);
-      final Uri moduleUri = component.first.importUri;
+      final Uri moduleUri = component
+          .firstWhere((lib) => lib.importUri == mainUri,
+              orElse: () => component.first)
+          .importUri;
       modules[moduleUri] = component;
       for (Library componentLibrary in component) {
         moduleAssignment[componentLibrary.importUri] = moduleUri;
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index 0d6c03a..301e609 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_test.dart
@@ -1235,6 +1235,77 @@
       expect(await starter(args), 0);
     });
 
+    group('http uris', () {
+      var host = 'localhost';
+      File dillFile;
+      int port;
+      HttpServer server;
+
+      setUp(() async {
+        dillFile = File('${tempDir.path}/app.dill');
+        server = await HttpServer.bind(host, 0);
+        port = server.port;
+        server.listen((request) {
+          var path = request.uri.path;
+          var file = File('${tempDir.path}$path');
+          var response = request.response;
+          if (!file.existsSync()) {
+            response.statusCode = 404;
+          } else {
+            response.statusCode = 200;
+            response.add(file.readAsBytesSync());
+          }
+          response.close();
+        });
+        var main = File('${tempDir.path}/foo.dart')..createSync();
+        main.writeAsStringSync(
+            "import 'package:foo/foo.dart'; main() {print(foo);}\n");
+        File('${tempDir.path}/.packages')
+          ..createSync()
+          ..writeAsStringSync("\nfoo:http://$host:$port/packages/foo");
+        File('${tempDir.path}/packages/foo/foo.dart')
+          ..createSync(recursive: true)
+          ..writeAsStringSync("var foo = 'hello';");
+      });
+
+      tearDown(() async {
+        await server.close();
+        print('closed');
+      });
+
+      test('compile with http uris', () async {
+        expect(dillFile.existsSync(), equals(false));
+        final List<String> args = <String>[
+          '--sdk-root=${sdkRoot.toFilePath()}',
+          '--incremental',
+          '--platform=${platformKernel.path}',
+          '--output-dill=${dillFile.path}',
+          '--enable-http-uris',
+          '--packages=http://$host:$port/.packages',
+          'http://$host:$port/foo.dart',
+        ];
+        expect(await starter(args), 0);
+        expect(dillFile.existsSync(), equals(true));
+      });
+
+      test('compile with an http file system root', () async {
+        expect(dillFile.existsSync(), equals(false));
+        final List<String> args = <String>[
+          '--sdk-root=${sdkRoot.toFilePath()}',
+          '--incremental',
+          '--platform=${platformKernel.path}',
+          '--output-dill=${dillFile.path}',
+          '--enable-http-uris',
+          '--packages=test-app:///.packages',
+          '--filesystem-root=http://$host:$port/',
+          '--filesystem-scheme=test-app',
+          'test-app:///foo.dart',
+        ];
+        expect(await starter(args), 0);
+        expect(dillFile.existsSync(), equals(true));
+      });
+    });
+
     test('compile to JavaScript', () async {
       var file = File('${tempDir.path}/foo.dart')..createSync();
       file.writeAsStringSync("main() {}\n");
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 2e7ddb0..ca12325 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -28,7 +28,7 @@
 };
 
 Target getTarget(String name, TargetFlags flags) {
-  var builder = targets[name];
+  _TargetBuilder builder = targets[name];
   if (builder == null) return null;
   return builder(flags);
 }
@@ -283,12 +283,19 @@
 
 class NoneTarget extends Target {
   final TargetFlags flags;
-  final bool supportsLateFields;
 
-  NoneTarget(this.flags, {this.supportsLateFields: true});
+  NoneTarget(this.flags);
 
+  @override
+  bool get supportsLateFields => !flags.forceLateLoweringForTesting;
+
+  @override
   String get name => 'none';
+
+  @override
   List<String> get extraRequiredLibraries => <String>[];
+
+  @override
   void performModularTransformationsOnLibraries(
       Component component,
       CoreTypes coreTypes,
diff --git a/pkg/native_stack_traces/.gitignore b/pkg/native_stack_traces/.gitignore
new file mode 100644
index 0000000..49ce72d
--- /dev/null
+++ b/pkg/native_stack_traces/.gitignore
@@ -0,0 +1,3 @@
+.dart_tool/
+.packages
+pubspec.lock
diff --git a/pkg/native_stack_traces/AUTHORS b/pkg/native_stack_traces/AUTHORS
new file mode 100644
index 0000000..846e4a1
--- /dev/null
+++ b/pkg/native_stack_traces/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the Dart project. Names should be added to the list like so:
+#
+#   Name/Organization <email address>
+
+Google LLC
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
new file mode 100644
index 0000000..f379ffe
--- /dev/null
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -0,0 +1,9 @@
+# Changelog
+
+## 0.2.0
+
+- API and documentation cleanups
+
+## 0.1.0
+
+- Initial release
diff --git a/pkg/native_stack_traces/LICENSE b/pkg/native_stack_traces/LICENSE
new file mode 100644
index 0000000..18daf2b
--- /dev/null
+++ b/pkg/native_stack_traces/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2020, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/native_stack_traces/README.md b/pkg/native_stack_traces/README.md
new file mode 100644
index 0000000..a052851
--- /dev/null
+++ b/pkg/native_stack_traces/README.md
@@ -0,0 +1,71 @@
+# native_stack_traces
+
+This package provides libraries and a utility for decoding non-symbolic
+stack traces generated by an AOT-compiled Dart application.
+
+## Converting stack traces
+
+In some modes of AOT compilation, information on mapping execution points to
+source locations is no longer stored in the Dart image. Instead, this
+information is translated to separately stored debugging information.
+This debugging information can then be stripped from the application
+before shipping.
+
+However, there is a drawback. Stack traces generated by such an application no
+longer includes file, function, and line number information (i.e., symbolic
+stack traces). Instead, stack trace frames simply include program counter
+information. Thus, to find the source information for these frames, we must use
+the debugging information. This means either keeping the original unstripped
+application, or saving the debugging information into a separate file.
+
+Given this debugging information, the libraries in this package can turn
+non-symbolic stack traces back into symbolic stack traces. In addition, this
+package includes a command line tool `decode` whose output is the same as its
+input except that non-symbolic stack traces are translated.
+
+### Using `decode`
+
+Take the following Dart code, which we put in `throws.dart`. The inlining
+pragmas are here just to ensure that `bar` is inlined into `foo` and that `foo`
+is _not_ inlined into `bar`, to illustrate how inlined code is handled in the
+translated output.
+
+```dart
+@pragma('vm:prefer-inline')
+bar() => throw null;
+
+@pragma('vm:never-inline')
+foo() => bar();
+
+main() => foo();
+```
+
+Now we run the following commands:
+
+```bash
+# Make sure that we have the native_stack_traces package.
+$ pub get native_stack_traces
+$ pub global activate native_stack_traces
+
+# We compile the example program, removing the source location information
+# from the snapshot and saving the debugging information into throws.debug.
+$ dart2native -k aot -S throws.debug -o throws.aotsnapshot throws.dart
+
+# Run the program, saving the error output to throws.err.
+$ dartaotruntime throws.aotsnapshot 2>throws.err
+
+# Using the saved debugging information, we can translate the stack trace
+# contained in throws.err to its symbolic form.
+$ pub global run native_stack_traces:decode translate -d throws.debug -i throws.err
+
+# We can also just pipe the output of running the program directly into
+# the utility.
+$ dartaotruntime throws.aotsnapshot |& \
+    pub global run native_stack_traces:decode translate -d throws.debug
+```
+
+## Features and bugs
+
+Please file feature requests and bugs at the [issue tracker][tracker].
+
+[tracker]: https://github.com/dart-lang/sdk/issues
diff --git a/pkg/native_stack_traces/analysis_options.yaml b/pkg/native_stack_traces/analysis_options.yaml
new file mode 100644
index 0000000..84a5e26
--- /dev/null
+++ b/pkg/native_stack_traces/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:pedantic/analysis_options.1.8.0.yaml
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
new file mode 100644
index 0000000..fe59643
--- /dev/null
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -0,0 +1,265 @@
+// 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";
+import "dart:convert";
+import "dart:io" as io;
+
+import 'package:args/args.dart' show ArgParser, ArgResults;
+import 'package:path/path.dart' as path;
+import 'package:native_stack_traces/native_stack_traces.dart';
+
+final ArgParser _translateParser = ArgParser(allowTrailingOptions: true)
+  ..addOption('debug',
+      abbr: 'd',
+      help: 'Filename containing debugging information (REQUIRED)',
+      valueHelp: 'FILE')
+  ..addOption('input',
+      abbr: 'i', help: 'Filename for processed input', valueHelp: 'FILE')
+  ..addOption('output',
+      abbr: 'o', help: 'Filename for generated output', valueHelp: 'FILE')
+  ..addFlag('verbose',
+      abbr: 'v',
+      negatable: false,
+      help: 'Translate all frames, not just user or library code frames');
+
+final ArgParser _findParser = ArgParser(allowTrailingOptions: true)
+  ..addOption('debug',
+      abbr: 'd',
+      help: 'Filename containing debugging information (REQUIRED)',
+      valueHelp: 'FILE')
+  ..addMultiOption('location',
+      abbr: 'l', help: 'PC address to find', valueHelp: 'PC')
+  ..addFlag('verbose',
+      abbr: 'v',
+      negatable: false,
+      help: 'Translate all frames, not just user or library code frames')
+  ..addOption('vm_start',
+      help: 'Absolute address for start of VM instructions', valueHelp: 'PC')
+  ..addOption('isolate_start',
+      help: 'Absolute address for start of isolate instructions',
+      valueHelp: 'PC');
+
+final ArgParser _helpParser = ArgParser(allowTrailingOptions: true);
+
+final ArgParser _argParser = ArgParser(allowTrailingOptions: true)
+  ..addCommand('help', _helpParser)
+  ..addCommand('find', _findParser)
+  ..addCommand('translate', _translateParser)
+  ..addFlag('help',
+      abbr: 'h',
+      negatable: false,
+      help: 'Print usage information for this or a particular subcommand');
+
+final String _mainUsage = '''
+Usage: convert_stack_traces <command> [options] ...
+
+Commands:
+${_argParser.commands.keys.join("\n")}
+
+Options shared by all commands:
+${_argParser.usage}''';
+
+final String _helpUsage = '''
+Usage: convert_stack_traces help [<command>]
+
+Returns usage for the convert_stack_traces utility or a particular command.
+
+Commands:
+${_argParser.commands.keys.join("\n")}''';
+
+final String _translateUsage = '''
+Usage: convert_stack_traces translate [options]
+
+The translate command takes text that includes non-symbolic stack traces
+generated by the VM when executing a snapshot compiled with the
+--dwarf-stack-traces flag. It outputs almost the same text, but with any
+non-symbolic stack traces converted to symbolic stack traces that contain
+function names, file names, and line numbers.
+
+Options shared by all commands:
+${_argParser.usage}
+
+Options specific to the translate command:
+${_translateParser.usage}''';
+
+final String _findUsage = '''
+Usage: convert_stack_traces find [options] <PC> ...
+
+The find command looks up program counter (PC) addresses, either given as
+arguments on the command line or via the -l option. For each PC address,
+it outputs the file, function, and line number information if found.
+
+PC addresses are expected to be hexadecimal numbers with or without an initial
+"0x" marker.
+
+The -l option may be provided multiple times, or a single use of the -l option
+may be given multiple arguments separated by commas.
+
+By default, PC addresses are assumed to be virtual addresses valid for the
+given debugging information. To find absolute PC addresses, use both the
+--vm_start and --isolate_start arguments tp provide the absolute addresses of
+the VM and isolate instructions sections.
+
+Options shared by all commands:
+${_argParser.usage}
+
+Options specific to the find command:
+${_findParser.usage}''';
+
+final _usages = <String, String>{
+  null: _mainUsage,
+  '': _mainUsage,
+  'help': _helpUsage,
+  'translate': _translateUsage,
+  'find': _findUsage,
+};
+
+const int _badUsageExitCode = 1;
+
+void errorWithUsage(String message, {String command}) {
+  print("Error: $message.\n");
+  print(_usages[command]);
+  io.exitCode = _badUsageExitCode;
+}
+
+void help(ArgResults options) {
+  void usageError(String message) => errorWithUsage(message, command: 'help');
+
+  switch (options.rest.length) {
+    case 0:
+      return print(_usages['help']);
+    case 1:
+      {
+        final usage = _usages[options.rest.first];
+        if (usage != null) return print(usage);
+        return usageError('invalid command ${options.rest.first}');
+      }
+    default:
+      return usageError('too many arguments');
+  }
+}
+
+void find(ArgResults options) {
+  void usageError(String message) => errorWithUsage(message, command: 'find');
+  int convertAddress(String s) => int.tryParse(s, radix: 16);
+
+  if (options['debug'] == null) {
+    return usageError('must provide -d/--debug');
+  }
+  final dwarf = Dwarf.fromFile(options['debug']);
+  final verbose = options['verbose'];
+
+  int vm_start;
+  if (options['vm_start'] != null) {
+    vm_start = convertAddress(options['vm_start']);
+    if (vm_start == null) {
+      return usageError('could not parse VM start address '
+          '${options['vm_start']}');
+    }
+  }
+
+  int isolate_start;
+  if (options['isolate_start'] != null) {
+    isolate_start = convertAddress(options['isolate_start']);
+    if (isolate_start == null) {
+      return usageError('could not parse isolate start address '
+          '${options['isolate_start']}');
+    }
+  }
+
+  if ((vm_start == null) != (isolate_start == null)) {
+    return usageError("need both VM start and isolate start");
+  }
+
+  final locations = <int>[];
+  for (final s in options['location'] + options.rest) {
+    final location = convertAddress(s);
+    if (location == null) {
+      return usageError('could not parse PC address ${s}');
+    }
+    locations.add(location);
+  }
+  if (locations.isEmpty) return usageError('no PC addresses to find');
+
+  // Used to approximate how many hex digits we should have in the final output.
+  final maxDigits = options['location']
+      .fold(0, ((acc, s) => s.startsWith('0x') ? s.length - 2 : s.length));
+
+  Iterable<int> addresses = locations;
+  if (vm_start != null) {
+    final header = StackTraceHeader(isolate_start, vm_start);
+    addresses =
+        locations.map((l) => header.offsetOf(l).virtualAddressIn(dwarf));
+  }
+  for (final addr in addresses) {
+    final frames = dwarf
+        .callInfoFor(addr, includeInternalFrames: verbose)
+        ?.map((CallInfo c) => "  " + c.toString());
+    final addrString = addr > 0
+        ? "0x" + addr.toRadixString(16).padLeft(maxDigits, '0')
+        : addr.toString();
+    print("For virtual address ${addrString}:");
+    if (frames == null) {
+      print("  Invalid virtual address.");
+    } else if (frames.isEmpty) {
+      print("  Not a call from user or library code.");
+    } else {
+      frames.forEach(print);
+    }
+  }
+}
+
+Future<void> translate(ArgResults options) async {
+  void usageError(String message) =>
+      errorWithUsage(message, command: 'translate');
+
+  if (options['debug'] == null) {
+    return usageError('must provide -d/--debug');
+  }
+  final dwarf =
+      Dwarf.fromFile(path.canonicalize(path.normalize(options['debug'])));
+
+  final verbose = options['verbose'];
+  final output = options['output'] != null
+      ? io.File(path.canonicalize(path.normalize(options['output'])))
+          .openWrite()
+      : io.stdout;
+  final input = options['input'] != null
+      ? io.File(path.canonicalize(path.normalize(options['input']))).openRead()
+      : io.stdin;
+
+  final convertedStream = input
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: verbose))
+      .map((s) => s + "\n")
+      .transform(utf8.encoder);
+
+  await output.addStream(convertedStream);
+  await output.flush();
+  await output.close();
+}
+
+Future<void> main(List<String> arguments) async {
+  ArgResults options;
+
+  try {
+    options = _argParser.parse(arguments);
+  } on FormatException catch (e) {
+    return errorWithUsage(e.message);
+  }
+
+  if (options['help']) return print(_usages[options.command?.name]);
+  if (options.command == null) return errorWithUsage('no command provided');
+
+  switch (options.command.name) {
+    case 'help':
+      return help(options.command);
+    case 'find':
+      return find(options.command);
+    case 'translate':
+      return await translate(options.command);
+  }
+}
diff --git a/pkg/native_stack_traces/lib/native_stack_traces.dart b/pkg/native_stack_traces/lib/native_stack_traces.dart
new file mode 100644
index 0000000..ad8e6a9
--- /dev/null
+++ b/pkg/native_stack_traces/lib/native_stack_traces.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2020, 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.
+
+export 'src/convert.dart'
+    show collectPCOffsets, DwarfStackTraceDecoder, StackTraceHeader;
+export 'src/dwarf.dart' show CallInfo, Dwarf, PCOffset;
diff --git a/pkg/native_stack_traces/lib/src/convert.dart b/pkg/native_stack_traces/lib/src/convert.dart
new file mode 100644
index 0000000..86eebaa
--- /dev/null
+++ b/pkg/native_stack_traces/lib/src/convert.dart
@@ -0,0 +1,144 @@
+// 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";
+import "dart:math";
+
+import "dwarf.dart";
+
+String _stackTracePiece(CallInfo call, int depth) => "#${depth}\t${call}";
+
+// A pattern matching the last line of the non-symbolic stack trace header.
+//
+// Currently, this happens to include the only pieces of information from the
+// stack trace header we need: the absolute addresses during program
+// execution of the start of the isolate and VM instructions.
+final _headerEndRE =
+    RegExp(r'isolate_instructions: ([\da-f]+) vm_instructions: ([\da-f]+)$');
+
+// Parses instructions section information into a new [StackTraceHeader].
+//
+// Returns a new [StackTraceHeader] if [line] contains the needed header
+// information, otherwise returns `null`.
+StackTraceHeader _parseInstructionsLine(String line) {
+  final match = _headerEndRE.firstMatch(line);
+  if (match == null) return null;
+  final isolateAddr = int.parse(match[1], radix: 16);
+  final vmAddr = int.parse(match[2], radix: 16);
+  return StackTraceHeader(isolateAddr, vmAddr);
+}
+
+/// Header information for a non-symbolic Dart stack trace.
+class StackTraceHeader {
+  final int _isolateStart;
+  final int _vmStart;
+
+  StackTraceHeader(this._isolateStart, this._vmStart);
+
+  /// The [PCOffset] for the given absolute program counter address.
+  PCOffset offsetOf(int address) {
+    final isolateOffset = address - _isolateStart;
+    int vmOffset = address - _vmStart;
+    if (vmOffset > 0 && vmOffset == min(vmOffset, isolateOffset)) {
+      return PCOffset(vmOffset, InstructionsSection.vm);
+    } else {
+      return PCOffset(isolateOffset, InstructionsSection.isolate);
+    }
+  }
+}
+
+/// A Dart DWARF stack trace contains up to four pieces of information:
+///   - The zero-based frame index from the top of the stack.
+///   - The absolute address of the program counter.
+///   - The virtual address of the program counter, if the snapshot was
+///     loaded as a dynamic library, otherwise not present.
+///   - The path to the snapshot, if it was loaded as a dynamic library,
+///     otherwise the string "<unknown>".
+final _traceLineRE =
+    RegExp(r'    #(\d{2}) abs ([\da-f]+)(?: virt ([\da-f]+))? (.*)$');
+
+PCOffset _retrievePCOffset(StackTraceHeader header, Match match) {
+  if (header == null || match == null) return null;
+  final address = int.tryParse(match[2], radix: 16);
+  return header.offsetOf(address);
+}
+
+/// The [PCOffset]s for frames of the non-symbolic stack traces in [lines].
+Iterable<PCOffset> collectPCOffsets(Iterable<String> lines) sync* {
+  StackTraceHeader header;
+  for (var line in lines) {
+    final parsedHeader = _parseInstructionsLine(line);
+    if (parsedHeader != null) {
+      header = parsedHeader;
+      continue;
+    }
+    final match = _traceLineRE.firstMatch(line);
+    final offset = _retrievePCOffset(header, match);
+    if (offset != null) yield offset;
+  }
+}
+
+/// A [StreamTransformer] that scans lines for non-symbolic stack traces.
+///
+/// A [NativeStackTraceDecoder] scans a stream of lines for non-symbolic
+/// stack traces containing only program counter address information. Such
+/// stack traces are generated by the VM when executing a snapshot compiled
+/// with `--dwarf-stack-traces`.
+///
+/// The transformer assumes that there may be text preceding the stack frames
+/// on individual lines, like in log files, but that there is no trailing text.
+/// For each stack frame found, the transformer attempts to locate a function
+/// name, file name and line number using the provided DWARF information.
+///
+/// If no information is found, or the line is not a stack frame, then the line
+/// will be unchanged in the output stream.
+///
+/// If the located information corresponds to Dart internals and
+/// [includeInternalFrames] is false, then the output stream contains no
+/// entries for the line.
+///
+/// Otherwise, the output stream contains one or more lines with symbolic stack
+/// frames for the given non-symbolic stack frame line. Multiple symbolic stack
+/// frame lines are generated when the PC address corresponds to inlined code.
+/// In the output stream, each symbolic stack frame is prefixed by the non-stack
+/// frame portion of the original line.
+class DwarfStackTraceDecoder extends StreamTransformerBase<String, String> {
+  final Dwarf _dwarf;
+  final bool _includeInternalFrames;
+
+  DwarfStackTraceDecoder(this._dwarf, {bool includeInternalFrames = false})
+      : _includeInternalFrames = includeInternalFrames;
+
+  Stream<String> bind(Stream<String> stream) async* {
+    int depth = 0;
+    StackTraceHeader header;
+    await for (final line in stream) {
+      final parsedHeader = _parseInstructionsLine(line);
+      if (parsedHeader != null) {
+        header = parsedHeader;
+        depth = 0;
+        yield line;
+        continue;
+      }
+      // If at any point we can't get appropriate information for the current
+      // line as a stack trace line, then just pass the line through unchanged.
+      final lineMatch = _traceLineRE.firstMatch(line);
+      final offset = _retrievePCOffset(header, lineMatch);
+      final callInfo = offset?.callInfoFrom(_dwarf,
+          includeInternalFrames: _includeInternalFrames);
+      if (callInfo == null) {
+        yield line;
+        continue;
+      }
+      // No lines to output (as this corresponds to Dart internals).
+      if (callInfo.isEmpty) continue;
+      // Output the lines for the symbolic frame with the prefix found on the
+      // original non-symbolic frame line.
+      final prefix = line.substring(0, lineMatch.start);
+      for (final call in callInfo) {
+        yield prefix + _stackTracePiece(call, depth++);
+      }
+    }
+  }
+}
diff --git a/pkg/native_stack_traces/lib/src/dwarf.dart b/pkg/native_stack_traces/lib/src/dwarf.dart
new file mode 100644
index 0000000..751301c
--- /dev/null
+++ b/pkg/native_stack_traces/lib/src/dwarf.dart
@@ -0,0 +1,1123 @@
+// 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:math';
+
+import 'elf.dart';
+import 'reader.dart';
+
+int _initialLengthValue(Reader reader) {
+  final length = reader.readBytes(4);
+  if (length == 0xffffffff) {
+    throw FormatException("64-bit DWARF format detected");
+  } else if (length > 0xfffffff0) {
+    throw FormatException("Unrecognized reserved initial length value");
+  }
+  return length;
+}
+
+enum _Tag {
+  compileUnit,
+  inlinedSubroutine,
+  subprogram,
+}
+
+const _tags = <int, _Tag>{
+  0x11: _Tag.compileUnit,
+  0x1d: _Tag.inlinedSubroutine,
+  0x2e: _Tag.subprogram,
+};
+
+const _tagStrings = <_Tag, String>{
+  _Tag.compileUnit: "DW_TAG_compile_unit",
+  _Tag.inlinedSubroutine: "DW_TAG_inlined_subroutine",
+  _Tag.subprogram: "DW_TAG_subroutine",
+};
+
+enum _AttributeName {
+  abstractOrigin,
+  callColumn,
+  callFile,
+  callLine,
+  compilationDirectory,
+  declarationColumn,
+  declarationFile,
+  declarationLine,
+  highProgramCounter,
+  lowProgramCounter,
+  inline,
+  name,
+  producer,
+  sibling,
+  statementList,
+}
+
+const _attributeNames = <int, _AttributeName>{
+  0x01: _AttributeName.sibling,
+  0x03: _AttributeName.name,
+  0x10: _AttributeName.statementList,
+  0x11: _AttributeName.lowProgramCounter,
+  0x12: _AttributeName.highProgramCounter,
+  0x1b: _AttributeName.compilationDirectory,
+  0x20: _AttributeName.inline,
+  0x25: _AttributeName.producer,
+  0x31: _AttributeName.abstractOrigin,
+  0x39: _AttributeName.declarationColumn,
+  0x3a: _AttributeName.declarationFile,
+  0x3b: _AttributeName.declarationLine,
+  0x57: _AttributeName.callColumn,
+  0x58: _AttributeName.callFile,
+  0x59: _AttributeName.callLine,
+};
+
+const _attributeNameStrings = <_AttributeName, String>{
+  _AttributeName.sibling: "DW_AT_sibling",
+  _AttributeName.name: "DW_AT_name",
+  _AttributeName.statementList: "DW_AT_stmt_list",
+  _AttributeName.lowProgramCounter: "DW_AT_low_pc",
+  _AttributeName.highProgramCounter: "DW_AT_high_pc",
+  _AttributeName.compilationDirectory: "DW_AT_comp_dir",
+  _AttributeName.inline: "DW_AT_inline",
+  _AttributeName.producer: "DW_AT_producer",
+  _AttributeName.abstractOrigin: "DW_AT_abstract_origin",
+  _AttributeName.declarationColumn: "DW_AT_decl_column",
+  _AttributeName.declarationFile: "DW_AT_decl_file",
+  _AttributeName.declarationLine: "DW_AT_decl_line",
+  _AttributeName.callColumn: "DW_AT_call_column",
+  _AttributeName.callFile: "DW_AT_call_file",
+  _AttributeName.callLine: "DW_AT_call_line",
+};
+
+enum _AttributeForm {
+  address,
+  constant,
+  reference4,
+  sectionOffset,
+  string,
+}
+
+const _attributeForms = <int, _AttributeForm>{
+  0x01: _AttributeForm.address,
+  0x08: _AttributeForm.string,
+  0x0f: _AttributeForm.constant,
+  0x13: _AttributeForm.reference4,
+  0x17: _AttributeForm.sectionOffset,
+};
+
+const _attributeFormStrings = <_AttributeForm, String>{
+  _AttributeForm.address: "DW_FORM_addr",
+  _AttributeForm.string: "DW_FORM_string",
+  _AttributeForm.constant: "DW_FORM_udata",
+  _AttributeForm.reference4: "DW_FORM_ref4",
+  _AttributeForm.sectionOffset: "DW_FORM_sec_offset",
+};
+
+class _Attribute {
+  final _AttributeName name;
+  final _AttributeForm form;
+
+  _Attribute(this.name, this.form);
+}
+
+class _Abbreviation {
+  final Reader reader;
+
+  _Tag tag;
+  bool children;
+  List<_Attribute> attributes;
+
+  _Abbreviation.fromReader(this.reader) {
+    _read();
+  }
+
+  // Constants from the DWARF specification.
+  static const _DW_CHILDREN_no = 0x00;
+  static const _DW_CHILDREN_yes = 0x01;
+
+  bool _readChildren() {
+    switch (reader.readByte()) {
+      case _DW_CHILDREN_no:
+        return false;
+      case _DW_CHILDREN_yes:
+        return true;
+      default:
+        throw FormatException("Expected DW_CHILDREN_no or DW_CHILDREN_yes");
+    }
+  }
+
+  void _read() {
+    reader.reset();
+    final tagInt = reader.readLEB128EncodedInteger();
+    if (!_tags.containsKey(tagInt)) {
+      throw FormatException("Unexpected DW_TAG value 0x${paddedHex(tagInt)}");
+    }
+    tag = _tags[tagInt];
+    children = _readChildren();
+    attributes = <_Attribute>[];
+    while (!reader.done) {
+      final nameInt = reader.readLEB128EncodedInteger();
+      final formInt = reader.readLEB128EncodedInteger();
+      if (nameInt == 0 && formInt == 0) {
+        break;
+      }
+      if (!_attributeNames.containsKey(nameInt)) {
+        throw FormatException("Unexpected DW_AT value 0x${paddedHex(nameInt)}");
+      }
+      if (!_attributeForms.containsKey(formInt)) {
+        throw FormatException(
+            "Unexpected DW_FORM value 0x${paddedHex(formInt)}");
+      }
+      attributes
+          .add(_Attribute(_attributeNames[nameInt], _attributeForms[formInt]));
+    }
+  }
+
+  @override
+  String toString() {
+    var ret = "    Tag: ${_tagStrings[tag]}\n"
+        "    Children: ${children ? "DW_CHILDREN_yes" : "DW_CHILDREN_no"}\n"
+        "    Attributes:\n";
+    for (final attribute in attributes) {
+      ret += "      ${_attributeNameStrings[attribute.name]}: "
+          "${_attributeFormStrings[attribute.form]}\n";
+    }
+    return ret;
+  }
+}
+
+class _AbbreviationsTable {
+  final Reader reader;
+
+  Map<int, _Abbreviation> _abbreviations;
+
+  _AbbreviationsTable.fromReader(this.reader) {
+    _read();
+  }
+
+  bool containsKey(int code) => _abbreviations.containsKey(code);
+  _Abbreviation operator [](int code) => _abbreviations[code];
+
+  void _read() {
+    reader.reset();
+    _abbreviations = <int, _Abbreviation>{};
+    while (!reader.done) {
+      final code = reader.readLEB128EncodedInteger();
+      // Code of 0 marks end of abbreviations table.
+      if (code == 0) {
+        break;
+      }
+      final abbrev = _Abbreviation.fromReader(reader.shrink(reader.offset));
+      _abbreviations[code] = abbrev;
+      reader.seek(abbrev.reader.offset);
+    }
+  }
+
+  @override
+  String toString() =>
+      "Abbreviations table:\n\n" +
+      _abbreviations.keys
+          .map((k) => "  Abbreviation $k:\n" + _abbreviations[k].toString())
+          .join("\n");
+}
+
+/// A DWARF Debug Information Entry (DIE).
+class DebugInformationEntry {
+  final Reader reader;
+  final CompilationUnit compilationUnit;
+
+  // The index of the entry in the abbreviation table for this DIE. If 0, then
+  // this is not actually a full DIE, but an end marker for a list of entries.
+  int code;
+  Map<_Attribute, Object> attributes;
+  List<DebugInformationEntry> children;
+
+  DebugInformationEntry.fromReader(this.reader, this.compilationUnit) {
+    _read();
+  }
+
+  Object _readAttribute(_Attribute attribute) {
+    switch (attribute.form) {
+      case _AttributeForm.string:
+        return reader.readNullTerminatedString();
+      case _AttributeForm.address:
+        return reader.readBytes(compilationUnit.addressSize);
+      case _AttributeForm.sectionOffset:
+        return reader.readBytes(4);
+      case _AttributeForm.constant:
+        return reader.readLEB128EncodedInteger();
+      case _AttributeForm.reference4:
+        return reader.readBytes(4);
+    }
+    return null;
+  }
+
+  String _nameOfOrigin(int offset) {
+    if (!compilationUnit.referenceTable.containsKey(offset)) {
+      throw ArgumentError(
+          "${paddedHex(offset)} is not the offset of an abbreviated unit");
+    }
+    final origin = compilationUnit.referenceTable[offset];
+    assert(origin.containsKey(_AttributeName.name));
+    return origin[_AttributeName.name] as String;
+  }
+
+  String _attributeValueToString(_Attribute attribute, Object value) {
+    switch (attribute.form) {
+      case _AttributeForm.string:
+        return value as String;
+      case _AttributeForm.address:
+        return paddedHex(value as int, compilationUnit.addressSize);
+      case _AttributeForm.sectionOffset:
+        return paddedHex(value as int, 4);
+      case _AttributeForm.constant:
+        return value.toString();
+      case _AttributeForm.reference4:
+        return paddedHex(value as int, 4) +
+            " (origin: ${_nameOfOrigin(value as int)})";
+    }
+    return "<unknown>";
+  }
+
+  int get _unitOffset => reader.start - compilationUnit.reader.start;
+
+  void _read() {
+    reader.reset();
+    code = reader.readLEB128EncodedInteger();
+    // DIEs with an abbreviation table index of 0 are list end markers.
+    if (code == 0) {
+      return;
+    }
+    if (!compilationUnit.abbreviations.containsKey(code)) {
+      throw FormatException("Unknown abbreviation code 0x${paddedHex(code)}");
+    }
+    final abbreviation = compilationUnit.abbreviations[code];
+    attributes = <_Attribute, Object>{};
+    for (final attribute in abbreviation.attributes) {
+      attributes[attribute] = _readAttribute(attribute);
+    }
+    compilationUnit.referenceTable[_unitOffset] = this;
+    if (!abbreviation.children) return;
+    children = <DebugInformationEntry>[];
+    while (!reader.done) {
+      final child = DebugInformationEntry.fromReader(
+          reader.shrink(reader.offset), compilationUnit);
+      reader.seek(child.reader.offset);
+      if (child.code == 0) {
+        break;
+      }
+      children.add(child);
+    }
+  }
+
+  _Attribute _attributeForName(_AttributeName name) => attributes.keys
+      .firstWhere((_Attribute k) => k.name == name, orElse: () => null);
+
+  bool containsKey(_AttributeName name) => _attributeForName(name) != null;
+
+  Object operator [](_AttributeName name) {
+    final key = _attributeForName(name);
+    if (key == null) {
+      return null;
+    }
+    return attributes[key];
+  }
+
+  DebugInformationEntry get abstractOrigin {
+    final index = this[_AttributeName.abstractOrigin] as int;
+    return compilationUnit.referenceTable[index];
+  }
+
+  int get lowPC => this[_AttributeName.lowProgramCounter] as int;
+
+  int get highPC => this[_AttributeName.highProgramCounter] as int;
+
+  bool containsPC(int virtualAddress) =>
+      lowPC != null && lowPC <= virtualAddress && virtualAddress < highPC;
+
+  String get name => this[_AttributeName.name] as String;
+
+  int get callFileIndex => this[_AttributeName.callFile] as int;
+
+  int get callLine => this[_AttributeName.callLine] as int;
+
+  _Tag get tag => compilationUnit.abbreviations[code].tag;
+
+  List<CallInfo> callInfo(int address, LineNumberProgram lineNumberProgram) {
+    String callFilename(int index) => lineNumberProgram.filesInfo[index].name;
+    if (!containsPC(address)) {
+      return null;
+    }
+    final inlined = tag == _Tag.inlinedSubroutine;
+    for (final unit in children) {
+      final callInfo = unit.callInfo(address, lineNumberProgram);
+      if (callInfo == null) {
+        continue;
+      }
+      if (tag != _Tag.compileUnit) {
+        callInfo.add(CallInfo(
+            function: abstractOrigin.name,
+            inlined: inlined,
+            filename: callFilename(unit.callFileIndex),
+            line: unit.callLine));
+      }
+      return callInfo;
+    }
+    if (tag == _Tag.compileUnit) {
+      return null;
+    }
+    final filename = lineNumberProgram.filename(address);
+    final line = lineNumberProgram.lineNumber(address);
+    return [
+      CallInfo(
+          function: abstractOrigin.name,
+          inlined: inlined,
+          filename: filename,
+          line: line)
+    ];
+  }
+
+  @override
+  String toString() {
+    var ret =
+        "Abbreviated unit (code $code, offset ${paddedHex(_unitOffset)}):\n";
+    for (final attribute in attributes.keys) {
+      ret += "  ${_attributeNameStrings[attribute.name]} => "
+          "${_attributeValueToString(attribute, attributes[attribute])}\n";
+    }
+    if (children == null || children.isEmpty) {
+      ret += "Has no children.\n\n";
+      return ret;
+    }
+    ret += "Has ${children.length} " +
+        (children.length == 1 ? "child" : "children") +
+        "\n\n";
+    for (int i = 0; i < children.length; i++) {
+      ret += "Child ${i} of unit at offset ${paddedHex(_unitOffset)}:\n";
+      ret += children[i].toString();
+    }
+    return ret;
+  }
+}
+
+/// A class representing a DWARF compilation unit.
+class CompilationUnit {
+  final Reader reader;
+  final Dwarf dwarf;
+
+  int size;
+  int version;
+  int abbreviationOffset;
+  int addressSize;
+  List<DebugInformationEntry> contents;
+  Map<int, DebugInformationEntry> referenceTable;
+
+  CompilationUnit.fromReader(this.reader, this.dwarf) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    size = _initialLengthValue(reader);
+    // An empty unit is an ending marker.
+    if (size == 0) {
+      return;
+    }
+    version = reader.readBytes(2);
+    if (version != 2) {
+      throw FormatException("Expected DWARF version 2, got $version");
+    }
+    abbreviationOffset = reader.readBytes(4);
+    if (!dwarf.abbreviationTables.containsKey(abbreviationOffset)) {
+      throw FormatException("No abbreviation table found for offset "
+          "0x${paddedHex(abbreviationOffset, 4)}");
+    }
+    addressSize = reader.readByte();
+    contents = <DebugInformationEntry>[];
+    referenceTable = <int, DebugInformationEntry>{};
+    while (!reader.done) {
+      final subunit =
+          DebugInformationEntry.fromReader(reader.shrink(reader.offset), this);
+      reader.seek(subunit.reader.offset);
+      if (subunit.code == 0) {
+        break;
+      }
+      assert(subunit.tag == _Tag.compileUnit);
+      contents.add(subunit);
+    }
+  }
+
+  Iterable<CallInfo> callInfo(int address) {
+    for (final unit in contents) {
+      final lineNumberProgram =
+          dwarf.lineNumberInfo[unit[_AttributeName.statementList]];
+      final callInfo = unit.callInfo(address, lineNumberProgram);
+      if (callInfo != null) {
+        return callInfo;
+      }
+    }
+    return null;
+  }
+
+  _AbbreviationsTable get abbreviations =>
+      dwarf.abbreviationTables[abbreviationOffset];
+
+  @override
+  String toString() =>
+      "Compilation unit:\n"
+          "  Version: $version\n"
+          "  Abbreviation offset: ${paddedHex(abbreviationOffset, 4)}\n"
+          "  Address size: $addressSize\n\n" +
+      contents.map((DebugInformationEntry u) => u.toString()).join();
+}
+
+/// A class representing a DWARF `.debug_info` section.
+class DebugInfo {
+  final Reader reader;
+  final Dwarf dwarf;
+
+  List<CompilationUnit> units;
+
+  DebugInfo.fromReader(this.reader, this.dwarf) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    units = <CompilationUnit>[];
+    while (!reader.done) {
+      final unit =
+          CompilationUnit.fromReader(reader.shrink(reader.offset), dwarf);
+      reader.seek(unit.reader.offset);
+      if (unit.size == 0) {
+        break;
+      }
+      units.add(unit);
+    }
+  }
+
+  Iterable<CallInfo> callInfo(int address) {
+    for (final unit in units) {
+      final callInfo = unit.callInfo(address);
+      if (callInfo != null) {
+        return callInfo;
+      }
+    }
+    return null;
+  }
+
+  String toString() =>
+      "Debug information:\n\n" +
+      units.map((CompilationUnit u) => u.toString()).join();
+}
+
+class FileEntry {
+  final Reader reader;
+
+  String name;
+  int directoryIndex;
+  int lastModified;
+  int size;
+
+  FileEntry.fromReader(this.reader) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    name = reader.readNullTerminatedString();
+    if (name == "") {
+      return;
+    }
+    directoryIndex = reader.readLEB128EncodedInteger();
+    lastModified = reader.readLEB128EncodedInteger();
+    size = reader.readLEB128EncodedInteger();
+  }
+
+  @override
+  String toString() => "File name: $name\n"
+      "  Directory index: $directoryIndex\n"
+      "  Last modified: $lastModified\n"
+      "  Size: $size\n";
+}
+
+class FileInfo {
+  final Reader reader;
+
+  Map<int, FileEntry> _files;
+
+  FileInfo.fromReader(this.reader) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    _files = <int, FileEntry>{};
+    int index = 1;
+    while (!reader.done) {
+      final file = FileEntry.fromReader(reader.shrink(reader.offset));
+      reader.seek(file.reader.offset);
+      // An empty null-terminated string marks the table end.
+      if (file.name == "") {
+        break;
+      }
+      _files[index] = file;
+      index++;
+    }
+  }
+
+  bool containsKey(int index) => _files.containsKey(index);
+  FileEntry operator [](int index) => _files[index];
+
+  void writeToStringBuffer(StringBuffer buffer) {
+    if (_files.isEmpty) {
+      buffer.writeln("No file information.");
+      return;
+    }
+
+    final indexHeader = "Entry";
+    final dirIndexHeader = "Dir";
+    final modifiedHeader = "Time";
+    final sizeHeader = "Size";
+    final nameHeader = "Name";
+
+    final indexStrings = _files
+        .map((int i, FileEntry f) => MapEntry<int, String>(i, i.toString()));
+    final dirIndexStrings = _files.map((int i, FileEntry f) =>
+        MapEntry<int, String>(i, f.directoryIndex.toString()));
+    final modifiedStrings = _files.map((int i, FileEntry f) =>
+        MapEntry<int, String>(i, f.lastModified.toString()));
+    final sizeStrings = _files.map(
+        (int i, FileEntry f) => MapEntry<int, String>(i, f.size.toString()));
+
+    final maxIndexLength = indexStrings.values
+        .fold(indexHeader.length, (int acc, String s) => max(acc, s.length));
+    final maxDirIndexLength = dirIndexStrings.values
+        .fold(dirIndexHeader.length, (int acc, String s) => max(acc, s.length));
+    final maxModifiedLength = modifiedStrings.values
+        .fold(modifiedHeader.length, (int acc, String s) => max(acc, s.length));
+    final maxSizeLength = sizeStrings.values
+        .fold(sizeHeader.length, (int acc, String s) => max(acc, s.length));
+
+    buffer.writeln("File information:");
+
+    buffer..write(" ")..write(indexHeader.padRight(maxIndexLength));
+    buffer..write(" ")..write(dirIndexHeader.padRight(maxDirIndexLength));
+    buffer..write(" ")..write(modifiedHeader.padRight(maxModifiedLength));
+    buffer..write(" ")..write(sizeHeader.padRight(maxSizeLength));
+    buffer
+      ..write(" ")
+      ..writeln(nameHeader);
+
+    for (final index in _files.keys) {
+      buffer..write(" ")..write(indexStrings[index].padRight(maxIndexLength));
+      buffer
+        ..write(" ")
+        ..write(dirIndexStrings[index].padRight(maxDirIndexLength));
+      buffer
+        ..write(" ")
+        ..write(modifiedStrings[index].padRight(maxModifiedLength));
+      buffer..write(" ")..write(sizeStrings[index].padRight(maxSizeLength));
+      buffer
+        ..write(" ")
+        ..writeln(_files[index].name);
+    }
+  }
+
+  @override
+  String toString() {
+    var buffer = StringBuffer();
+    writeToStringBuffer(buffer);
+    return buffer.toString();
+  }
+}
+
+class LineNumberState {
+  final defaultIsStatement;
+
+  int address;
+  int fileIndex;
+  int line;
+  int column;
+  bool isStatement;
+  bool basicBlock;
+  bool endSequence;
+
+  LineNumberState(this.defaultIsStatement) {
+    reset();
+  }
+
+  void reset() {
+    address = 0;
+    fileIndex = 1;
+    line = 1;
+    column = 0;
+    isStatement = defaultIsStatement;
+    basicBlock = false;
+    endSequence = false;
+  }
+
+  LineNumberState clone() {
+    final clone = LineNumberState(defaultIsStatement);
+    clone.address = address;
+    clone.fileIndex = fileIndex;
+    clone.line = line;
+    clone.column = column;
+    clone.isStatement = isStatement;
+    clone.basicBlock = basicBlock;
+    clone.endSequence = endSequence;
+    return clone;
+  }
+
+  String toString() => "Current line number state machine registers:\n"
+      "  Address: ${paddedHex(address)}\n"
+      "  File index: $fileIndex\n"
+      "  Line number: $line\n"
+      "  Column number: $column\n"
+      "  Is ${isStatement ? "" : "not "}a statement.\n"
+      "  Is ${basicBlock ? "" : "not "}at the beginning of a basic block.\n"
+      "  Is ${endSequence ? "" : "not "}just after the end of a sequence.\n";
+}
+
+/// A class representing a DWARF line number program.
+class LineNumberProgram {
+  final Reader reader;
+
+  int size;
+  int version;
+  int headerLength;
+  int minimumInstructionLength;
+  bool defaultIsStatement;
+  int lineBase;
+  int lineRange;
+  int opcodeBase;
+  Map<int, int> standardOpcodeLengths;
+  List<String> includeDirectories;
+  FileInfo filesInfo;
+  List<LineNumberState> calculatedMatrix;
+  Map<int, LineNumberState> cachedLookups;
+
+  LineNumberProgram.fromReader(this.reader) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    size = _initialLengthValue(reader);
+    if (size == 0) {
+      return;
+    }
+    version = reader.readBytes(2);
+    headerLength = reader.readBytes(4);
+    minimumInstructionLength = reader.readByte();
+    switch (reader.readByte()) {
+      case 0:
+        defaultIsStatement = false;
+        break;
+      case 1:
+        defaultIsStatement = true;
+        break;
+      default:
+        throw FormatException("Unexpected value for default_is_stmt");
+    }
+    lineBase = reader.readByte(signed: true);
+    lineRange = reader.readByte();
+    opcodeBase = reader.readByte();
+    standardOpcodeLengths = <int, int>{};
+    // Standard opcode numbering starts at 1.
+    for (int i = 1; i < opcodeBase; i++) {
+      standardOpcodeLengths[i] = reader.readLEB128EncodedInteger();
+    }
+    includeDirectories = <String>[];
+    while (!reader.done) {
+      final directory = reader.readNullTerminatedString();
+      if (directory == "") {
+        break;
+      }
+      includeDirectories.add(directory);
+    }
+    filesInfo = FileInfo.fromReader(reader.shrink(reader.offset));
+    reader.seek(filesInfo.reader.offset);
+    // Header length doesn't include the 4-byte length or 2-byte version fields.
+    assert(reader.offset == headerLength + 6);
+    calculatedMatrix = <LineNumberState>[];
+    final currentState = LineNumberState(defaultIsStatement);
+    while (!reader.done) {
+      _applyNextOpcode(currentState);
+    }
+    if (calculatedMatrix.isEmpty) {
+      throw FormatException("No line number information generated by program");
+    }
+    // Set the offset to the declared size in case of padding.  The declared
+    // size does not include the size of the size field itself.
+    reader.seek(size + 4);
+    cachedLookups = <int, LineNumberState>{};
+  }
+
+  void _addStateToMatrix(LineNumberState state) {
+    calculatedMatrix.add(state.clone());
+  }
+
+  void _applyNextOpcode(LineNumberState state) {
+    void applySpecialOpcode(int opcode) {
+      final adjustedOpcode = opcode - opcodeBase;
+      state.address = adjustedOpcode ~/ lineRange;
+      state.line += lineBase + (adjustedOpcode % lineRange);
+    }
+
+    final opcode = reader.readByte();
+    if (opcode >= opcodeBase) {
+      return applySpecialOpcode(opcode);
+    }
+    switch (opcode) {
+      case 0: // Extended opcodes
+        final extendedLength = reader.readByte();
+        final subOpcode = reader.readByte();
+        switch (subOpcode) {
+          case 0:
+            throw FormatException(
+                "Attempted to execute extended opcode ${subOpcode} (padding?)");
+          case 1: // DW_LNE_end_sequence
+            state.endSequence = true;
+            _addStateToMatrix(state);
+            state.reset();
+            break;
+          case 2: // DW_LNE_set_address
+            // The length includes the subopcode.
+            final valueLength = extendedLength - 1;
+            assert(valueLength == 4 || valueLength == 8);
+            final newAddress = reader.readBytes(valueLength);
+            state.address = newAddress;
+            break;
+          case 3: // DW_LNE_define_file
+            throw FormatException("DW_LNE_define_file instruction not handled");
+          default:
+            throw FormatException(
+                "Extended opcode ${subOpcode} not in DWARF 2");
+        }
+        break;
+      case 1: // DW_LNS_copy
+        _addStateToMatrix(state);
+        state.basicBlock = false;
+        break;
+      case 2: // DW_LNS_advance_pc
+        final increment = reader.readLEB128EncodedInteger();
+        state.address += minimumInstructionLength * increment;
+        break;
+      case 3: // DW_LNS_advance_line
+        state.line += reader.readLEB128EncodedInteger(signed: true);
+        break;
+      case 4: // DW_LNS_set_file
+        state.fileIndex = reader.readLEB128EncodedInteger();
+        break;
+      case 5: // DW_LNS_set_column
+        state.column = reader.readLEB128EncodedInteger();
+        break;
+      case 6: // DW_LNS_negate_stmt
+        state.isStatement = !state.isStatement;
+        break;
+      case 7: // DW_LNS_set_basic_block
+        state.basicBlock = true;
+        break;
+      case 8: // DW_LNS_const_add_pc
+        applySpecialOpcode(255);
+        break;
+      case 9: // DW_LNS_fixed_advance_pc
+        state.address += reader.readBytes(2);
+        break;
+      default:
+        throw FormatException("Standard opcode ${opcode} not in DWARF 2");
+    }
+  }
+
+  bool containsKey(int address) {
+    assert(calculatedMatrix.last.endSequence);
+    return address >= calculatedMatrix.first.address &&
+        address < calculatedMatrix.last.address;
+  }
+
+  LineNumberState operator [](int address) {
+    if (cachedLookups.containsKey(address)) {
+      return cachedLookups[address];
+    }
+    if (!containsKey(address)) {
+      return null;
+    }
+    // Since the addresses are generated in increasing order, we can do a
+    // binary search to find the right state.
+    assert(calculatedMatrix != null && calculatedMatrix.isNotEmpty);
+    var minIndex = 0;
+    var maxIndex = calculatedMatrix.length - 1;
+    while (true) {
+      if (minIndex == maxIndex || minIndex + 1 == maxIndex) {
+        final found = calculatedMatrix[minIndex];
+        cachedLookups[address] = found;
+        return found;
+      }
+      final index = minIndex + ((maxIndex - minIndex) ~/ 2);
+      final compared = calculatedMatrix[index].address.compareTo(address);
+      if (compared == 0) {
+        return calculatedMatrix[index];
+      } else if (compared < 0) {
+        minIndex = index;
+      } else if (compared > 0) {
+        maxIndex = index;
+      }
+    }
+  }
+
+  String filename(int address) {
+    final state = this[address];
+    if (state == null) {
+      return null;
+    }
+    return filesInfo[state.fileIndex].name;
+  }
+
+  int lineNumber(int address) {
+    final state = this[address];
+    if (state == null) {
+      return null;
+    }
+    return state.line;
+  }
+
+  @override
+  String toString() {
+    var buffer = StringBuffer("  Size: $size\n"
+        "  Version: $version\n"
+        "  Header length: $headerLength\n"
+        "  Min instruction length: $minimumInstructionLength\n"
+        "  Default value of is_stmt: $defaultIsStatement\n"
+        "  Line base: $lineBase\n"
+        "  Line range: $lineRange\n"
+        "  Opcode base: $opcodeBase\n"
+        "  Standard opcode lengths:\n");
+    for (int i = 1; i < opcodeBase; i++) {
+      buffer
+        ..write("    Opcode ")
+        ..write(i)
+        ..write(": ")
+        ..writeln(standardOpcodeLengths[i]);
+    }
+
+    if (includeDirectories.isEmpty) {
+      buffer.writeln("No include directories.");
+    } else {
+      buffer.writeln("Include directories:");
+      for (final dir in includeDirectories) {
+        buffer
+          ..write("    ")
+          ..writeln(dir);
+      }
+    }
+
+    filesInfo.writeToStringBuffer(buffer);
+
+    buffer.writeln("Results of line number program:");
+    for (final state in calculatedMatrix) {
+      buffer..write(state);
+    }
+
+    return buffer.toString();
+  }
+}
+
+/// A class representing a DWARF .debug_line section.
+class LineNumberInfo {
+  final Reader reader;
+
+  Map<int, LineNumberProgram> programs;
+
+  LineNumberInfo.fromReader(this.reader) {
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    programs = <int, LineNumberProgram>{};
+    while (!reader.done) {
+      final start = reader.offset;
+      final program = LineNumberProgram.fromReader(reader.shrink(start));
+      reader.seek(program.reader.offset);
+      if (program.size == 0) {
+        break;
+      }
+      programs[start] = program;
+    }
+  }
+
+  bool containsKey(int address) => programs.containsKey(address);
+  LineNumberProgram operator [](int address) => programs[address];
+
+  String toString() =>
+      "Line number information:\n\n" +
+      programs
+          .map((int i, LineNumberProgram p) =>
+              MapEntry(i, "Line number program @ 0x${paddedHex(i)}:\n$p\n"))
+          .values
+          .join();
+}
+
+// TODO(11617): Replace calls to these functions with a general hashing solution
+// once available.
+int _hashCombine(int hash, int value) {
+  hash = 0x1fffffff & (hash + value);
+  hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+  return hash ^ (hash >> 6);
+}
+
+int _hashFinish(int hash) {
+  hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+  hash = hash ^ (hash >> 11);
+  return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+}
+
+class CallInfo {
+  final bool inlined;
+  final String function;
+  final String filename;
+  final int line;
+
+  CallInfo({this.inlined = false, this.function, this.filename, this.line});
+
+  int get hashCode => _hashFinish(_hashCombine(
+      _hashCombine(
+          _hashCombine(_hashCombine(0, inlined.hashCode), function.hashCode),
+          filename.hashCode),
+      line.hashCode));
+
+  bool operator ==(Object other) {
+    if (other is CallInfo) {
+      return inlined == other.inlined &&
+          function == other.function &&
+          filename == other.filename &&
+          line == other.line;
+    }
+    return false;
+  }
+
+  String toString() =>
+      "${function} (${filename}:${line <= 0 ? "??" : line.toString()})";
+}
+
+/// The instructions section in which a program counter address is located.
+enum InstructionsSection { vm, isolate }
+
+/// A program counter address viewed as an offset into the appropriate
+/// instructions section of a Dart snapshot.
+class PCOffset {
+  final int offset;
+  final InstructionsSection section;
+
+  PCOffset(this.offset, this.section);
+
+  /// The virtual address for this [PCOffset] in [dwarf].
+  int virtualAddressIn(Dwarf dwarf) => dwarf.virtualAddressOf(this);
+
+  /// The call information found for this [PCOffset] in [dwarf].
+  ///
+  /// If [includeInternalFrames] is false, then only information corresponding
+  /// to user or library code is returned.
+  Iterable<CallInfo> callInfoFrom(Dwarf dwarf,
+          {bool includeInternalFrames = false}) =>
+      dwarf.callInfoFor(dwarf.virtualAddressOf(this),
+          includeInternalFrames: includeInternalFrames);
+
+  @override
+  int get hashCode => _hashFinish(_hashCombine(offset.hashCode, section.index));
+
+  @override
+  bool operator ==(Object other) {
+    return other is PCOffset &&
+        offset == other.offset &&
+        section == other.section;
+  }
+}
+
+/// The DWARF debugging information for a Dart snapshot.
+class Dwarf {
+  final Elf elf;
+  Map<int, _AbbreviationsTable> abbreviationTables;
+  DebugInfo debugInfo;
+  LineNumberInfo lineNumberInfo;
+  int _vmStartAddress;
+  int _isolateStartAddress;
+
+  Dwarf.fromElf(this.elf) {
+    _loadSections();
+  }
+
+  /// Attempts to load the DWARF debugging information from the file at [path].
+  /// Returns a [Dwarf] object if the load succeeds, otherwise returns null.
+  factory Dwarf.fromFile(String path) {
+    final elf = Elf.fromFile(path);
+    if (elf == null) return null;
+    return Dwarf.fromElf(elf);
+  }
+
+  void _loadSections() {
+    final abbrevSection = elf.namedSection(".debug_abbrev").first;
+    abbreviationTables = <int, _AbbreviationsTable>{};
+    var abbreviationOffset = 0;
+    while (abbreviationOffset < abbrevSection.reader.length) {
+      final table = _AbbreviationsTable.fromReader(
+          abbrevSection.reader.shrink(abbreviationOffset));
+      abbreviationTables[abbreviationOffset] = table;
+      abbreviationOffset += table.reader.offset;
+    }
+    assert(abbreviationOffset == abbrevSection.reader.length);
+
+    final lineNumberSection = elf.namedSection(".debug_line").first;
+    lineNumberInfo = LineNumberInfo.fromReader(lineNumberSection.reader);
+
+    final infoSection = elf.namedSection(".debug_info").first;
+    debugInfo = DebugInfo.fromReader(infoSection.reader, this);
+
+    final textSegments = elf.namedSection(".text").toList();
+    if (textSegments.length != 2) {
+      throw FormatException(
+          "Expected two text segments for VM and isolate instructions");
+    }
+
+    _vmStartAddress = textSegments[0].virtualAddress;
+    _isolateStartAddress = textSegments[1].virtualAddress;
+  }
+
+  /// The call information for the given virtual address. There may be
+  /// multiple [CallInfo] objects returned for a single virtual address when
+  /// code has been inlined.
+  ///
+  /// If [includeInternalFrames] is false, then only information corresponding
+  /// to user or library code is returned.
+  Iterable<CallInfo> callInfoFor(int address,
+      {bool includeInternalFrames = false}) {
+    final calls = debugInfo.callInfo(address);
+    if (calls != null && !includeInternalFrames) {
+      return calls.where((CallInfo c) => c.line > 0);
+    }
+    return calls;
+  }
+
+  /// The virtual address in this DWARF information for the given [PCOffset].
+  int virtualAddressOf(PCOffset pcOffset) {
+    switch (pcOffset.section) {
+      case InstructionsSection.vm:
+        return pcOffset.offset + _vmStartAddress;
+      case InstructionsSection.isolate:
+        return pcOffset.offset + _isolateStartAddress;
+      default:
+        throw "Unexpected value for instructions section";
+    }
+  }
+
+  @override
+  String toString() =>
+      "DWARF debugging information:\n\n" +
+      abbreviationTables
+          .map((int i, _AbbreviationsTable t) =>
+              MapEntry(i, "(Offset ${paddedHex(i)}) $t"))
+          .values
+          .join() +
+      "\n$debugInfo\n$lineNumberInfo";
+}
diff --git a/pkg/native_stack_traces/lib/src/elf.dart b/pkg/native_stack_traces/lib/src/elf.dart
new file mode 100644
index 0000000..1fa0d3d
--- /dev/null
+++ b/pkg/native_stack_traces/lib/src/elf.dart
@@ -0,0 +1,581 @@
+// 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:typed_data';
+import 'dart:io';
+
+import 'reader.dart';
+
+int _readElfBytes(Reader reader, int bytes, int alignment) {
+  final alignOffset = reader.offset % alignment;
+  if (alignOffset != 0) {
+    // Move the reader to the next aligned position.
+    reader.seek(reader.offset - alignOffset + alignment);
+  }
+  return reader.readBytes(bytes);
+}
+
+// Reads an Elf{32,64}_Addr.
+int _readElfAddress(Reader reader) {
+  return _readElfBytes(reader, reader.wordSize, reader.wordSize);
+}
+
+// Reads an Elf{32,64}_Off.
+int _readElfOffset(Reader reader) {
+  return _readElfBytes(reader, reader.wordSize, reader.wordSize);
+}
+
+// Reads an Elf{32,64}_Half.
+int _readElfHalf(Reader reader) {
+  return _readElfBytes(reader, 2, 2);
+}
+
+// Reads an Elf{32,64}_Word.
+int _readElfWord(Reader reader) {
+  return _readElfBytes(reader, 4, 4);
+}
+
+// Reads an Elf64_Xword.
+int _readElfXword(Reader reader) {
+  switch (reader.wordSize) {
+    case 4:
+      throw "Internal reader error: reading Elf64_Xword in 32-bit ELF file";
+    case 8:
+      return _readElfBytes(reader, 8, 8);
+    default:
+      throw "Unsupported word size ${reader.wordSize}";
+  }
+}
+
+// Used in cases where the value read for a given field is Elf32_Word on 32-bit
+// and Elf64_Xword on 64-bit.
+int _readElfNative(Reader reader) {
+  switch (reader.wordSize) {
+    case 4:
+      return _readElfWord(reader);
+    case 8:
+      return _readElfXword(reader);
+    default:
+      throw "Unsupported word size ${reader.wordSize}";
+  }
+}
+
+class ElfHeader {
+  final Reader startingReader;
+
+  int wordSize;
+  Endian endian;
+  int entry;
+  int flags;
+  int headerSize;
+  int programHeaderOffset;
+  int sectionHeaderOffset;
+  int programHeaderCount;
+  int sectionHeaderCount;
+  int programHeaderEntrySize;
+  int sectionHeaderEntrySize;
+  int sectionHeaderStringsIndex;
+
+  int get programHeaderSize => programHeaderCount * programHeaderEntrySize;
+  int get sectionHeaderSize => sectionHeaderCount * sectionHeaderEntrySize;
+
+  // Constants used within the ELF specification.
+  static const _ELFMAG = "\x7fELF";
+  static const _ELFCLASS32 = 0x01;
+  static const _ELFCLASS64 = 0x02;
+  static const _ELFDATA2LSB = 0x01;
+  static const _ELFDATA2MSB = 0x02;
+
+  ElfHeader.fromReader(this.startingReader) {
+    _read();
+  }
+
+  static bool startsWithMagicNumber(Reader reader) {
+    reader.reset();
+    for (final sigByte in _ELFMAG.codeUnits) {
+      if (reader.readByte() != sigByte) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  int _readWordSize(Reader reader) {
+    switch (reader.readByte()) {
+      case _ELFCLASS32:
+        return 4;
+      case _ELFCLASS64:
+        return 8;
+      default:
+        throw FormatException("Unexpected e_ident[EI_CLASS] value");
+    }
+  }
+
+  int get calculatedHeaderSize => 0x18 + 3 * wordSize + 0x10;
+
+  Endian _readEndian(Reader reader) {
+    switch (reader.readByte()) {
+      case _ELFDATA2LSB:
+        return Endian.little;
+      case _ELFDATA2MSB:
+        return Endian.big;
+      default:
+        throw FormatException("Unexpected e_indent[EI_DATA] value");
+    }
+  }
+
+  void _read() {
+    startingReader.reset();
+    for (final sigByte in _ELFMAG.codeUnits) {
+      if (startingReader.readByte() != sigByte) {
+        throw FormatException("Not an ELF file");
+      }
+    }
+    wordSize = _readWordSize(startingReader);
+    final fileSize = startingReader.bdata.buffer.lengthInBytes;
+    if (fileSize < calculatedHeaderSize) {
+      throw FormatException("ELF file too small for header: "
+          "file size ${fileSize} < "
+          "calculated header size $calculatedHeaderSize");
+    }
+    endian = _readEndian(startingReader);
+    if (startingReader.readByte() != 0x01) {
+      throw FormatException("Unexpected e_ident[EI_VERSION] value");
+    }
+
+    // After this point, we need the reader to be correctly set up re: word
+    // size and endianness, since we start reading more than single bytes.
+    final reader = Reader.fromTypedData(startingReader.bdata,
+        wordSize: wordSize, endian: endian);
+    reader.seek(startingReader.offset);
+
+    // Skip rest of e_ident/e_type/e_machine, i.e. move to e_version.
+    reader.seek(0x14, absolute: true);
+    if (_readElfWord(reader) != 0x01) {
+      throw FormatException("Unexpected e_version value");
+    }
+
+    entry = _readElfAddress(reader);
+    programHeaderOffset = _readElfOffset(reader);
+    sectionHeaderOffset = _readElfOffset(reader);
+    flags = _readElfWord(reader);
+    headerSize = _readElfHalf(reader);
+    programHeaderEntrySize = _readElfHalf(reader);
+    programHeaderCount = _readElfHalf(reader);
+    sectionHeaderEntrySize = _readElfHalf(reader);
+    sectionHeaderCount = _readElfHalf(reader);
+    sectionHeaderStringsIndex = _readElfHalf(reader);
+
+    if (headerSize != calculatedHeaderSize) {
+      throw FormatException("Stored ELF header size ${headerSize} != "
+          "calculated ELF header size $calculatedHeaderSize");
+    }
+    if (fileSize < programHeaderOffset) {
+      throw FormatException("File is truncated before program header");
+    }
+    if (fileSize < programHeaderOffset + programHeaderSize) {
+      throw FormatException("File is truncated within the program header");
+    }
+    if (fileSize < sectionHeaderOffset) {
+      throw FormatException("File is truncated before section header");
+    }
+    if (fileSize < sectionHeaderOffset + sectionHeaderSize) {
+      throw FormatException("File is truncated within the section header");
+    }
+  }
+
+  String toString() {
+    var ret = "Format is ${wordSize * 8} bits\n";
+    switch (endian) {
+      case Endian.little:
+        ret += "Little-endian format\n";
+        break;
+      case Endian.big:
+        ret += "Big-endian format\n";
+        break;
+    }
+    ret += "Entry point: 0x${paddedHex(entry, wordSize)}\n"
+        "Flags: 0x${paddedHex(flags, 4)}\n"
+        "Header size: ${headerSize}\n"
+        "Program header offset: "
+        "0x${paddedHex(programHeaderOffset, wordSize)}\n"
+        "Program header entry size: ${programHeaderEntrySize}\n"
+        "Program header entry count: ${programHeaderCount}\n"
+        "Section header offset: "
+        "0x${paddedHex(sectionHeaderOffset, wordSize)}\n"
+        "Section header entry size: ${sectionHeaderEntrySize}\n"
+        "Section header entry count: ${sectionHeaderCount}\n"
+        "Section header strings index: ${sectionHeaderStringsIndex}\n";
+    return ret;
+  }
+}
+
+class ProgramHeaderEntry {
+  Reader reader;
+
+  int type;
+  int flags;
+  int offset;
+  int vaddr;
+  int paddr;
+  int filesz;
+  int memsz;
+  int align;
+
+  // p_type constants from ELF specification.
+  static const _PT_NULL = 0;
+  static const _PT_LOAD = 1;
+  static const _PT_DYNAMIC = 2;
+  static const _PT_PHDR = 6;
+
+  ProgramHeaderEntry.fromReader(this.reader) {
+    assert(reader.wordSize == 4 || reader.wordSize == 8);
+    _read();
+  }
+
+  void _read() {
+    reader.reset();
+    type = _readElfWord(reader);
+    if (reader.wordSize == 8) {
+      flags = _readElfWord(reader);
+    }
+    offset = _readElfOffset(reader);
+    vaddr = _readElfAddress(reader);
+    paddr = _readElfAddress(reader);
+    filesz = _readElfNative(reader);
+    memsz = _readElfNative(reader);
+    if (reader.wordSize == 4) {
+      flags = _readElfWord(reader);
+    }
+    align = _readElfNative(reader);
+  }
+
+  static const _typeStrings = <int, String>{
+    _PT_NULL: "PT_NULL",
+    _PT_LOAD: "PT_LOAD",
+    _PT_DYNAMIC: "PT_DYNAMIC",
+    _PT_PHDR: "PT_PHDR",
+  };
+
+  static String _typeToString(int type) {
+    if (_typeStrings.containsKey(type)) {
+      return _typeStrings[type];
+    }
+    return "unknown (${paddedHex(type, 4)})";
+  }
+
+  String toString() => "Type: ${_typeToString(type)}\n"
+      "Flags: 0x${paddedHex(flags, 4)}\n"
+      "Offset: $offset (0x${paddedHex(offset, reader.wordSize)})\n"
+      "Virtual address: 0x${paddedHex(vaddr, reader.wordSize)}\n"
+      "Physical address: 0x${paddedHex(paddr, reader.wordSize)}\n"
+      "Size in file: $filesz\n"
+      "Size in memory: $memsz\n"
+      "Alignment: 0x${paddedHex(align, reader.wordSize)}\n";
+}
+
+class ProgramHeader {
+  final Reader reader;
+  final int entrySize;
+  final int entryCount;
+
+  List<ProgramHeaderEntry> _entries;
+
+  ProgramHeader.fromReader(this.reader, {this.entrySize, this.entryCount}) {
+    _read();
+  }
+
+  int get length => _entries.length;
+  ProgramHeaderEntry operator [](int index) => _entries[index];
+
+  void _read() {
+    reader.reset();
+    _entries = <ProgramHeaderEntry>[];
+    for (var i = 0; i < entryCount; i++) {
+      final entry = ProgramHeaderEntry.fromReader(
+          reader.shrink(i * entrySize, entrySize));
+      _entries.add(entry);
+    }
+  }
+
+  String toString() {
+    var ret = "";
+    for (var i = 0; i < length; i++) {
+      ret += "Entry $i:\n${this[i]}\n";
+    }
+    return ret;
+  }
+}
+
+class SectionHeaderEntry {
+  final Reader reader;
+
+  int nameIndex;
+  String name;
+  int type;
+  int flags;
+  int addr;
+  int offset;
+  int size;
+  int link;
+  int info;
+  int addrAlign;
+  int entrySize;
+
+  SectionHeaderEntry.fromReader(this.reader) {
+    _read();
+  }
+
+  // sh_type constants from ELF specification.
+  static const _SHT_NULL = 0;
+  static const _SHT_PROGBITS = 1;
+  static const _SHT_SYMTAB = 2;
+  static const _SHT_STRTAB = 3;
+  static const _SHT_HASH = 5;
+  static const _SHT_DYNAMIC = 6;
+  static const _SHT_NOBITS = 8;
+  static const _SHT_DYNSYM = 11;
+
+  void _read() {
+    reader.reset();
+    nameIndex = _readElfWord(reader);
+    type = _readElfWord(reader);
+    flags = _readElfNative(reader);
+    addr = _readElfAddress(reader);
+    offset = _readElfOffset(reader);
+    size = _readElfNative(reader);
+    link = _readElfWord(reader);
+    info = _readElfWord(reader);
+    addrAlign = _readElfNative(reader);
+    entrySize = _readElfNative(reader);
+  }
+
+  void setName(StringTable nameTable) {
+    name = nameTable[nameIndex];
+  }
+
+  static const _typeStrings = <int, String>{
+    _SHT_NULL: "SHT_NULL",
+    _SHT_PROGBITS: "SHT_PROGBITS",
+    _SHT_SYMTAB: "SHT_SYMTAB",
+    _SHT_STRTAB: "SHT_STRTAB",
+    _SHT_HASH: "SHT_HASH",
+    _SHT_DYNAMIC: "SHT_DYNAMIC",
+    _SHT_NOBITS: "SHT_NOBITS",
+    _SHT_DYNSYM: "SHT_DYNSYM",
+  };
+
+  static String _typeToString(int type) {
+    if (_typeStrings.containsKey(type)) {
+      return _typeStrings[type];
+    }
+    return "unknown (${paddedHex(type, 4)})";
+  }
+
+  String toString() => "Name: ${name} (@ ${nameIndex})\n"
+      "Type: ${_typeToString(type)}\n"
+      "Flags: 0x${paddedHex(flags, reader.wordSize)}\n"
+      "Address: 0x${paddedHex(addr, reader.wordSize)}\n"
+      "Offset: $offset (0x${paddedHex(offset, reader.wordSize)})\n"
+      "Size: $size\n"
+      "Link: $link\n"
+      "Info: 0x${paddedHex(info, 4)}\n"
+      "Address alignment: 0x${paddedHex(addrAlign, reader.wordSize)}\n"
+      "Entry size: ${entrySize}\n";
+}
+
+class SectionHeader {
+  final Reader reader;
+  final int entrySize;
+  final int entryCount;
+  final int stringsIndex;
+
+  List<SectionHeaderEntry> _entries;
+  StringTable nameTable;
+
+  SectionHeader.fromReader(this.reader,
+      {this.entrySize, this.entryCount, this.stringsIndex}) {
+    _read();
+  }
+
+  SectionHeaderEntry _readSectionHeaderEntry(int index) {
+    final ret = SectionHeaderEntry.fromReader(
+        reader.shrink(index * entrySize, entrySize));
+    if (nameTable != null) {
+      ret.setName(nameTable);
+    }
+    return ret;
+  }
+
+  void _read() {
+    reader.reset();
+    // Set up the section header string table first so we can use it
+    // for the other section header entries.
+    final nameTableEntry = _readSectionHeaderEntry(stringsIndex);
+    assert(nameTableEntry.type == SectionHeaderEntry._SHT_STRTAB);
+    nameTable = StringTable(nameTableEntry,
+        reader.refocus(nameTableEntry.offset, nameTableEntry.size));
+    nameTableEntry.setName(nameTable);
+
+    _entries = <SectionHeaderEntry>[];
+    for (var i = 0; i < entryCount; i++) {
+      // We don't need to reparse the shstrtab entry.
+      if (i == stringsIndex) {
+        _entries.add(nameTableEntry);
+      } else {
+        _entries.add(_readSectionHeaderEntry(i));
+      }
+    }
+  }
+
+  int get length => _entries.length;
+  SectionHeaderEntry operator [](int index) => _entries[index];
+
+  @override
+  String toString() {
+    var ret = "";
+    for (var i = 0; i < length; i++) {
+      ret += "Entry $i:\n${this[i]}\n";
+    }
+    return ret;
+  }
+}
+
+class Section {
+  final Reader reader;
+  final SectionHeaderEntry headerEntry;
+
+  Section(this.headerEntry, this.reader);
+
+  factory Section.fromEntryAndReader(SectionHeaderEntry entry, Reader reader) {
+    switch (entry.type) {
+      case SectionHeaderEntry._SHT_STRTAB:
+        return StringTable(entry, reader);
+      default:
+        return Section(entry, reader);
+    }
+  }
+
+  int get virtualAddress => headerEntry.addr;
+  int get length => reader.bdata.lengthInBytes;
+  @override
+  String toString() => "an unparsed section of ${length} bytes\n";
+}
+
+class StringTable extends Section {
+  final _entries = Map<int, String>();
+
+  StringTable(SectionHeaderEntry entry, Reader reader) : super(entry, reader) {
+    while (!reader.done) {
+      _entries[reader.offset] = reader.readNullTerminatedString();
+    }
+  }
+
+  String operator [](int index) => _entries[index];
+
+  @override
+  String toString() {
+    var buffer = StringBuffer("a string table:\n");
+    for (var key in _entries.keys) {
+      buffer
+        ..write(" ")
+        ..write(key)
+        ..write(" => ")
+        ..writeln(_entries[key]);
+    }
+    return buffer.toString();
+  }
+}
+
+class Elf {
+  final Reader startingReader;
+
+  ElfHeader header;
+  ProgramHeader programHeader;
+  SectionHeader sectionHeader;
+
+  Map<SectionHeaderEntry, Section> sections;
+
+  Elf.fromReader(this.startingReader) {
+    _read();
+  }
+
+  /// Returns either an [Elf] object representing the ELF information in the
+  /// file at [path] or null if the file does not start with the ELF magic
+  /// number.
+  factory Elf.fromFile(String path) {
+    if (!startsWithMagicNumber(path)) return null;
+    return Elf.fromReader(Reader.fromTypedData(File(path).readAsBytesSync(),
+        // We provide null for the wordSize and endianness to ensure
+        // we don't accidentally call any methods that use them until
+        // we have gotten that information from the ELF header.
+        wordSize: null,
+        endian: null));
+  }
+
+  /// Checks that the file at [path] starts with the ELF magic number.
+  static bool startsWithMagicNumber(String path) {
+    final file = File(path).openSync();
+    var ret = true;
+    for (int code in ElfHeader._ELFMAG.codeUnits) {
+      if (file.readByteSync() != code) {
+        ret = false;
+        break;
+      }
+    }
+    file.closeSync();
+    return ret;
+  }
+
+  /// Returns an iterable of [Section]s whose name matches [name].
+  Iterable<Section> namedSection(String name) {
+    final ret = <Section>[];
+    for (var entry in sections.keys) {
+      if (entry.name == name) {
+        ret.add(sections[entry]);
+      }
+    }
+    if (ret.isEmpty) {
+      throw FormatException("No section named $name found in ELF file");
+    }
+    return ret;
+  }
+
+  void _read() {
+    startingReader.reset();
+    header = ElfHeader.fromReader(startingReader.copy());
+    // Now use the word size and endianness information from the header.
+    final reader = Reader.fromTypedData(startingReader.bdata,
+        wordSize: header.wordSize, endian: header.endian);
+    programHeader = ProgramHeader.fromReader(
+        reader.refocus(header.programHeaderOffset, header.programHeaderSize),
+        entrySize: header.programHeaderEntrySize,
+        entryCount: header.programHeaderCount);
+    sectionHeader = SectionHeader.fromReader(
+        reader.refocus(header.sectionHeaderOffset, header.sectionHeaderSize),
+        entrySize: header.sectionHeaderEntrySize,
+        entryCount: header.sectionHeaderCount,
+        stringsIndex: header.sectionHeaderStringsIndex);
+    sections = <SectionHeaderEntry, Section>{};
+    for (var i = 0; i < sectionHeader.length; i++) {
+      final entry = sectionHeader[i];
+      if (i == header.sectionHeaderStringsIndex) {
+        sections[entry] = sectionHeader.nameTable;
+      } else {
+        sections[entry] = Section.fromEntryAndReader(
+            entry, reader.refocus(entry.offset, entry.size));
+      }
+    }
+  }
+
+  @override
+  String toString() {
+    String accumulateSection(String acc, SectionHeaderEntry entry) =>
+        acc + "\nSection ${entry.name} is ${sections[entry]}";
+    return "Header information:\n\n${header}"
+        "\nProgram header information:\n\n${programHeader}"
+        "\nSection header information:\n\n${sectionHeader}"
+        "${sections.keys.fold("", accumulateSection)}";
+  }
+}
diff --git a/pkg/native_stack_traces/lib/src/reader.dart b/pkg/native_stack_traces/lib/src/reader.dart
new file mode 100644
index 0000000..e6d15d9
--- /dev/null
+++ b/pkg/native_stack_traces/lib/src/reader.dart
@@ -0,0 +1,145 @@
+// 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:typed_data';
+import 'dart:math';
+
+String paddedHex(int value, [int bytes = 0]) {
+  return value.toRadixString(16).padLeft(2 * bytes, '0');
+}
+
+class Reader {
+  final ByteData bdata;
+  final Endian endian;
+  final int wordSize;
+
+  int _offset = 0;
+
+  Reader.fromTypedData(TypedData data, {this.wordSize, this.endian})
+      : bdata =
+            ByteData.view(data.buffer, data.offsetInBytes, data.lengthInBytes);
+
+  Reader copy() =>
+      Reader.fromTypedData(bdata, wordSize: wordSize, endian: endian);
+
+  Reader shrink(int offset, [int size = -1]) {
+    if (size < 0) size = bdata.lengthInBytes - offset;
+    assert(offset >= 0 && offset < bdata.lengthInBytes);
+    assert(size >= 0 && (offset + size) <= bdata.lengthInBytes);
+    return Reader.fromTypedData(
+        ByteData.view(bdata.buffer, bdata.offsetInBytes + offset, size),
+        wordSize: wordSize,
+        endian: endian);
+  }
+
+  Reader refocus(int pos, [int size = -1]) {
+    if (size < 0) size = bdata.lengthInBytes - pos;
+    assert(pos >= 0 && pos < bdata.buffer.lengthInBytes);
+    assert(size >= 0 && (pos + size) <= bdata.buffer.lengthInBytes);
+    return Reader.fromTypedData(ByteData.view(bdata.buffer, pos, size),
+        wordSize: wordSize, endian: endian);
+  }
+
+  int get start => bdata.offsetInBytes;
+  int get offset => _offset;
+  int get length => bdata.lengthInBytes;
+  bool get done => _offset >= length;
+
+  void seek(int offset, {bool absolute = false}) {
+    final newOffset = (absolute ? 0 : _offset) + offset;
+    assert(newOffset >= 0 && newOffset < bdata.lengthInBytes);
+    _offset = newOffset;
+  }
+
+  void reset() {
+    seek(0, absolute: true);
+  }
+
+  int readBytes(int size, {bool signed = false}) {
+    assert(_offset + size < length);
+    int ret;
+    switch (size) {
+      case 1:
+        ret = signed ? bdata.getInt8(_offset) : bdata.getUint8(_offset);
+        break;
+      case 2:
+        ret = signed
+            ? bdata.getInt16(_offset, endian)
+            : bdata.getUint16(_offset, endian);
+        break;
+      case 4:
+        ret = signed
+            ? bdata.getInt32(_offset, endian)
+            : bdata.getUint32(_offset, endian);
+        break;
+      case 8:
+        ret = signed
+            ? bdata.getInt64(_offset, endian)
+            : bdata.getUint64(_offset, endian);
+        break;
+      default:
+        throw ArgumentError("invalid request to read $size bytes");
+    }
+    _offset += size;
+    return ret;
+  }
+
+  int readByte({bool signed = false}) => readBytes(1, signed: signed);
+  int readWord() => readBytes(wordSize);
+  String readNullTerminatedString() {
+    final start = bdata.offsetInBytes + _offset;
+    for (int i = 0; _offset + i < bdata.lengthInBytes; i++) {
+      if (bdata.getUint8(_offset + i) == 0) {
+        _offset += i + 1;
+        return String.fromCharCodes(bdata.buffer.asUint8List(start, i));
+      }
+    }
+    return String.fromCharCodes(
+        bdata.buffer.asUint8List(start, bdata.lengthInBytes - _offset));
+  }
+
+  int readLEB128EncodedInteger({bool signed = false}) {
+    var ret = 0;
+    var shift = 0;
+    for (var byte = readByte(); !done; byte = readByte()) {
+      ret |= (byte & 0x7f) << shift;
+      shift += 7;
+      if (byte & 0x80 == 0) {
+        if (signed && byte & 0x40 != 0) {
+          ret |= -(1 << shift);
+        }
+        break;
+      }
+    }
+    return ret;
+  }
+
+  String dumpCurrentReaderPosition({int maxSize = 0, int bytesPerLine = 16}) {
+    var baseData = ByteData.view(bdata.buffer, 0, bdata.buffer.lengthInBytes);
+    var startOffset = 0;
+    var endOffset = baseData.lengthInBytes;
+    final currentOffset = start + _offset;
+    if (maxSize != 0 && maxSize < baseData.lengthInBytes) {
+      var lowerWindow = currentOffset - (maxSize >> 1);
+      // Adjust so that we always start at the beginning of a line.
+      lowerWindow -= lowerWindow % bytesPerLine;
+      final upperWindow = lowerWindow + maxSize;
+      startOffset = max(startOffset, lowerWindow);
+      endOffset = min(endOffset, upperWindow);
+    }
+    var ret = "";
+    for (int i = startOffset; i < endOffset; i += bytesPerLine) {
+      ret += "0x" + paddedHex(i, 8) + " ";
+      for (int j = 0; j < bytesPerLine && i + j < endOffset; j++) {
+        var byte = baseData.getUint8(i + j);
+        ret += (i + j == currentOffset) ? "|" : " ";
+        ret += paddedHex(byte, 1);
+      }
+      ret += "\n";
+    }
+    return ret;
+  }
+
+  String toString() => dumpCurrentReaderPosition();
+}
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
new file mode 100644
index 0000000..118b873
--- /dev/null
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -0,0 +1,18 @@
+name: native_stack_traces
+description: Utilities for working with non-symbolic stack traces.
+version: 0.2.0
+
+homepage: https://github.com/dart-lang/sdk/tree/master/pkg/native_stack_traces
+
+environment:
+  sdk: '>=2.7.1 <3.0.0'
+
+executables:
+  decode:
+
+dependencies:
+  args: ^1.5.2
+  path: ^1.6.4
+
+dev_dependencies:
+  pedantic: ^1.8.0
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 19aa7aa..b623e3c 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -156,6 +156,7 @@
   stackTraceTypeOrigin,
   thisOrSuper,
   throw_,
+  typedefReference,
   uninitializedRead,
 }
 
@@ -233,6 +234,10 @@
   void implicitTypeArguments(
       Source source, AstNode node, Iterable<DecoratedTypeInfo> types);
 
+  /// Clear any data from the propagation step in preparation for that step
+  /// being re-run.
+  void prepareForUpdate();
+
   /// Called whenever the migration engine performs a step in the propagation of
   /// nullability information through the nullability graph, to report details
   /// of the step that was performed and why.
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 3040d66..7801316 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -18,7 +18,9 @@
   /// An if-test or conditional expression needs to have its condition and
   /// "then" branch discarded.
   static const discardThen = const NullabilityFixDescription._(
-    appliedMessage: 'Discarded an unreachable conditional then branch',
+    appliedMessage:
+        'Discarded a condition which is always false, and the "then" branch '
+        'that follows',
     kind: NullabilityFixKind.discardThen,
   );
 
@@ -36,6 +38,12 @@
     kind: NullabilityFixKind.discardElse,
   );
 
+  /// An if-test needs to be discarded completely.
+  static const discardIf = const NullabilityFixDescription._(
+    appliedMessage: 'Discarded an if-test with no effect',
+    kind: NullabilityFixKind.discardIf,
+  );
+
   /// An expression's value needs to be null-checked.
   static const checkExpression = const NullabilityFixDescription._(
     appliedMessage: 'Added a non-null assertion to nullable expression',
@@ -48,6 +56,13 @@
     kind: NullabilityFixKind.removeAs,
   );
 
+  /// A null-aware operator needs to be changed into its non-null-aware
+  /// equivalent.
+  static const removeNullAwareness = const NullabilityFixDescription._(
+      appliedMessage:
+          'Changed a null-aware access into an ordinary access, because the target cannot be null',
+      kind: NullabilityFixKind.removeNullAwareness);
+
   /// A message used by dartfix to indicate a fix has been applied.
   final String appliedMessage;
 
@@ -99,10 +114,12 @@
   checkExpression,
   discardCondition,
   discardElse,
+  discardIf,
   discardThen,
   makeTypeNullable,
   noModification,
   removeAs,
+  removeNullAwareness,
 }
 
 /// Provisional API for DartFix to perform nullability migration.
@@ -119,17 +136,11 @@
   /// complete.  TODO(paulberry): remove this mode once the migration algorithm
   /// is fully implemented.
   ///
-  /// [useFixBuilder] indicates whether migration should use the new
-  /// [FixBuilder] infrastructure.  Once FixBuilder is at feature parity with
-  /// the old implementation, this option will be removed and FixBuilder will
-  /// be used unconditionally.
-  ///
   /// Optional parameter [removeViaComments] indicates whether dead code should
   /// be removed in its entirety (the default) or removed by commenting it out.
   factory NullabilityMigration(NullabilityMigrationListener listener,
       {bool permissive,
       NullabilityMigrationInstrumentation instrumentation,
-      bool useFixBuilder,
       bool removeViaComments}) = NullabilityMigrationImpl;
 
   void finalizeInput(ResolvedUnitResult result);
@@ -139,6 +150,9 @@
   void prepareInput(ResolvedUnitResult result);
 
   void processInput(ResolvedUnitResult result);
+
+  /// Update the migration after an edge has been added or removed.
+  void update();
 }
 
 /// [NullabilityMigrationListener] is used by [NullabilityMigration]
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 4da69d5..e4c3772 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -25,7 +25,7 @@
 import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:nnbd_migration/src/utilities/annotation_tracker.dart';
+import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/utilities/scoped_set.dart';
@@ -93,7 +93,7 @@
     with
         _AssignmentChecker,
         PermissiveModeVisitor<DecoratedType>,
-        AnnotationTracker<DecoratedType>,
+        CompletenessTracker<DecoratedType>,
         ResolutionUtils {
   final TypeSystem _typeSystem;
 
@@ -268,6 +268,7 @@
     if (BestPracticesVerifier.isUnnecessaryCast(node, _typeSystem)) {
       _variables.recordUnnecessaryCast(source, node);
     }
+    node.type.accept(this);
     final typeNode = _variables.decoratedTypeAnnotation(source, node.type);
     _handleAssignment(node.expression, destinationType: typeNode);
     _flowAnalysis.asExpression_end(node.expression, typeNode);
@@ -474,8 +475,14 @@
   }
 
   @override
-  DecoratedType visitClassDeclaration(ClassDeclaration node) =>
-      visitClassOrMixinOrExtensionDeclaration(node);
+  DecoratedType visitClassDeclaration(ClassDeclaration node) {
+    visitClassOrMixinOrExtensionDeclaration(node);
+    node.extendsClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.withClause?.accept(this);
+    node.typeParameters?.accept(this);
+    return null;
+  }
 
   DecoratedType visitClassOrMixinOrExtensionDeclaration(
       CompilationUnitMember node) {
@@ -511,6 +518,9 @@
 
   @override
   DecoratedType visitClassTypeAlias(ClassTypeAlias node) {
+    node.superclass.accept(this);
+    node.implementsClause?.accept(this);
+    node.withClause?.accept(this);
     var classElement = node.declaredElement;
     var supertype = classElement.supertype;
     var superElement = supertype.element;
@@ -526,8 +536,9 @@
       var superConstructorDecoratedType =
           _variables.decoratedElementType(superConstructorElement);
       var origin = ImplicitMixinSuperCallOrigin(source, node);
-      _unionDecoratedTypeParameters(
-          constructorDecoratedType, superConstructorDecoratedType, origin);
+      _linkDecoratedTypeParameters(
+          constructorDecoratedType, superConstructorDecoratedType, origin,
+          isUnion: true);
     }
     return null;
   }
@@ -568,6 +579,7 @@
   DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
     _fieldsNotInitializedByConstructor =
         _fieldsNotInitializedAtDeclaration.toSet();
+    node.redirectedConstructor?.type?.typeArguments?.accept(this);
     _handleExecutableDeclaration(
         node,
         node.declaredElement,
@@ -651,12 +663,16 @@
     return null;
   }
 
-  DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) =>
-      visitClassOrMixinOrExtensionDeclaration(node);
+  DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) {
+    visitClassOrMixinOrExtensionDeclaration(node);
+    node.extendedType.accept(this);
+    return null;
+  }
 
   @override
   DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
     node.metadata.accept(this);
+    node.parameters?.accept(this);
     var parameterElement = node.declaredElement as FieldFormalParameterElement;
     var parameterType = _variables.decoratedElementType(parameterElement);
     var field = parameterElement.field;
@@ -664,11 +680,13 @@
     var fieldType = _variables.decoratedElementType(field);
     var origin = FieldFormalParameterOrigin(source, node);
     if (node.type == null) {
-      _unionDecoratedTypes(parameterType, fieldType, origin);
+      _linkDecoratedTypes(parameterType, fieldType, origin, isUnion: true);
     } else {
+      node.type.accept(this);
       _checkAssignment(origin,
           source: parameterType, destination: fieldType, hard: true);
     }
+
     return null;
   }
 
@@ -689,6 +707,7 @@
   @override
   DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
     node.metadata.accept(this);
+    node.returnType?.accept(this);
     if (_flowAnalysis != null) {
       // This is a local function.
       _flowAnalysis.functionExpression_begin(node);
@@ -712,6 +731,7 @@
   DecoratedType visitFunctionExpression(FunctionExpression node) {
     // TODO(mfairhurst): enable edge builder "_insideFunction" hard edge tests.
     node.parameters?.accept(this);
+    node.typeParameters?.accept(this);
     if (node.parent is! FunctionDeclaration) {
       _flowAnalysis.functionExpression_begin(node);
     }
@@ -737,6 +757,7 @@
       FunctionExpressionInvocation node) {
     final argumentList = node.argumentList;
     final typeArguments = node.typeArguments;
+    typeArguments?.accept(this);
     DecoratedType calleeType = _checkExpressionNotNull(node.function);
     if (calleeType.type is FunctionType) {
       return _handleInvocationArguments(node, argumentList.arguments,
@@ -744,7 +765,6 @@
           invokeType: node.staticInvokeType);
     } else {
       // Invocation of type `dynamic` or `Function`.
-      typeArguments?.accept(this);
       argumentList.accept(this);
       return _makeNullableDynamicType(node);
     }
@@ -868,6 +888,7 @@
     List<DecoratedType> decoratedTypeArguments;
     var typeArguments = node.constructorName.type.typeArguments;
     if (typeArguments != null) {
+      typeArguments.accept(this);
       typeArgumentTypes = typeArguments.arguments.map((t) => t.type);
       decoratedTypeArguments = typeArguments.arguments
           .map((t) => _variables.decoratedTypeAnnotation(source, t))
@@ -969,6 +990,7 @@
         instrumentation?.implicitTypeArguments(source, node, [elementType]);
         _currentLiteralElementType = elementType;
       } else {
+        node.typeArguments.accept(this);
         _currentLiteralElementType = _variables.decoratedTypeAnnotation(
             source, node.typeArguments.arguments[0]);
       }
@@ -993,6 +1015,7 @@
   DecoratedType visitMethodDeclaration(MethodDeclaration node) {
     _handleExecutableDeclaration(node, node.declaredElement, node.metadata,
         node.returnType, node.parameters, null, node.body, null);
+    node.typeParameters?.accept(this);
     return null;
   }
 
@@ -1003,6 +1026,8 @@
     bool isNullAware = node.isNullAware;
     var callee = node.methodName.staticElement;
     bool calleeIsStatic = callee is ExecutableElement && callee.isStatic;
+    node.typeArguments?.accept(this);
+
     if (node.isCascaded) {
       targetType = _currentCascadeTargetType;
     } else if (target != null) {
@@ -1022,7 +1047,6 @@
       // Dynamic dispatch.  The return type is `dynamic`.
       // TODO(paulberry): would it be better to assume a return type of `Never`
       // so that we don't unnecessarily propagate nullabilities everywhere?
-      node.typeArguments?.accept(this);
       node.argumentList.accept(this);
       return _makeNullableDynamicType(node);
     }
@@ -1047,8 +1071,13 @@
   }
 
   @override
-  DecoratedType visitMixinDeclaration(MixinDeclaration node) =>
-      visitClassOrMixinOrExtensionDeclaration(node);
+  DecoratedType visitMixinDeclaration(MixinDeclaration node) {
+    visitClassOrMixinOrExtensionDeclaration(node);
+    node.implementsClause?.accept(this);
+    node.onClause?.accept(this);
+    node.typeParameters?.accept(this);
+    return null;
+  }
 
   @override
   DecoratedType visitNamespaceDirective(NamespaceDirective node) {
@@ -1227,6 +1256,7 @@
           _currentLiteralElementType = elementType;
         } else {
           assert(typeArguments.length == 1);
+          node.typeArguments.accept(this);
           _currentLiteralElementType =
               _variables.decoratedTypeAnnotation(source, typeArguments[0]);
         }
@@ -1254,6 +1284,7 @@
               ?.implicitTypeArguments(source, node, [keyType, valueType]);
         } else {
           assert(typeArguments.length == 2);
+          node.typeArguments.accept(this);
           _currentMapKeyType =
               _variables.decoratedTypeAnnotation(source, typeArguments[0]);
           _currentMapValueType =
@@ -1304,6 +1335,8 @@
       return _makeNonNullLiteralType(node);
     } else if (staticElement is ExtensionElement) {
       return _makeNonNullLiteralType(node);
+    } else if (staticElement == null) {
+      assert(node.toString() == 'void');
     } else if (staticElement.enclosingElement is ClassElement &&
         (staticElement.enclosingElement as ClassElement).isEnum) {
       return getOrComputeElementType(staticElement);
@@ -1317,6 +1350,7 @@
   @override
   DecoratedType visitSpreadElement(SpreadElement node) {
     final spreadType = node.expression.staticType;
+    DecoratedType spreadTypeDecorated;
     if (_typeSystem.isSubtypeOf(spreadType, typeProvider.mapObjectObjectType)) {
       assert(_currentMapKeyType != null && _currentMapValueType != null);
       final expectedType = typeProvider.mapType2(
@@ -1325,7 +1359,7 @@
           typeProvider, expectedType, _graph,
           typeArguments: [_currentMapKeyType, _currentMapValueType]);
 
-      _handleAssignment(node.expression,
+      spreadTypeDecorated = _handleAssignment(node.expression,
           destinationType: expectedDecoratedType);
     } else if (_typeSystem.isSubtypeOf(
         spreadType, typeProvider.iterableDynamicType)) {
@@ -1336,14 +1370,14 @@
           typeProvider, expectedType, _graph,
           typeArguments: [_currentLiteralElementType]);
 
-      _handleAssignment(node.expression,
+      spreadTypeDecorated = _handleAssignment(node.expression,
           destinationType: expectedDecoratedType);
     } else {
       // Downcast. We can't assume nullability here, so do nothing.
     }
 
     if (!node.isNullAware) {
-      _checkExpressionNotNull(node.expression);
+      _checkExpressionNotNull(node.expression, sourceType: spreadTypeDecorated);
     }
 
     return null;
@@ -1459,7 +1493,25 @@
   DecoratedType visitTypeName(TypeName typeName) {
     var typeArguments = typeName.typeArguments?.arguments;
     var element = typeName.name.staticElement;
-    if (element is TypeParameterizedElement) {
+    if (element is GenericTypeAliasElement) {
+      final typedefType = _variables.decoratedElementType(element);
+      final typeNameType = _variables.decoratedTypeAnnotation(source, typeName);
+
+      Map<TypeParameterElement, DecoratedType> substitutions;
+      if (typeName.typeArguments == null) {
+        // TODO(mfairhurst): substitute instantiations to bounds
+        substitutions = {};
+      } else {
+        substitutions = Map<TypeParameterElement, DecoratedType>.fromIterables(
+            element.typeParameters,
+            typeName.typeArguments.arguments
+                .map((t) => _variables.decoratedTypeAnnotation(source, t)));
+      }
+
+      final decoratedType = typedefType.substitute(substitutions);
+      final origin = TypedefReferenceOrigin(source, typeName);
+      _linkDecoratedTypes(decoratedType, typeNameType, origin, isUnion: true);
+    } else if (element is TypeParameterizedElement) {
       if (typeArguments == null) {
         var instantiatedType =
             _variables.decoratedTypeAnnotation(source, typeName);
@@ -1469,10 +1521,11 @@
         }
         var origin = InstantiateToBoundsOrigin(source, typeName);
         for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
-          _unionDecoratedTypes(
+          _linkDecoratedTypes(
               instantiatedType.typeArguments[i],
               _variables.decoratedTypeParameterBound(element.typeParameters[i]),
-              origin);
+              origin,
+              isUnion: false);
         }
       } else {
         for (int i = 0; i < typeArguments.length; i++) {
@@ -1491,6 +1544,8 @@
         }
       }
     }
+    typeName.visitChildren(this);
+    typeNameVisited(typeName); // Note this has been visited to TypeNameTracker.
     return null;
   }
 
@@ -1500,6 +1555,7 @@
     bool isTopLevel =
         parent is FieldDeclaration || parent is TopLevelVariableDeclaration;
     node.metadata.accept(this);
+    node.type?.accept(this);
     for (var variable in node.variables) {
       variable.metadata.accept(this);
       var initializer = variable.initializer;
@@ -1567,11 +1623,12 @@
   /// value is non-null.
   ///
   /// Returns the decorated type of [expression].
-  DecoratedType _checkExpressionNotNull(Expression expression) {
+  DecoratedType _checkExpressionNotNull(Expression expression,
+      {DecoratedType sourceType}) {
     if (_isPrefix(expression)) {
       throw ArgumentError('cannot check non-nullability of a prefix');
     }
-    DecoratedType sourceType = expression.accept(this);
+    sourceType ??= expression.accept(this);
     if (sourceType == null) {
       throw StateError('No type computed for ${expression.runtimeType} '
           '(${expression.toSource()}) offset=${expression.offset}');
@@ -1629,17 +1686,43 @@
   DecoratedType _decorateUpperOrLowerBound(AstNode astNode, DartType type,
       DecoratedType left, DecoratedType right, bool isLUB,
       {NullabilityNode node}) {
+    var leftType = left.type;
+    var rightType = right.type;
+    if (leftType is TypeParameterType && leftType != type) {
+      // We are "unwrapping" a type parameter type to its bound.
+      final typeParam = leftType.element;
+      return _decorateUpperOrLowerBound(
+          astNode,
+          type,
+          left.substitute(
+              {typeParam: _variables.decoratedTypeParameterBound(typeParam)}),
+          right,
+          isLUB,
+          node: node);
+    }
+    if (rightType is TypeParameterType && rightType != type) {
+      // We are "unwrapping" a type parameter type to its bound.
+      final typeParam = rightType.element;
+      return _decorateUpperOrLowerBound(
+          astNode,
+          type,
+          left,
+          right.substitute(
+              {typeParam: _variables.decoratedTypeParameterBound(typeParam)}),
+          isLUB,
+          node: node);
+    }
+
     node ??= isLUB
         ? NullabilityNode.forLUB(left.node, right.node)
         : _nullabilityNodeForGLB(astNode, left.node, right.node);
+
     if (type.isDynamic || type.isVoid) {
       return DecoratedType(type, node);
     } else if (type is InterfaceType) {
       if (type.typeArguments.isEmpty) {
         return DecoratedType(type, node);
       } else {
-        var leftType = left.type;
-        var rightType = right.type;
         if (leftType.isDartCoreNull) {
           assert(isLUB, "shouldn't be possible to get C<T> from GLB(null, S)");
           return DecoratedType(type, node, typeArguments: right.typeArguments);
@@ -1746,12 +1829,9 @@
         return DecoratedType(type, node);
       }
 
-      if (leftType.element == type.element &&
-          rightType.element == type.element) {
-        return DecoratedType(type, node);
-      }
-
-      _unimplemented(astNode, 'LUB/GLB with unequal type parameter types');
+      assert(leftType.element == type.element &&
+          rightType.element == type.element);
+      return DecoratedType(type, node);
     }
     _unimplemented(astNode, '_decorateUpperOrLowerBound');
   }
@@ -2005,10 +2085,11 @@
       var overriddenFunctionType =
           decoratedOverriddenFunctionType.substitute(substitution);
       if (returnType == null) {
-        _unionDecoratedTypes(
+        _linkDecoratedTypes(
             _currentFunctionType.returnType,
             overriddenFunctionType.returnType,
-            ReturnTypeInheritanceOrigin(source, node));
+            ReturnTypeInheritanceOrigin(source, node),
+            isUnion: true);
       } else {
         _checkAssignment(ReturnTypeInheritanceOrigin(source, node),
             source: _currentFunctionType.returnType,
@@ -2047,8 +2128,9 @@
           if (overriddenParameterType != null) {
             var origin = ParameterInheritanceOrigin(source, node);
             if (_isUntypedParameter(normalParameter)) {
-              _unionDecoratedTypes(
-                  overriddenParameterType, currentParameterType, origin);
+              _linkDecoratedTypes(
+                  overriddenParameterType, currentParameterType, origin,
+                  isUnion: true);
             } else {
               _checkAssignment(origin,
                   source: overriddenParameterType,
@@ -2080,6 +2162,7 @@
       if (parts is ForEachPartsWithDeclaration) {
         var variableElement = parts.loopVariable.declaredElement;
         lhsElement = variableElement;
+        parts.loopVariable?.type?.accept(this);
       } else if (parts is ForEachPartsWithIdentifier) {
         lhsElement = parts.identifier.staticElement;
       } else {
@@ -2303,6 +2386,44 @@
     }
   }
 
+  void _linkDecoratedTypeParameters(
+      DecoratedType x, DecoratedType y, EdgeOrigin origin,
+      {bool isUnion = true}) {
+    for (int i = 0;
+        i < x.positionalParameters.length && i < y.positionalParameters.length;
+        i++) {
+      _linkDecoratedTypes(
+          x.positionalParameters[i], y.positionalParameters[i], origin,
+          isUnion: isUnion);
+    }
+    for (var entry in x.namedParameters.entries) {
+      var superParameterType = y.namedParameters[entry.key];
+      if (superParameterType != null) {
+        _linkDecoratedTypes(entry.value, y.namedParameters[entry.key], origin,
+            isUnion: isUnion);
+      }
+    }
+  }
+
+  void _linkDecoratedTypes(DecoratedType x, DecoratedType y, EdgeOrigin origin,
+      {bool isUnion = true}) {
+    if (isUnion) {
+      _graph.union(x.node, y.node, origin);
+    } else {
+      _graph.connect(x.node, y.node, origin, hard: true);
+    }
+    _linkDecoratedTypeParameters(x, y, origin, isUnion: isUnion);
+    for (int i = 0;
+        i < x.typeArguments.length && i < y.typeArguments.length;
+        i++) {
+      _linkDecoratedTypes(x.typeArguments[i], y.typeArguments[i], origin,
+          isUnion: isUnion);
+    }
+    if (x.returnType != null && y.returnType != null) {
+      _linkDecoratedTypes(x.returnType, y.returnType, origin, isUnion: isUnion);
+    }
+  }
+
   EdgeOrigin _makeEdgeOrigin(DecoratedType sourceType, Expression expression) {
     if (sourceType.type.isDynamic) {
       return DynamicAssignmentOrigin(source, expression);
@@ -2402,36 +2523,6 @@
     throw UnimplementedError(buffer.toString());
   }
 
-  void _unionDecoratedTypeParameters(
-      DecoratedType x, DecoratedType y, EdgeOrigin origin) {
-    for (int i = 0;
-        i < x.positionalParameters.length && i < y.positionalParameters.length;
-        i++) {
-      _unionDecoratedTypes(
-          x.positionalParameters[i], y.positionalParameters[i], origin);
-    }
-    for (var entry in x.namedParameters.entries) {
-      var superParameterType = y.namedParameters[entry.key];
-      if (superParameterType != null) {
-        _unionDecoratedTypes(entry.value, y.namedParameters[entry.key], origin);
-      }
-    }
-  }
-
-  void _unionDecoratedTypes(
-      DecoratedType x, DecoratedType y, EdgeOrigin origin) {
-    _graph.union(x.node, y.node, origin);
-    _unionDecoratedTypeParameters(x, y, origin);
-    for (int i = 0;
-        i < x.typeArguments.length && i < y.typeArguments.length;
-        i++) {
-      _unionDecoratedTypes(x.typeArguments[i], y.typeArguments[i], origin);
-    }
-    if (x.returnType != null && y.returnType != null) {
-      _unionDecoratedTypes(x.returnType, y.returnType, origin);
-    }
-  }
-
   /// Produce Future<flatten(T)> for some T, however, we would like to merely
   /// upcast T to that type if possible, skipping the flatten when not
   /// necessary.
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 5f9eb0a..57ac8eb 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -225,6 +225,19 @@
   EdgeOriginKind get kind => EdgeOriginKind.instantiateToBounds;
 }
 
+/// Edge origin resulting from a usage of a typedef.
+///
+/// Since typedefs require multiple phases to resolve, they are represented by
+/// a set of inferred nodes. In the secondary phases of graph build, those get
+/// unioned with references to the nodes referring to source code. The origin of
+/// those union edges will be [TypedefReferenceOrigin].
+class TypedefReferenceOrigin extends EdgeOrigin {
+  TypedefReferenceOrigin(Source source, TypeName node) : super(source, node);
+
+  @override
+  EdgeOriginKind get kind => EdgeOriginKind.typedefReference;
+}
+
 /// Edge origin resulting from the use of a type as the main type in an 'is'
 /// check.
 ///
diff --git a/pkg/nnbd_migration/lib/src/edit_plan.dart b/pkg/nnbd_migration/lib/src/edit_plan.dart
index 07be747..d844505 100644
--- a/pkg/nnbd_migration/lib/src/edit_plan.dart
+++ b/pkg/nnbd_migration/lib/src/edit_plan.dart
@@ -262,20 +262,22 @@
   /// If no changes are required to the AST node that is being extracted, the
   /// caller may create innerPlan using [EditPlan.passThrough].
   ///
-  /// Optional argument [info] contains information about why the change was
-  /// made.
+  /// Optional parameters [infoBefore] and [infoAfter] contain information about
+  /// why the change was made.  The reason there are two of these parameters is
+  /// because in general, two chunks of source code will be removed: the code
+  /// coming before [innerPlan.sourceNode] and the code coming after it.
   ///
   /// [innerPlan] will be finalized as a side effect (either immediately or when
   /// the newly created plan is finalized), so it should not be re-used by the
   /// caller.
   NodeProducingEditPlan extract(
       AstNode sourceNode, NodeProducingEditPlan innerPlan,
-      {AtomicEditInfo info}) {
+      {AtomicEditInfo infoBefore, AtomicEditInfo infoAfter}) {
     var parent = innerPlan.sourceNode.parent;
     if (!identical(parent, sourceNode) && parent is ParenthesizedExpression) {
       innerPlan = _ProvisionalParenEditPlan(parent, innerPlan);
     }
-    return _ExtractEditPlan(sourceNode, innerPlan, this, info);
+    return _ExtractEditPlan(sourceNode, innerPlan, this, infoBefore, infoAfter);
   }
 
   /// Converts [plan] to a representation of the concrete edits that need
@@ -417,6 +419,68 @@
     return _RemoveEditPlan(parent, firstIndex, lastIndex, info);
   }
 
+  /// Creates a new edit plan that removes null awareness from [sourceNode].
+  ///
+  /// Optional arguments [targetPlan], [methodNamePlan], [typeArgumentsPlan],
+  /// and [argumentListPlan] indicate what changes should be made to the node's
+  /// target, method name, type arguments, and argument list, respectively.
+  ///
+  /// Optional argument [info] contains information about why the change was
+  /// made.
+  NodeProducingEditPlan removeNullAwarenessFromMethodInvocation(
+      MethodInvocation sourceNode,
+      {NodeProducingEditPlan targetPlan,
+      NodeProducingEditPlan methodNamePlan,
+      NodeProducingEditPlan typeArgumentsPlan,
+      NodeProducingEditPlan argumentListPlan,
+      AtomicEditInfo info}) {
+    assert(sourceNode.operator.type == TokenType.QUESTION_PERIOD);
+    var builder = _PassThroughBuilderImpl(sourceNode);
+    if (targetPlan != null) {
+      builder._handleNodeProducingEditPlan(targetPlan);
+    }
+    builder.changes += {
+      sourceNode.operator.offset: [AtomicEdit.delete(1, info: info)]
+    };
+    if (methodNamePlan != null) {
+      builder._handleNodeProducingEditPlan(methodNamePlan);
+    }
+    if (typeArgumentsPlan != null) {
+      builder._handleNodeProducingEditPlan(typeArgumentsPlan);
+    }
+    if (argumentListPlan != null) {
+      builder._handleNodeProducingEditPlan(argumentListPlan);
+    }
+    return builder.finish(this);
+  }
+
+  /// Creates a new edit plan that removes null awareness from [sourceNode].
+  ///
+  /// Optional arguments [targetPlan] and, [propertyNamePlan] indicate what
+  /// changes should be made to the node's target and property name,
+  /// respectively.
+  ///
+  /// Optional argument [info] contains information about why the change was
+  /// made.
+  NodeProducingEditPlan removeNullAwarenessFromPropertyAccess(
+      PropertyAccess sourceNode,
+      {NodeProducingEditPlan targetPlan,
+      NodeProducingEditPlan propertyNamePlan,
+      AtomicEditInfo info}) {
+    assert(sourceNode.operator.type == TokenType.QUESTION_PERIOD);
+    var builder = _PassThroughBuilderImpl(sourceNode);
+    if (targetPlan != null) {
+      builder._handleNodeProducingEditPlan(targetPlan);
+    }
+    builder.changes += {
+      sourceNode.operator.offset: [AtomicEdit.delete(1, info: info)]
+    };
+    if (propertyNamePlan != null) {
+      builder._handleNodeProducingEditPlan(propertyNamePlan);
+    }
+    return builder.finish(this);
+  }
+
   /// Creates a new edit plan that replaces the contents of [sourceNode] with
   /// the given [replacement] text.
   ///
@@ -721,10 +785,12 @@
 class _ExtractEditPlan extends _NestedEditPlan {
   final EditPlanner _planner;
 
-  final AtomicEditInfo _info;
+  final AtomicEditInfo _infoBefore;
+
+  final AtomicEditInfo _infoAfter;
 
   _ExtractEditPlan(AstNode sourceNode, NodeProducingEditPlan innerPlan,
-      this._planner, this._info)
+      this._planner, this._infoBefore, this._infoAfter)
       : super(sourceNode, innerPlan);
 
   @override
@@ -741,7 +807,7 @@
             _planner.removeViaComments
                 ? _RemovalStyle.commentSpace
                 : _RemovalStyle.delete,
-            _info) +
+            _infoBefore) +
         changes +
         _removeCode(
             innerPlan.sourceNode.end,
@@ -749,7 +815,7 @@
             _planner.removeViaComments
                 ? _RemovalStyle.spaceComment
                 : _RemovalStyle.delete,
-            _info);
+            _infoAfter);
     // Apply parens if needed.
     if (parens && !useInnerParens) {
       changes = _createAddParenChanges(changes);
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_repo.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_repo.dart
new file mode 100644
index 0000000..f063abb
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_repo.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+const _github = 'git@github.com';
+
+/// Data class to contain settings for a given repository.
+///
+/// A repository can be referred to by one or more [FantasySubPackageSettings].
+class FantasyRepoSettings {
+  final String repoName;
+  final String clone;
+  final String branch;
+  final String revision;
+
+  FantasyRepoSettings(this.repoName, this.clone, this.branch, this.revision);
+
+  factory FantasyRepoSettings.fromName(String repoName) {
+    switch (repoName) {
+
+      /// TODO(jcollins-g): Port table over from add_repo_to_workspace.
+      default:
+        return FantasyRepoSettings(
+            repoName, '$_github:dart-lang/$repoName.git', 'master', 'master');
+    }
+  }
+
+  @override
+  int get hashCode => toString().hashCode;
+
+  @override
+  bool operator ==(other) {
+    return other is FantasyRepoSettings &&
+        (other.repoName == repoName &&
+            other.clone == clone &&
+            other.branch == branch &&
+            other.revision == revision);
+  }
+
+  @override
+  String toString() =>
+      'FantasyRepoSettings("$repoName", "$clone", "$branch", "$revision")';
+}
+
+const _repoSubDir = '_repo';
+
+/// Represent a single git clone that may be referred to by one or more
+/// [FantasySubPackage]s.
+class FantasyRepo {
+  final String name;
+  final FantasyRepoSettings repoSettings;
+  final Directory repoRoot;
+
+  FantasyRepo._(this.name, this.repoSettings, this.repoRoot);
+
+  static Future<FantasyRepo> buildFrom(
+      String repoName, Directory workspaceRoot) async {
+    FantasyRepoSettings repoSettings = FantasyRepoSettings.fromName(repoName);
+    Directory repoRoot = Directory(path
+        .canonicalize(path.join(workspaceRoot.path, _repoSubDir, repoName)));
+    // TODO(jcollins-g): implement git operations, cloning, etc.
+    return FantasyRepo._(repoName, repoSettings, repoRoot);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_sub_package.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_sub_package.dart
new file mode 100644
index 0000000..0f12e7d
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_sub_package.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/src/fantasyland/fantasy_repo.dart';
+import 'package:path/path.dart' as path;
+
+/// Data class containing settings for a package within a [FantasyWorkspaceImpl].
+class FantasySubPackageSettings {
+  final String name;
+  final String repoName;
+  final String subDir;
+
+  FantasySubPackageSettings(this.name, this.repoName, this.subDir);
+
+  factory FantasySubPackageSettings.fromName(String name) {
+    switch (name) {
+
+      /// TODO(jcollins-g): Port table over from add_package_to_workspace.
+      default:
+        return FantasySubPackageSettings(name, name, '.');
+    }
+  }
+
+  @override
+  int get hashCode => toString().hashCode;
+
+  @override
+  bool operator ==(other) {
+    return other is FantasySubPackageSettings &&
+        (other.name == name &&
+            other.repoName == repoName &&
+            other.subDir == other.subDir);
+  }
+
+  @override
+  String toString() =>
+      'FantasySubPackageSettings("$name", "$repoName", "$subDir")';
+}
+
+/// Represents one package within a [FantasyWorkspaceImpl].
+///
+/// A `FantasySubPackage` differs from a normal package in that Dart code within
+/// it depends on a global .packages file to resolve symbols.
+class FantasySubPackage {
+  final String name;
+  final FantasyRepo containingRepo;
+  final FantasySubPackageSettings packageSettings;
+
+  /// The symlink in the workspace directory whose [Link.target] is the root of
+  /// the package.
+  final Link packageSymlink;
+
+  FantasySubPackage._(this.name, this.containingRepo, this.packageSettings,
+      this.packageSymlink);
+
+  static Future<FantasySubPackage> buildFrom(String packageName,
+      FantasyRepo containingRepo, Directory workspaceRoot) async {
+    FantasySubPackageSettings packageSettings =
+        FantasySubPackageSettings.fromName(packageName);
+    Link packageSymlink = Link(path.join(workspaceRoot.path, packageName));
+    if (!await packageSymlink.exists()) {
+      await packageSymlink.create(path.canonicalize(
+          path.join(containingRepo.repoRoot.path, packageSettings.subDir)));
+    }
+    // TODO(jcollins-g): implement .packages file handling here
+    return FantasySubPackage._(
+        packageName, containingRepo, packageSettings, packageSymlink);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart
new file mode 100644
index 0000000..f93b888
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/src/fantasyland/fantasy_sub_package.dart';
+import 'package:nnbd_migration/src/fantasyland/fantasy_repo.dart';
+import 'package:nnbd_migration/src/fantasyland/fantasy_workspace_impl.dart';
+
+/// Represent a single [FantasyWorkspace].
+abstract class FantasyWorkspace {
+  Directory get workspaceRoot;
+
+  /// Fully initialized subpackages.
+  ///
+  /// This is fully populated once all [addPackageToWorkspace] futures are
+  /// complete.
+  Map<String, FantasySubPackage> subPackages = {};
+
+  /// Asynchronously add one package to the workspace.
+  ///
+  /// Completes when the given package and all its dependencies (implementation
+  /// dependent) are added to the workspace.
+  Future<void> addPackageToWorkspace(String packageName);
+
+  /// Asynchronously add one repository to the workspace.
+  ///
+  /// Completes when the repository is synced and cloned.
+  /// Completes immediately if the [repoName] is already added.
+  Future<FantasyRepo> addRepoToWorkspace(String repoName);
+}
+
+/// Build a "fantasyland"style repository structure suitable for applying
+/// a migration to.
+Future<FantasyWorkspace> buildFantasyLand(String topLevelPackage,
+    List<String> extraPackages, Directory fantasyLandDir) {
+  return FantasyWorkspaceTopLevelDevDepsImpl.buildFor(
+      topLevelPackage, extraPackages, fantasyLandDir);
+}
diff --git a/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart
new file mode 100644
index 0000000..4f1eb20
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/fantasyland/fantasy_workspace_impl.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/src/fantasyland/fantasy_repo.dart';
+import 'package:nnbd_migration/src/fantasyland/fantasy_sub_package.dart';
+import 'package:nnbd_migration/src/fantasyland/fantasy_workspace.dart';
+
+abstract class FantasyWorkspaceImpl extends FantasyWorkspace {
+  @override
+  final Directory workspaceRoot;
+
+  FantasyWorkspaceImpl._(this.workspaceRoot);
+
+  /// Repositories on which [addRepoToWorkspace] has been called.
+  Map<String, Future<FantasyRepo>> _repos = {};
+
+  /// Sub-packages on which [addPackageToWorkspace] has been called.
+  Map<String, Future<List<String>>> _packageDependencies = {};
+
+  /// Fully initialized subpackages.
+  ///
+  /// This is complete once all [addPackageToWorkspace] futures are complete.
+  /// futures are complete.
+  Map<String, FantasySubPackage> subPackages = {};
+
+  /// Implementation-dependent part of addPackageToWorkspace.
+  ///
+  /// The returned future should complete only when this package's repository
+  /// is:
+  ///
+  ///  cloned
+  ///  up to date
+  ///  added to the global .packages
+  ///  symlinked into the workspace
+  ///  has a [FantasySubPackage] assigned to its key in [subPackages].
+  ///
+  /// Returns a list of packageNames that needed to be added as dependencies.
+  ///
+  /// Which dependencies are automatically added is implementation dependent.
+  Future<List<String>> addPackageToWorkspaceInternal(String packageName);
+
+  Future<void> addPackageToWorkspace(String packageName) async {
+    if (_packageDependencies.containsKey(packageName)) return;
+    _packageDependencies[packageName] =
+        addPackageToWorkspaceInternal(packageName);
+    return Future.wait((await _packageDependencies[packageName])
+        .map((n) => addPackageToWorkspace(n)));
+  }
+
+  /// Asynchronously add one repository to the workspace.
+  ///
+  /// Completes when the repository is synced and cloned.
+  /// Completes immediately if the [repoName] is already added.
+  Future<FantasyRepo> addRepoToWorkspace(String repoName) {
+    if (_repos.containsKey(repoName)) return _repos[repoName];
+    _repos[repoName] = FantasyRepo.buildFrom(repoName, workspaceRoot);
+    return _repos[repoName];
+  }
+}
+
+/// Represents a [FantasyWorkspaceImpl] that only fetches dev_dependencies
+/// for the top level package.
+class FantasyWorkspaceTopLevelDevDepsImpl extends FantasyWorkspaceImpl {
+  final String topLevelPackage;
+
+  FantasyWorkspaceTopLevelDevDepsImpl._(
+      this.topLevelPackage, Directory workspaceRoot)
+      : super._(workspaceRoot);
+
+  static Future<FantasyWorkspace> buildFor(String topLevelPackage,
+      List<String> extraPackageNames, Directory workspaceRoot) async {
+    if (!await workspaceRoot.exists())
+      await workspaceRoot.create(recursive: true);
+
+    var workspace =
+        FantasyWorkspaceTopLevelDevDepsImpl._(topLevelPackage, workspaceRoot);
+    await Future.wait([
+      for (var n in [topLevelPackage, ...extraPackageNames])
+        workspace.addPackageToWorkspace(n)
+    ]);
+    return workspace;
+  }
+
+  Future<List<String>> addPackageToWorkspaceInternal(String packageName) async {
+    FantasySubPackageSettings packageSettings =
+        FantasySubPackageSettings.fromName(packageName);
+    FantasyRepo containingRepo =
+        await addRepoToWorkspace(packageSettings.repoName);
+    await FantasySubPackage.buildFrom(
+        packageName, containingRepo, workspaceRoot);
+    if (packageName == topLevelPackage) {
+      throw UnimplementedError(); // TODO(jcollins-g): implement some dependency calculations.
+    }
+    return [];
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index 2301471..2f4f372 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -12,17 +12,17 @@
 
 /// Implementation of [NodeChange] representing the addition of the keyword
 /// `required` to a named parameter.
-class AddRequiredKeyword extends _NestableChange {
+class AddRequiredKeyword extends NestableChange {
   /// Information about why the change should be made.
   final AtomicEditInfo info;
 
   const AddRequiredKeyword(this.info,
       [NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
-    var innerPlan = _inner.apply(node, aggregator);
+    var innerPlan = inner.apply(node, aggregator);
     return aggregator.planner.surround(innerPlan,
         prefix: [AtomicEdit.insert('required ', info: info)]);
   }
@@ -62,39 +62,39 @@
           "EliminateDeadIf applied to an AST node that's not an if");
     }
     AstNode nodeToKeep;
-    NullabilityFixDescription description;
+    NullabilityFixDescription descriptionBefore, descriptionAfter;
     if (conditionValue) {
       nodeToKeep = thenNode;
+      descriptionBefore = NullabilityFixDescription.discardCondition;
       if (elseNode == null) {
-        description = NullabilityFixDescription.discardCondition;
+        descriptionAfter = descriptionBefore;
       } else {
-        description = NullabilityFixDescription.discardElse;
+        descriptionAfter = NullabilityFixDescription.discardElse;
       }
     } else {
       nodeToKeep = elseNode;
-      description = NullabilityFixDescription.discardThen;
+      descriptionBefore =
+          descriptionAfter = NullabilityFixDescription.discardThen;
     }
-    var info = AtomicEditInfo(description, reasons);
-    if (nodeToKeep == null) {
+    if (nodeToKeep == null ||
+        nodeToKeep is Block && nodeToKeep.statements.isEmpty) {
+      var info = AtomicEditInfo(NullabilityFixDescription.discardIf, reasons);
       return aggregator.planner.removeNode(node, info: info);
     }
-    if (nodeToKeep is Block) {
-      if (nodeToKeep.statements.isEmpty) {
-        return aggregator.planner.removeNode(node, info: info);
-      } else if (nodeToKeep.statements.length == 1) {
-        var singleStatement = nodeToKeep.statements[0];
-        if (singleStatement is VariableDeclarationStatement) {
-          // It's not safe to eliminate the {} because it increases the scope of
-          // the variable declarations
-        } else {
-          return aggregator.planner.extract(
-              node, aggregator.innerPlanForNode(nodeToKeep.statements.single),
-              info: info);
-        }
+    var infoBefore = AtomicEditInfo(descriptionBefore, reasons);
+    var infoAfter = AtomicEditInfo(descriptionAfter, reasons);
+    if (nodeToKeep is Block && nodeToKeep.statements.length == 1) {
+      var singleStatement = (nodeToKeep as Block).statements[0];
+      if (singleStatement is VariableDeclarationStatement) {
+        // It's not safe to eliminate the {} because it increases the scope of
+        // the variable declarations
+      } else {
+        nodeToKeep = singleStatement;
       }
     }
-    return aggregator.planner
-        .extract(node, aggregator.innerPlanForNode(nodeToKeep), info: info);
+    return aggregator.planner.extract(
+        node, aggregator.innerPlanForNode(nodeToKeep),
+        infoBefore: infoBefore, infoAfter: infoAfter);
   }
 
   @override
@@ -167,7 +167,7 @@
 
 /// Implementation of [NodeChange] representing introduction of an explicit
 /// downcast.
-class IntroduceAs extends _NestableChange {
+class IntroduceAs extends NestableChange {
   /// TODO(paulberry): shouldn't be a String
   final String type;
 
@@ -176,28 +176,28 @@
 
   const IntroduceAs(this.type, this.info,
       [NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
-    var innerPlan = _inner.apply(node, aggregator);
+    var innerPlan = inner.apply(node, aggregator);
     return aggregator.planner.addBinaryPostfix(innerPlan, TokenType.AS, type);
   }
 }
 
 /// Implementation of [NodeChange] representing the addition of a trailing `?`
 /// to a type.
-class MakeNullable extends _NestableChange {
+class MakeNullable extends NestableChange {
   /// The decorated type to which a question mark is being added.
   final DecoratedType decoratedType;
 
   const MakeNullable(this.decoratedType,
       [NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
-    var innerPlan = _inner.apply(node, aggregator);
+    var innerPlan = inner.apply(node, aggregator);
     return aggregator.planner.makeNullable(innerPlan,
         info: AtomicEditInfo(
             NullabilityFixDescription.makeTypeNullable(
@@ -206,6 +206,14 @@
   }
 }
 
+/// Shared base class for [NodeChange]s that are based on an [inner] change.
+abstract class NestableChange extends NodeChange {
+  /// The change that should be applied first, before applying this change.
+  final NodeChange<NodeProducingEditPlan> inner;
+
+  const NestableChange._(this.inner);
+}
+
 /// Implementation of [NodeChange] representing no change at all.  This class
 /// is intended to be used as a base class for changes that wrap around other
 /// changes.
@@ -237,17 +245,17 @@
 
 /// Implementation of [NodeChange] representing the addition of a null check to
 /// an expression.
-class NullCheck extends _NestableChange {
+class NullCheck extends NestableChange {
   /// Information about why the change should be made.
   final AtomicEditInfo info;
 
   const NullCheck(this.info,
       [NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
-    var innerPlan = _inner.apply(node, aggregator);
+    var innerPlan = inner.apply(node, aggregator);
     return aggregator.planner
         .addUnaryPostfix(innerPlan, TokenType.BANG, info: info);
   }
@@ -255,27 +263,74 @@
 
 /// Implementation of [NodeChange] representing the removal of an unnecessary
 /// cast.
-class RemoveAs extends _NestableChange {
+class RemoveAs extends NestableChange {
   const RemoveAs([NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
     return aggregator.planner.extract(
-        node, _inner.apply((node as AsExpression).expression, aggregator),
-        info: AtomicEditInfo(NullabilityFixDescription.removeAs, const []));
+        node, inner.apply((node as AsExpression).expression, aggregator),
+        infoAfter:
+            AtomicEditInfo(NullabilityFixDescription.removeAs, const []));
+  }
+}
+
+/// Implementation of [NodeChange] representing the removal of `?` from a `?.`
+/// in a method invocation because the target is non-nullable, or because of
+/// null shorting.
+class RemoveNullAwarenessFromMethodInvocation
+    extends NodeChange<NodeProducingEditPlan> {
+  const RemoveNullAwarenessFromMethodInvocation();
+
+  @override
+  NodeProducingEditPlan apply(AstNode node, FixAggregator aggregator) {
+    var methodInvocation = node as MethodInvocation;
+    var typeArguments = methodInvocation.typeArguments;
+    return aggregator.planner.removeNullAwarenessFromMethodInvocation(
+        methodInvocation,
+        targetPlan: aggregator.innerPlanForNode(methodInvocation.target),
+        methodNamePlan:
+            aggregator.innerPlanForNode(methodInvocation.methodName),
+        typeArgumentsPlan: typeArguments == null
+            ? null
+            : aggregator.innerPlanForNode(typeArguments),
+        argumentListPlan:
+            aggregator.innerPlanForNode(methodInvocation.argumentList),
+        info:
+            AtomicEditInfo(NullabilityFixDescription.removeNullAwareness, []));
+  }
+}
+
+/// Implementation of [NodeChange] representing the removal of `?` from a `?.`
+/// in a property access because the target is non-nullable, or because of null
+/// shorting.
+class RemoveNullAwarenessFromPropertyAccess
+    extends NodeChange<NodeProducingEditPlan> {
+  const RemoveNullAwarenessFromPropertyAccess();
+
+  @override
+  NodeProducingEditPlan apply(AstNode node, FixAggregator aggregator) {
+    var propertyAccess = node as PropertyAccess;
+    return aggregator.planner.removeNullAwarenessFromPropertyAccess(
+        propertyAccess,
+        targetPlan: aggregator.innerPlanForNode(propertyAccess.target),
+        propertyNamePlan:
+            aggregator.innerPlanForNode(propertyAccess.propertyName),
+        info:
+            AtomicEditInfo(NullabilityFixDescription.removeNullAwareness, []));
   }
 }
 
 /// Implementation of [NodeChange] that changes an `@required` annotation into
 /// a `required` keyword.
-class RequiredAnnotationToRequiredKeyword extends _NestableChange {
+class RequiredAnnotationToRequiredKeyword extends NestableChange {
   /// Information about why the change should be made.
   final AtomicEditInfo info;
 
   const RequiredAnnotationToRequiredKeyword(this.info,
       [NodeChange<NodeProducingEditPlan> inner = const NoChange()])
-      : super(inner);
+      : super._(inner);
 
   @override
   EditPlan apply(AstNode node, FixAggregator aggregator) {
@@ -290,17 +345,10 @@
       // The text `required` already exists in the annotation; we can just
       // extract it.
       return aggregator.planner
-          .extract(node, _inner.apply(name, aggregator), info: info);
+          .extract(node, inner.apply(name, aggregator), infoBefore: info);
     } else {
       return aggregator.planner
           .replace(node, [AtomicEdit.insert('required', info: info)]);
     }
   }
 }
-
-/// Shared base class for [NodeChange]s that are based on an [_inner] change.
-abstract class _NestableChange extends NodeChange {
-  final NodeChange<NodeProducingEditPlan> _inner;
-
-  const _NestableChange(this._inner);
-}
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 4e2b9a8..eddd920 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -28,6 +28,7 @@
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/variables.dart';
 
 /// Problem reported by [FixBuilder] when encountering a compound assignment
@@ -81,13 +82,21 @@
 
   ResolverVisitor _resolver;
 
+  /// The listener to which exceptions should be reported.
+  final NullabilityMigrationListener listener;
+
+  /// The compilation unit for which fixes are being built.
+  final CompilationUnit unit;
+
   FixBuilder(
       Source source,
       DecoratedClassHierarchy decoratedClassHierarchy,
       TypeProvider typeProvider,
       Dart2TypeSystem typeSystem,
       Variables variables,
-      LibraryElement definingLibrary)
+      LibraryElement definingLibrary,
+      NullabilityMigrationListener listener,
+      CompilationUnit unit)
       : this._(
             decoratedClassHierarchy,
             _makeNnbdTypeSystem(
@@ -95,14 +104,18 @@
                 typeSystem),
             variables,
             source,
-            definingLibrary);
+            definingLibrary,
+            listener,
+            unit);
 
   FixBuilder._(
       DecoratedClassHierarchy decoratedClassHierarchy,
       this._typeSystem,
       this._variables,
       this.source,
-      LibraryElement definingLibrary)
+      LibraryElement definingLibrary,
+      this.listener,
+      this.unit)
       : typeProvider = _typeSystem.typeProvider {
     // TODO(paulberry): make use of decoratedClassHierarchy
     assert(_typeSystem.isNonNullableByDefault);
@@ -128,16 +141,32 @@
 
   /// Visits the entire compilation [unit] using the analyzer's resolver and
   /// makes note of changes that need to be made.
-  void visitAll(CompilationUnit unit) {
-    unit.accept(_FixBuilderPreVisitor(this));
-    unit.accept(_resolver);
-    unit.accept(_FixBuilderPostVisitor(this));
+  void visitAll() {
+    try {
+      unit.accept(_FixBuilderPreVisitor(this));
+      unit.accept(_resolver);
+      unit.accept(_FixBuilderPostVisitor(this));
+    } catch (exception, stackTrace) {
+      if (listener != null) {
+        listener.reportException(source, unit, exception, stackTrace);
+      } else {
+        rethrow;
+      }
+    }
   }
 
   /// Called whenever an AST node is found that needs to be changed.
-  void _addChange(AstNode node, NodeChange change) {
-    assert(!changes.containsKey(node));
-    changes[node] = change;
+  ///
+  /// The [update] callback is passed whatever change had previously been
+  /// decided upon for this node, or an instance of [NoChange], if the node was
+  /// previously unchanged.
+  void _addChange(AstNode node,
+      NodeChange Function(NodeChange<NodeProducingEditPlan>) update) {
+    // The previous change had better be a NodeChange<NodeProducingEditPlan>
+    // because these are the only kinds of changes that are possible to stack
+    // on top of one another.
+    var previousChange = changes[node] as NodeChange<NodeProducingEditPlan>;
+    changes[node] = update(previousChange ?? const NoChange());
   }
 
   /// Called whenever an AST node is found that can't be automatically fixed.
@@ -182,6 +211,33 @@
     }
   }
 
+  /// Determines whether the given [node], which is a null-aware method
+  /// invocation, property access, or index expression, should remain null-aware
+  /// after migration.
+  bool _shouldStayNullAware(Expression node) {
+    Expression target;
+    NodeChange<NodeProducingEditPlan> nodeChangeToUse;
+    if (node is PropertyAccess) {
+      target = node.target;
+      nodeChangeToUse = const RemoveNullAwarenessFromPropertyAccess();
+    } else if (node is MethodInvocation) {
+      target = node.target;
+      nodeChangeToUse = const RemoveNullAwarenessFromMethodInvocation();
+    } else {
+      throw StateError('Unexpected expression type: ${node.runtimeType}');
+    }
+    if (!_typeSystem.isPotentiallyNullable(target.staticType)) {
+      _addChange(node, (previousChange) {
+        // There should be no previous change because we decide what to do
+        // about `?.` before doing anything else.
+        assert(previousChange is NoChange);
+        return nodeChangeToUse;
+      });
+      return false;
+    }
+    return true;
+  }
+
   static TypeSystemImpl _makeNnbdTypeSystem(
       TypeProvider nnbdTypeProvider, Dart2TypeSystem typeSystem) {
     // TODO(paulberry): do we need to test both possible values of
@@ -201,30 +257,36 @@
 
   final Expando<List<CollectionElement>> _collectionElements = Expando();
 
+  final Expando<bool> _shouldStayNullAware = Expando();
+
   FlowAnalysis<AstNode, Statement, Expression, PromotableElement, DartType>
       _flowAnalysis;
 
   MigrationResolutionHooksImpl(this._fixBuilder);
 
   @override
-  bool getConditionalKnownValue(AstNode node) {
-    // TODO(paulberry): handle conditional expressions.
-    var conditionalDiscard =
-        _fixBuilder._variables.getConditionalDiscard(_fixBuilder.source, node);
-    if (conditionalDiscard == null) {
-      return null;
-    } else {
-      if (conditionalDiscard.keepTrue && conditionalDiscard.keepFalse) {
-        return null;
-      }
-      var conditionValue = conditionalDiscard.keepTrue;
-      _fixBuilder._addChange(
-          node,
-          EliminateDeadIf(conditionValue,
-              reasons: conditionalDiscard.reasons.toList()));
-      return conditionValue;
-    }
-  }
+  bool getConditionalKnownValue(AstNode node) =>
+      _wrapExceptions(node, () => null, () {
+        // TODO(paulberry): handle conditional expressions.
+        var conditionalDiscard = _fixBuilder._variables
+            .getConditionalDiscard(_fixBuilder.source, node);
+        if (conditionalDiscard == null) {
+          return null;
+        } else {
+          if (conditionalDiscard.keepTrue && conditionalDiscard.keepFalse) {
+            return null;
+          }
+          var conditionValue = conditionalDiscard.keepTrue;
+          _fixBuilder._addChange(node, (previousChange) {
+            // There shouldn't be a previous change for [node] because we
+            // check for dead code before making other modifications.
+            assert(previousChange is NoChange);
+            return EliminateDeadIf(conditionValue,
+                reasons: conditionalDiscard.reasons.toList());
+          });
+          return conditionValue;
+        }
+      });
 
   @override
   List<ParameterElement> getExecutableParameters(ExecutableElement element) =>
@@ -235,59 +297,85 @@
       getExecutableType(element).returnType;
 
   @override
-  FunctionType getExecutableType(FunctionTypedElement element) {
-    var type = _fixBuilder._computeMigratedType(element);
-    Element baseElement = element;
-    if (baseElement is Member) {
-      type = baseElement.substitution.substituteType(type);
-    }
-    return type as FunctionType;
+  FunctionType getExecutableType(FunctionTypedElement element) =>
+      _wrapExceptions(_fixBuilder.unit, () => element.type, () {
+        var type = _fixBuilder._computeMigratedType(element);
+        Element baseElement = element;
+        if (baseElement is Member) {
+          type = baseElement.substitution.substituteType(type);
+        }
+        return type as FunctionType;
+      });
+
+  @override
+  DartType getFieldType(FieldElement element) =>
+      _wrapExceptions(_fixBuilder.unit, () => element.type, () {
+        assert(!element.isSynthetic);
+        return _fixBuilder._computeMigratedType(element);
+      });
+
+  @override
+  List<CollectionElement> getListElements(ListLiteral node) => _wrapExceptions(
+      node,
+      () => node.elements,
+      () => _collectionElements[node] ??=
+          _transformCollectionElements(node.elements, node.typeArguments));
+
+  @override
+  List<CollectionElement> getSetOrMapElements(SetOrMapLiteral node) =>
+      _wrapExceptions(
+          node,
+          () => node.elements,
+          () => _collectionElements[node] ??=
+              _transformCollectionElements(node.elements, node.typeArguments));
+
+  @override
+  DartType getVariableType(VariableElement variable) =>
+      _wrapExceptions(_fixBuilder.unit, () => variable.type, () {
+        if (variable.library == null) {
+          // This is a synthetic variable created during resolution (e.g. a
+          // parameter of a function type), so the type it currently has is the
+          // correct post-migration type.
+          return variable.type;
+        }
+        return _fixBuilder._computeMigratedType(variable);
+      });
+
+  @override
+  bool isIndexExpressionNullAware(IndexExpression node) {
+    // Null-aware index expressions weren't supported prior to NNBD.
+    assert(!node.isNullAware);
+    return false;
   }
 
   @override
-  DartType getFieldType(FieldElement element) {
-    assert(!element.isSynthetic);
-    return _fixBuilder._computeMigratedType(element);
+  bool isMethodInvocationNullAware(MethodInvocation node) {
+    return node.isNullAware &&
+        (_shouldStayNullAware[node] ??= _fixBuilder._shouldStayNullAware(node));
   }
 
   @override
-  List<CollectionElement> getListElements(ListLiteral node) {
-    return _collectionElements[node] ??=
-        _transformCollectionElements(node.elements, node.typeArguments);
+  bool isPropertyAccessNullAware(PropertyAccess node) {
+    return node.isNullAware &&
+        (_shouldStayNullAware[node] ??= _fixBuilder._shouldStayNullAware(node));
   }
 
   @override
-  List<CollectionElement> getSetOrMapElements(SetOrMapLiteral node) {
-    return _collectionElements[node] ??=
-        _transformCollectionElements(node.elements, node.typeArguments);
-  }
-
-  @override
-  DartType getVariableType(VariableElement variable) {
-    if (variable.library == null) {
-      // This is a synthetic variable created during resolution (e.g. a
-      // parameter of a function type), so the type it currently has is the
-      // correct post-migration type.
-      return variable.type;
-    }
-    return _fixBuilder._computeMigratedType(variable);
-  }
-
-  @override
-  DartType modifyExpressionType(Expression node, DartType type) {
-    if (type.isDynamic) return type;
-    if (!_fixBuilder._typeSystem.isNullable(type)) return type;
-    var ancestor = _findNullabilityContextAncestor(node);
-    if (_needsNullCheckDueToStructure(ancestor)) {
-      return _addNullCheck(node, type);
-    }
-    var context =
-        InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
-    if (!_fixBuilder._typeSystem.isNullable(context)) {
-      return _addNullCheck(node, type);
-    }
-    return type;
-  }
+  DartType modifyExpressionType(Expression node, DartType type) =>
+      _wrapExceptions(node, () => type, () {
+        if (type.isDynamic) return type;
+        if (!_fixBuilder._typeSystem.isNullable(type)) return type;
+        var ancestor = _findNullabilityContextAncestor(node);
+        if (_needsNullCheckDueToStructure(ancestor)) {
+          return _addNullCheck(node, type);
+        }
+        var context =
+            InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
+        if (!_fixBuilder._typeSystem.isNullable(context)) {
+          return _addNullCheck(node, type);
+        }
+        return type;
+      });
 
   @override
   void setFlowAnalysis(
@@ -303,7 +391,8 @@
         ? AtomicEditInfo(
             NullabilityFixDescription.checkExpression, checks.edges)
         : null;
-    _fixBuilder._addChange(node, NullCheck(info));
+    _fixBuilder._addChange(
+        node, (previousChange) => NullCheck(info, previousChange));
     _flowAnalysis.nonNullAssert_end(node);
     return _fixBuilder._typeSystem.promoteToNonNull(type as TypeImpl);
   }
@@ -385,6 +474,22 @@
         .where((e) => e != null)
         .toList();
   }
+
+  /// Runs the computation in [compute].  If an exception occurs and
+  /// [_fixBuilder.listener] is non-null, the exception is reported to the
+  /// listener and [fallback] is called to produce a result.  Otherwise the
+  /// exception is propagated normally.
+  T _wrapExceptions<T>(
+      AstNode node, T Function() fallback, T Function() compute) {
+    if (_fixBuilder.listener == null) return compute();
+    try {
+      return compute();
+    } catch (exception, stackTrace) {
+      _fixBuilder.listener
+          .reportException(_fixBuilder.source, node, exception, stackTrace);
+      return fallback();
+    }
+  }
 }
 
 /// Problem reported by [FixBuilder] when encountering a non-nullable unnamed
@@ -398,17 +503,25 @@
 
 /// Visitor that computes additional migrations on behalf of [FixBuilder] that
 /// should be run after resolution
-class _FixBuilderPostVisitor extends RecursiveAstVisitor<void> {
+class _FixBuilderPostVisitor extends GeneralizingAstVisitor<void>
+    with PermissiveModeVisitor<void> {
   final FixBuilder _fixBuilder;
 
   _FixBuilderPostVisitor(this._fixBuilder);
 
   @override
+  NullabilityMigrationListener get listener => _fixBuilder.listener;
+
+  @override
+  Source get source => _fixBuilder.source;
+
+  @override
   void visitAsExpression(AsExpression node) {
     if (!_fixBuilder._variables.wasUnnecessaryCast(_fixBuilder.source, node) &&
         BestPracticesVerifier.isUnnecessaryCast(
             node, _fixBuilder._typeSystem)) {
-      _fixBuilder._addChange(node, const RemoveAs());
+      _fixBuilder._addChange(
+          node, (previousChange) => RemoveAs(previousChange));
     }
   }
 }
@@ -416,12 +529,19 @@
 /// Visitor that computes additional migrations on behalf of [FixBuilder] that
 /// don't need to be integrated into the resolver itself, and should be run
 /// prior to resolution
-class _FixBuilderPreVisitor extends RecursiveAstVisitor<void> {
+class _FixBuilderPreVisitor extends GeneralizingAstVisitor<void>
+    with PermissiveModeVisitor<void> {
   final FixBuilder _fixBuilder;
 
   _FixBuilderPreVisitor(this._fixBuilder);
 
   @override
+  NullabilityMigrationListener get listener => _fixBuilder.listener;
+
+  @override
+  Source get source => _fixBuilder.source;
+
+  @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     var element = node.declaredElement;
     if (node.defaultValue == null) {
@@ -444,7 +564,8 @@
     var decoratedType = _fixBuilder._variables
         .decoratedTypeAnnotation(_fixBuilder.source, node);
     if (decoratedType.node.isNullable) {
-      _fixBuilder._addChange(node, MakeNullable(decoratedType));
+      _fixBuilder._addChange(node,
+          (previousChange) => MakeNullable(decoratedType, previousChange));
     }
     (node as GenericFunctionTypeImpl).type =
         decoratedType.toFinalType(_fixBuilder.typeProvider);
@@ -457,7 +578,8 @@
         .decoratedTypeAnnotation(_fixBuilder.source, node);
     var type = decoratedType.type;
     if (!type.isDynamic && !type.isVoid && decoratedType.node.isNullable) {
-      _fixBuilder._addChange(node, MakeNullable(decoratedType));
+      _fixBuilder._addChange(node,
+          (previousChange) => MakeNullable(decoratedType, previousChange));
     }
     node.type = decoratedType.toFinalType(_fixBuilder.typeProvider);
     super.visitTypeName(node);
@@ -480,11 +602,14 @@
         // TODO(paulberry): what if `@required` isn't the first annotation?
         // Will we produce something that isn't grammatical?
         _fixBuilder._addChange(
-            annotation, RequiredAnnotationToRequiredKeyword(info));
+            annotation,
+            (previousChange) =>
+                RequiredAnnotationToRequiredKeyword(info, previousChange));
         return;
       }
     }
     // Otherwise create a new `required` keyword.
-    _fixBuilder._addChange(parameter, AddRequiredKeyword(info));
+    _fixBuilder._addChange(parameter,
+        (previousChange) => AddRequiredKeyword(info, previousChange));
   }
 }
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 33b620e..3a23ae3 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -19,7 +19,7 @@
 import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/potential_modification.dart';
-import 'package:nnbd_migration/src/utilities/annotation_tracker.dart';
+import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 
 import 'edge_origin.dart';
@@ -33,7 +33,7 @@
 class NodeBuilder extends GeneralizingAstVisitor<DecoratedType>
     with
         PermissiveModeVisitor<DecoratedType>,
-        AnnotationTracker<DecoratedType> {
+        CompletenessTracker<DecoratedType> {
   /// Constraint variables and decorated types are stored here.
   final VariableRecorder _variables;
 
@@ -486,7 +486,10 @@
   }
 
   @override
-  DecoratedType visitTypeName(TypeName node) => visitTypeAnnotation(node);
+  DecoratedType visitTypeName(TypeName node) {
+    typeNameVisited(node); // Note this has been visited to TypeNameTracker.
+    return visitTypeAnnotation(node);
+  }
 
   @override
   DecoratedType visitTypeParameter(TypeParameter node) {
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 47574a2..1cde09e 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
@@ -16,7 +15,6 @@
 import 'package:nnbd_migration/src/fix_builder.dart';
 import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:nnbd_migration/src/potential_modification.dart';
 import 'package:nnbd_migration/src/variables.dart';
 
 /// Implementation of the [NullabilityMigration] public API.
@@ -35,14 +33,6 @@
 
   bool _propagated = false;
 
-  /// Indicates whether migration should use the new [FixBuilder]
-  /// infrastructure.  Once FixBuilder is at feature parity with the old
-  /// implementation, this option will be removed and FixBuilder will be used
-  /// unconditionally.
-  ///
-  /// Currently defaults to `false`.
-  final bool useFixBuilder;
-
   /// Indicates whether code removed by the migration engine should be removed
   /// by commenting it out.  A value of `false` means to actually delete the
   /// code that is removed.
@@ -55,60 +45,27 @@
   /// complete.  TODO(paulberry): remove this mode once the migration algorithm
   /// is fully implemented.
   ///
-  /// [useFixBuilder] indicates whether migration should use the new
-  /// [FixBuilder] infrastructure.  Once FixBuilder is at feature parity with
-  /// the old implementation, this option will be removed and FixBuilder will
-  /// be used unconditionally.
-  ///
   /// Optional parameter [removeViaComments] indicates whether dead code should
   /// be removed in its entirety (the default) or removed by commenting it out.
   NullabilityMigrationImpl(NullabilityMigrationListener listener,
       {bool permissive: false,
       NullabilityMigrationInstrumentation instrumentation,
-      bool useFixBuilder: false,
-      bool removeViaComments = false})
+      bool removeViaComments = true})
       : this._(listener, NullabilityGraph(instrumentation: instrumentation),
-            permissive, instrumentation, useFixBuilder, removeViaComments);
+            permissive, instrumentation, removeViaComments);
 
   NullabilityMigrationImpl._(this.listener, this._graph, this._permissive,
-      this._instrumentation, this.useFixBuilder, this.removeViaComments) {
+      this._instrumentation, this.removeViaComments) {
     _instrumentation?.immutableNodes(_graph.never, _graph.always);
   }
 
-  @visibleForTesting
-  void broadcast(Variables variables, NullabilityMigrationListener listener,
-      NullabilityMigrationInstrumentation instrumentation) {
-    assert(!useFixBuilder);
-    for (var entry in variables.getPotentialModifications().entries) {
-      var source = entry.key;
-      final lineInfo = LineInfo.fromContent(source.contents.data);
-      var changes = <int, List<AtomicEdit>>{};
-      for (var potentialModification in entry.value) {
-        var modifications = potentialModification.modifications;
-        if (modifications.isEmpty) {
-          continue;
-        }
-        var description = potentialModification.description;
-        var info =
-            AtomicEditInfo(description, potentialModification.reasons.toList());
-        var atomicEditsByLocation = _gatherAtomicEditsByLocation(
-            source, potentialModification, lineInfo, info);
-        for (var entry in atomicEditsByLocation) {
-          var location = entry.key;
-          listener.addSuggestion(description.appliedMessage, location);
-          changes[location.offset] = [entry.value];
-        }
-        for (var edit in modifications) {
-          listener.addEdit(source, edit);
-        }
-      }
-      instrumentation?.changes(source, changes);
-    }
+  @override
+  void update() {
+    _graph.update();
   }
 
   @override
   void finalizeInput(ResolvedUnitResult result) {
-    if (!useFixBuilder) return;
     if (!_propagated) {
       _propagated = true;
       _graph.propagate();
@@ -123,8 +80,10 @@
         result.typeProvider,
         library.typeSystem as Dart2TypeSystem,
         _variables,
-        library);
-    fixBuilder.visitAll(unit);
+        library,
+        listener,
+        unit);
+    fixBuilder.visitAll();
     var changes = FixAggregator.run(unit, result.content, fixBuilder.changes,
         removeViaComments: removeViaComments);
     _instrumentation?.changes(source, changes);
@@ -145,22 +104,8 @@
     }
   }
 
-  void finish() {
-    if (useFixBuilder) return;
-    _graph.propagate();
-    if (_graph.unsatisfiedSubstitutions.isNotEmpty) {
-      // TODO(paulberry): for now we just ignore unsatisfied substitutions, to
-      // work around https://github.com/dart-lang/sdk/issues/38257
-      // throw new UnimplementedError('Need to report unsatisfied substitutions');
-    }
-    // TODO(paulberry): it would be nice to report on unsatisfied edges as well,
-    // however, since every `!` we add has an unsatisfied edge associated with
-    // it, we can't report on every unsatisfied edge.  We need to figure out a
-    // way to report unsatisfied edges that isn't too overwhelming.
-    if (_variables != null) {
-      broadcast(_variables, listener, _instrumentation);
-    }
-  }
+  /// TODO(paulberry): eliminate?
+  void finish() {}
 
   void prepareInput(ResolvedUnitResult result) {
     if (_variables == null) {
@@ -199,21 +144,4 @@
     );
     return location;
   }
-
-  static List<MapEntry<Location, AtomicEdit>> _gatherAtomicEditsByLocation(
-      Source source,
-      PotentialModification potentialModification,
-      LineInfo lineInfo,
-      AtomicEditInfo info) {
-    List<MapEntry<Location, AtomicEdit>> result = [];
-
-    for (var modification in potentialModification.modifications) {
-      var atomicEdit = AtomicEdit.replace(
-          modification.length, modification.replacement,
-          info: info);
-      result.add(MapEntry(
-          _computeLocation(lineInfo, modification, source), atomicEdit));
-    }
-    return result;
-  }
 }
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 04db7be..1acb613 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -111,6 +111,9 @@
   /// Set containing all sources being migrated.
   final _sourcesBeingMigrated = <Source>{};
 
+  /// A set containing all of the nodes in the graph.
+  final Set<NullabilityNode> nodes = {};
+
   /// After execution of [_propagateAlways], a list of all nodes reachable from
   /// [always] via zero or more edges of kind [_NullabilityEdgeKind.union].
   final List<NullabilityNode> _unionedWithAlways = [];
@@ -200,6 +203,29 @@
     _connect([y], x, _NullabilityEdgeKind.union, origin);
   }
 
+  /// Update the graph after an edge has been added or removed.
+  void update() {
+    //
+    // Reset the state of the nodes.
+    //
+    // This is inefficient because we reset the state of some nodes more than
+    // once, but not all nodes are reachable from both `never` and `always`, so
+    // we need to traverse the graph from both directions.
+    //
+    for (var node in nodes) {
+      node.resetState();
+    }
+    _unionedWithAlways.clear();
+    //
+    // Reset the state of the listener.
+    //
+    instrumentation.prepareForUpdate();
+    //
+    // Re-run the propagation step.
+    //
+    propagate();
+  }
+
   NullabilityEdge _connect(
       List<NullabilityNode> upstreamNodes,
       NullabilityNode destinationNode,
@@ -211,6 +237,8 @@
       _connectDownstream(upstreamNode, edge);
     }
     destinationNode._upstreamEdges.add(edge);
+    nodes.addAll(upstreamNodes);
+    nodes.add(destinationNode);
     return edge;
   }
 
@@ -558,6 +586,9 @@
     }
   }
 
+  /// Reset the state of this node to what it was before the graph was solved.
+  void resetState();
+
   String toString() {
     if (_debugName == null) {
       var prefix = _debugPrefix;
@@ -606,6 +637,12 @@
 
   @override
   String get _debugPrefix => 'LUB($left, $right)';
+
+  @override
+  void resetState() {
+    left.resetState();
+    right.resetState();
+  }
 }
 
 /// Derived class for nullability nodes that arise from type variable
@@ -628,6 +665,12 @@
 
   @override
   String get _debugPrefix => 'Substituted($innerNode, $outerNode)';
+
+  @override
+  void resetState() {
+    innerNode.resetState();
+    outerNode.resetState();
+  }
 }
 
 /// Base class for nullability nodes whose state can be mutated safely.
@@ -650,6 +693,11 @@
 
   @override
   bool get isNullable => _state.isNullable;
+
+  @override
+  void resetState() {
+    _state = NullabilityState.undetermined;
+  }
 }
 
 /// Kinds of nullability edges
@@ -704,6 +752,11 @@
   NullabilityState get _state => isNullable
       ? NullabilityState.ordinaryNullable
       : NullabilityState.nonNullable;
+
+  @override
+  void resetState() {
+    // There is no state to reset.
+  }
 }
 
 class _NullabilityNodeSimple extends NullabilityNodeMutable {
diff --git a/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
index 6ae2038..ab64227 100644
--- a/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
@@ -4,48 +4,9 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 
-/// Mixin that verifies (via assertion checks) that a visitor does not miss any
-/// annotations when processing a compilation unit.
-///
-/// Mixing in this class should have very low overhead when assertions are
-/// disabled.
-mixin AnnotationTracker<T> on AstVisitor<T>, PermissiveModeVisitor<T> {
-  _AnnotationTracker _annotationTracker;
-
-  @override
-  T visitAnnotation(Annotation node) {
-    assert(() {
-      _annotationTracker._nodeVisited(node);
-      return true;
-    }());
-    return super.visitAnnotation(node);
-  }
-
-  @override
-  T visitCompilationUnit(CompilationUnit node) {
-    T result;
-    reportExceptionsIfPermissive(node, () {
-      assert(() {
-        assert(_annotationTracker == null);
-        _annotationTracker = _AnnotationTracker();
-        node.accept(_annotationTracker);
-        return true;
-      }());
-      try {
-        result = super.visitCompilationUnit(node);
-        assert(_annotationTracker._nodes.isEmpty,
-            'Annotation nodes not visited: ${_annotationTracker._nodes}');
-      } finally {
-        _annotationTracker = null;
-      }
-    });
-    return result;
-  }
-}
-
-class _AnnotationTracker extends RecursiveAstVisitor<void> {
+/// A simple class to find all [Annotation]s and track if they all get visited.
+class AnnotationTracker extends RecursiveAstVisitor<void> {
   final Set<Annotation> _nodes = {};
 
   @override
@@ -53,9 +14,13 @@
     _nodes.add(node);
   }
 
-  void _nodeVisited(Annotation node) {
+  void nodeVisited(Annotation node) {
     if (!_nodes.remove(node)) {
       throw StateError('Visited unexpected annotation $node');
     }
   }
+
+  void finalize() {
+    assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
+  }
 }
diff --git a/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart
new file mode 100644
index 0000000..7f5bdbe
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2020, 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/dart/ast/ast.dart';
+import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
+import 'package:nnbd_migration/src/utilities/annotation_tracker.dart';
+import 'package:nnbd_migration/src/utilities/type_name_tracker.dart';
+
+/// Mixin that verifies (via assertion checks) that a visitor visits a
+/// compilation unit to "completeness" -- currently tracks Annotations and
+/// TypeNames.
+///
+/// Mixing in this class should have very low overhead when assertions are
+/// disabled.
+mixin CompletenessTracker<T> on AstVisitor<T>, PermissiveModeVisitor<T> {
+  AnnotationTracker _annotationTracker;
+  TypeNameTracker _typeNameTracker;
+
+  @override
+  T visitAnnotation(Annotation node) {
+    assert(() {
+      _annotationTracker.nodeVisited(node);
+      return true;
+    }());
+    return super.visitAnnotation(node);
+  }
+
+  void typeNameVisited(TypeName node) {
+    assert(() {
+      _typeNameTracker.nodeVisited(node);
+      return true;
+    }());
+  }
+
+  @override
+  T visitCompilationUnit(CompilationUnit node) {
+    T result;
+    reportExceptionsIfPermissive(node, () {
+      assert(() {
+        assert(_annotationTracker == null);
+        assert(_typeNameTracker == null);
+        _annotationTracker = AnnotationTracker()..visitCompilationUnit(node);
+        _typeNameTracker = TypeNameTracker()..visitCompilationUnit(node);
+        return true;
+      }());
+      try {
+        result = super.visitCompilationUnit(node);
+        assert(() {
+          _annotationTracker.finalize();
+          _typeNameTracker.finalize();
+          return true;
+        }());
+      } finally {
+        _annotationTracker = null;
+        _typeNameTracker = null;
+      }
+    });
+    return result;
+  }
+}
diff --git a/pkg/nnbd_migration/tool/src/multi_future_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart
similarity index 100%
rename from pkg/nnbd_migration/tool/src/multi_future_tracker.dart
rename to pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart
diff --git a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
new file mode 100644
index 0000000..80e3c6e
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
@@ -0,0 +1,162 @@
+// 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.
+
+// TODO(jcollins-g): Merge this with similar utilities in dartdoc
+// and extract into a separate package, generate testing and mirrors, and
+// reimport that into the SDK, before cut and paste gets out of hand.
+
+/// This is a modified version of dartdoc's
+/// SubprocessLauncher from test/src/utils.dart, for use with the
+/// nnbd_migration script.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'multi_future_tracker.dart';
+
+/// Maximum number of parallel subprocesses.  Use this to to avoid overloading
+/// your CPU.
+final MultiFutureTracker maxParallel =
+    MultiFutureTracker(Platform.numberOfProcessors * 2);
+
+/// Route all executions of pub through this [MultiFutureTracker] to avoid
+/// parallel executions of the pub command.
+final MultiFutureTracker pubTracker = MultiFutureTracker(1);
+
+final RegExp quotables = RegExp(r'[ "\r\n\$]');
+
+/// SubprocessLauncher manages one or more launched, non-interactive
+/// subprocesses.  It handles I/O streams, parses JSON output if
+/// available, and logs debugging information so the user can see exactly
+/// what was run.
+class SubprocessLauncher {
+  final String context;
+  final Map<String, String> environmentDefaults;
+
+  String get prefix => context.isNotEmpty ? '$context: ' : '';
+
+  /// From flutter:dev/tools/dartdoc.dart, modified.
+  static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
+      {String prefix = '', Iterable<String> Function(String line) filter}) {
+    assert(prefix != null);
+    if (filter == null) filter = (line) => [line];
+    return stream
+        .transform(utf8.decoder)
+        .transform(const LineSplitter())
+        .expand(filter)
+        .listen((String line) {
+      if (line != null) {
+        output.write('$prefix$line'.trim());
+        output.write('\n');
+      }
+    }).asFuture();
+  }
+
+  SubprocessLauncher(this.context, [Map<String, String> environment])
+      : this.environmentDefaults = environment ?? <String, String>{};
+
+  /// A wrapper around start/await process.exitCode that will display the
+  /// output of the executable continuously and fail on non-zero exit codes.
+  /// It will also parse any valid JSON objects (one per line) it encounters
+  /// on stdout/stderr, and return them.  Returns null if no JSON objects
+  /// were encountered, or if DRY_RUN is set to 1 in the execution environment.
+  ///
+  /// Makes running programs in grinder similar to set -ex for bash, even on
+  /// Windows (though some of the bashisms will no longer make sense).
+  /// TODO(jcollins-g): refactor to return a stream of stderr/stdout lines
+  ///                   and their associated JSON objects.
+  Future<Iterable<Map>> runStreamed(String executable, List<String> arguments,
+      {String workingDirectory,
+      Map<String, String> environment,
+      bool includeParentEnvironment = true,
+      void Function(String) perLine}) async {
+    environment ??= {};
+    environment.addAll(environmentDefaults);
+    List<Map> jsonObjects;
+
+    /// Parses json objects generated by the subprocess.  If a json object
+    /// contains the key 'message' or the keys 'data' and 'text', return that
+    /// value as a collection of lines suitable for printing.
+    Iterable<String> jsonCallback(String line) {
+      if (perLine != null) perLine(line);
+      Map result;
+      try {
+        result = json.decoder.convert(line) as Map;
+      } catch (FormatException) {
+        // ignore
+      }
+      if (result != null) {
+        jsonObjects ??= [];
+        jsonObjects.add(result);
+        if (result.containsKey('message')) {
+          line = result['message'] as String;
+        } else if (result.containsKey('data') &&
+            result['data'] is Map &&
+            (result['data'] as Map).containsKey('key')) {
+          line = result['data']['text'] as String;
+        }
+      }
+      return line.split('\n');
+    }
+
+    stderr.write('$prefix+ ');
+    if (workingDirectory != null) stderr.write('(cd "$workingDirectory" && ');
+    if (environment != null) {
+      stderr.write(environment.keys.map((String key) {
+        if (environment[key].contains(quotables)) {
+          return "$key='${environment[key]}'";
+        } else {
+          return "$key=${environment[key]}";
+        }
+      }).join(' '));
+      stderr.write(' ');
+    }
+    stderr.write('$executable');
+    if (arguments.isNotEmpty) {
+      for (String arg in arguments) {
+        if (arg.contains(quotables)) {
+          stderr.write(" '$arg'");
+        } else {
+          stderr.write(" $arg");
+        }
+      }
+    }
+    if (workingDirectory != null) stderr.write(')');
+    stderr.write('\n');
+
+    if (Platform.environment.containsKey('DRY_RUN')) return null;
+
+    String realExecutable = executable;
+    final List<String> realArguments = [];
+    if (Platform.isLinux) {
+      // Use GNU coreutils to force line buffering.  This makes sure that
+      // subprocesses that die due to fatal signals do not chop off the
+      // last few lines of their output.
+      //
+      // Dart does not actually do this (seems to flush manually) unless
+      // the VM crashes.
+      realExecutable = 'stdbuf';
+      realArguments.addAll(['-o', 'L', '-e', 'L']);
+      realArguments.add(executable);
+    }
+    realArguments.addAll(arguments);
+
+    Process process = await Process.start(realExecutable, realArguments,
+        workingDirectory: workingDirectory,
+        environment: environment,
+        includeParentEnvironment: includeParentEnvironment);
+    Future<void> stdoutFuture = _printStream(process.stdout, stdout,
+        prefix: prefix, filter: jsonCallback);
+    Future<void> stderrFuture = _printStream(process.stderr, stderr,
+        prefix: prefix, filter: jsonCallback);
+    await Future.wait([stderrFuture, stdoutFuture, process.exitCode]);
+
+    int exitCode = await process.exitCode;
+    if (exitCode != 0) {
+      throw ProcessException(executable, arguments,
+          "SubprocessLauncher got non-zero exitCode: $exitCode", exitCode);
+    }
+    return jsonObjects;
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/utilities/type_name_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/type_name_tracker.dart
new file mode 100644
index 0000000..67a1817
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/type_name_tracker.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+/// A simple class to find all [TypeName]s and track if they all get visited.
+class TypeNameTracker extends RecursiveAstVisitor<void> {
+  final Set<TypeName> _nodes = {};
+
+  bool _isTrueTypeName(TypeName node) {
+    final parent = node.parent;
+    if (parent is ConstructorName) {
+      // We only need to visit C in `new C()`, just `int` in `new C<int>()`.
+      return parent.type != node;
+    }
+
+    return true;
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    if (_isTrueTypeName(node)) {
+      _nodes.add(node);
+    }
+    super.visitTypeName(node);
+  }
+
+  void nodeVisited(TypeName node) {
+    if (_isTrueTypeName(node) && !_nodes.remove(node)) {
+      throw StateError('Visited unexpected type name $node');
+    }
+  }
+
+  void finalize() {
+    assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index d55477d..b433166 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -81,7 +81,8 @@
     var annotationsInSource = _decoratedTypeAnnotations[source];
     if (annotationsInSource == null) {
       throw StateError('No declarated type annotations in ${source.fullName}; '
-          'expected one for ${typeAnnotation.toSource()}');
+          'expected one for ${typeAnnotation.toSource()} '
+          '(offset ${typeAnnotation.offset})');
     }
     DecoratedType decoratedTypeAnnotation = annotationsInSource[
         uniqueIdentifierForSpan(typeAnnotation.offset, typeAnnotation.end)];
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index d076779..590477d 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -15,7 +15,6 @@
     defineReflectiveTests(_ProvisionalApiTest);
     defineReflectiveTests(_ProvisionalApiTestPermissive);
     defineReflectiveTests(_ProvisionalApiTestWithReset);
-    defineReflectiveTests(_ProvisionalApiTestWithFixBuilder);
   });
 }
 
@@ -24,16 +23,11 @@
 class _ProvisionalApiTest extends _ProvisionalApiTestBase
     with _ProvisionalApiTestCases {
   @override
-  bool get _useFixBuilder => false;
-
-  @override
   bool get _usePermissiveMode => false;
 }
 
 /// Base class for provisional API tests.
 abstract class _ProvisionalApiTestBase extends AbstractContextTest {
-  bool get _useFixBuilder;
-
   bool get _usePermissiveMode;
 
   /// Hook invoked between stages of processing inputs.
@@ -52,9 +46,7 @@
     }
     var listener = new TestMigrationListener();
     var migration = NullabilityMigration(listener,
-        permissive: _usePermissiveMode,
-        useFixBuilder: _useFixBuilder,
-        removeViaComments: removeViaComments);
+        permissive: _usePermissiveMode, removeViaComments: removeViaComments);
     for (var path in input.keys) {
       migration.prepareInput(await session.getResolvedUnit(path));
     }
@@ -107,6 +99,28 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39404')
+  Future<void> test_add_type_parameter_bound() async {
+    /// After a migration, a bound may be made nullable. Instantiate-to-bounds
+    /// may need to be made explicit where the migration engine prefers a
+    /// non-null type.
+    var content = '''
+class C<T extends num/*?*/> {}
+
+void main() {
+  C c = C();
+}
+''';
+    var expected = '''
+class C<T extends num?/*?*/> {}
+
+void main() {
+  C<num> c = C();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_as_allows_null() async {
     var content = '''
 int f(Object o) => (o as int)?.gcd(1);
@@ -438,6 +452,36 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_conditionalExpression_typeParameter_bound() async {
+    var content = '''
+num f1<T extends num>(bool b, num x, T y) => b ? x : y;
+num f2<T extends num>(bool b, num x, T y) => b ? x : y;
+num f3<T extends num>(bool b, num x, T y) => b ? x : y;
+num f4<T extends num>(bool b, num x, T y) => b ? x : y;
+
+void main() {
+  int x1 = f1<int/*?*/>(true, 0, null);
+  int x2 = f2<int/*!*/>(true, 0, null);
+  int x3 = f3<int>(true, null, 0);
+  int x4 = f4<int>(true, 0, 0);
+}
+''';
+    var expected = '''
+num? f1<T extends num?>(bool b, num x, T y) => b ? x : y;
+num? f2<T extends num>(bool b, num x, T? y) => b ? x : y;
+num? f3<T extends num>(bool b, num? x, T y) => b ? x : y;
+num f4<T extends num>(bool b, num x, T y) => b ? x : y;
+
+void main() {
+  int? x1 = f1<int?/*?*/>(true, 0, null);
+  int? x2 = f2<int/*!*/>(true, 0, null);
+  int? x3 = f3<int>(true, null, 0);
+  int x4 = f4<int>(true, 0, 0);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_constructorDeclaration_factory_non_null_return() async {
     var content = '''
 class C {
@@ -520,7 +564,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38462')
   Future<void> test_convert_required() async {
     addMetaPackage();
     var content = '''
@@ -1000,7 +1043,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  Future<void> test_discard_simple_condition() async {
+  Future<void> test_discard_simple_condition_keep_else() async {
     var content = '''
 int f(int i) {
   if (i == null) {
@@ -1023,6 +1066,29 @@
     await _checkSingleFileChanges(content, expected, removeViaComments: true);
   }
 
+  Future<void> test_discard_simple_condition_keep_then() async {
+    var content = '''
+int f(int i) {
+  if (i != null) {
+    return i + 1;
+  } else {
+    return null;
+  }
+}
+''';
+
+    var expected = '''
+int f(int i) {
+  /* if (i != null) {
+    */ return i + 1; /*
+  } else {
+    return null;
+  } */
+}
+''';
+    await _checkSingleFileChanges(content, expected, removeViaComments: true);
+  }
+
   Future<void> test_downcast_dynamic_function_to_functionType() async {
     var content = '''
 void f(Function a) {
@@ -1404,6 +1470,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40023')
   Future<void> test_extension_nullableOnType_viaImplicitInvocation() async {
     var content = '''
 class C {}
@@ -2002,6 +2069,7 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39404')
   Future<void> test_genericType_noTypeArguments_use_bound() async {
     var content = '''
 abstract class C<T extends Object> { // (1)
@@ -2102,7 +2170,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38472')
   Future<void> test_ifStatement_nullCheck_noElse() async {
     var content = '''
 int f(int x) {
@@ -2457,6 +2524,56 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_issue_40181() async {
+    // This contrived example created an "exact nullable" type parameter bound
+    // which propagated back to *all* instantiations of that parameter.
+    var content = '''
+class B<T extends Object> {
+  B([C<T> t]);
+}
+
+abstract class C<T extends Object> {
+  void f(T t);
+}
+
+class E {
+  final C<Object> _base;
+  E([C base]) : _base = base;
+  f(Object t) {
+    _base.f(t);
+  }
+}
+
+void main() {
+  E e = E();
+  e.f(null);
+}
+''';
+    var expected = '''
+class B<T extends Object> {
+  B([C<T>? t]);
+}
+
+abstract class C<T extends Object?> {
+  void f(T t);
+}
+
+class E {
+  final C<Object?>? _base;
+  E([C? base]) : _base = base;
+  f(Object? t) {
+    _base!.f(t);
+  }
+}
+
+void main() {
+  E e = E();
+  e.f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_libraryWithParts() async {
     var root = '/home/test/lib';
     var path1 = convertPath('$root/lib.dart');
@@ -2808,7 +2925,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38462')
   Future<void> test_named_parameter_no_default_unused_required() async {
     // The `@required` annotation overrides the assumption of nullability.
     // The call at `f()` is presumed to be in error.
@@ -3523,7 +3639,50 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @failingTest
+  Future<void> test_remove_question_from_question_dot() async {
+    var content = '_f(int/*!*/ i) => i?.isEven;';
+    var expected = '_f(int/*!*/ i) => i.isEven;';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_remove_question_from_question_dot_and_add_bang() async {
+    var content = '''
+class C {
+  int/*?*/ i;
+}
+int/*!*/ f(C/*!*/ c) => c?.i;
+''';
+    var expected = '''
+class C {
+  int?/*?*/ i;
+}
+int/*!*/ f(C/*!*/ c) => c.i!;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_remove_question_from_question_dot_method() async {
+    var content = '_f(int/*!*/ i) => i?.abs();';
+    var expected = '_f(int/*!*/ i) => i.abs();';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_remove_question_from_question_dot_shortcut() async {
+    var content = '''
+class C {
+  int/*!*/ i;
+}
+bool/*?*/ f(C/*?*/ c) => c?.i?.isEven;
+''';
+    var expected = '''
+class C {
+  int/*!*/ i;
+}
+bool?/*?*/ f(C?/*?*/ c) => c?.i.isEven;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_removed_if_element_doesnt_introduce_nullability() async {
     // Failing because we don't yet remove the dead list element
     // `if (x == null) recover()`.
@@ -3695,6 +3854,300 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_typedef_assign_null_complex() async {
+    var content = '''
+typedef F<R> = Function(R);
+
+class C<T> {
+  F<T> _f;
+
+  C(this._f) {
+    f(null);
+  }
+
+  f(Object o) {
+    _f(o as T);
+  }
+}
+''';
+    var expected = '''
+typedef F<R> = Function(R);
+
+class C<T> {
+  F<T?> _f;
+
+  C(this._f) {
+    f(null);
+  }
+
+  f(Object? o) {
+    _f(o as T?);
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_parameter() async {
+    var content = '''
+typedef F = Function(int);
+
+F/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F = Function(int?);
+
+F/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_return() async {
+    var content = '''
+typedef F = int Function();
+
+F _f = () => null;
+''';
+    var expected = '''
+typedef F = int? Function();
+
+F _f = () => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_return_type_formal() async {
+    var content = '''
+typedef F = T Function<T>();
+
+F _f = <T>() => null;
+''';
+    var expected = '''
+typedef F = T? Function<T>();
+
+F _f = <T>() => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_return_type_parameter() async {
+    var content = '''
+typedef F<T> = T Function();
+
+F<int> _f = () => null;
+''';
+    var expected = '''
+typedef F<T> = T Function();
+
+F<int?> _f = () => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_type_formal() async {
+    var content = '''
+typedef F = Function<T>(T);
+
+F/*!*/ _f;
+
+f() {
+  _f<int>(null);
+}
+''';
+    var expected = '''
+typedef F = Function<T>(T);
+
+F/*!*/ _f;
+
+f() {
+  _f<int?>(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_type_formal_with_paramter() async {
+    var content = '''
+typedef F<R> = Function<T>(T);
+
+F<Object>/*!*/ _f;
+
+f() {
+  _f<int>(null);
+}
+''';
+    var expected = '''
+typedef F<R> = Function<T>(T);
+
+F<Object>/*!*/ _f;
+
+f() {
+  _f<int?>(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_type_parameter() async {
+    var content = '''
+typedef F<T> = Function(T);
+
+F<int>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F<T> = Function(T);
+
+F<int?>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_type_parameter_non_null() async {
+    var content = '''
+typedef F<T> = Function(T);
+
+F<int>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F<T> = Function(T);
+
+F<int?>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_assign_null_type_return_value_nested() async {
+    var content = '''
+typedef F<T> = T Function();
+
+F<F<int>> f = () => () => null;
+''';
+    var expected = '''
+typedef F<T> = T Function();
+
+F<F<int?>> f = () => () => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_old_assign_null_parameter() async {
+    var content = '''
+typedef F(int x);
+
+F/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F(int? x);
+
+F/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_old_assign_null_return() async {
+    var content = '''
+typedef int F();
+
+F _f = () => null;
+''';
+    var expected = '''
+typedef int? F();
+
+F _f = () => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_old_assign_null_return_type_parameter() async {
+    var content = '''
+typedef T F<T>();
+
+F<int> _f = () => null;
+''';
+    var expected = '''
+typedef T F<T>();
+
+F<int?> _f = () => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_old_assign_null_type_parameter() async {
+    var content = '''
+typedef F<T>(T t);
+
+F<int>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F<T>(T t);
+
+F<int?>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_typedef_old_assign_null_type_parameter_non_null() async {
+    var content = '''
+typedef F<T>(T t);
+
+F<int>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    var expected = '''
+typedef F<T>(T t);
+
+F<int?>/*!*/ _f;
+
+f() {
+  _f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void>
       test_unconditional_assert_statement_implies_non_null_intent() async {
     var content = '''
@@ -4044,7 +4497,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38472')
   Future<void> test_unnecessary_cast_remove() async {
     var content = '''
 _f(Object x) {
@@ -4066,9 +4518,6 @@
 class _ProvisionalApiTestPermissive extends _ProvisionalApiTestBase
     with _ProvisionalApiTestCases {
   @override
-  bool get _useFixBuilder => false;
-
-  @override
   bool get _usePermissiveMode => true;
 
   // TODO(danrubel): Remove this once the superclass test has been fixed.
@@ -4078,45 +4527,6 @@
   }
 }
 
-@reflectiveTest
-class _ProvisionalApiTestWithFixBuilder extends _ProvisionalApiTestBase
-    with _ProvisionalApiTestCases {
-  @override
-  bool get _useFixBuilder => true;
-
-  @override
-  bool get _usePermissiveMode => false;
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_convert_required() => super.test_convert_required();
-
-  @override
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40023')
-  Future<void> test_extension_nullableOnType_viaImplicitInvocation() =>
-      super.test_extension_nullableOnType_viaImplicitInvocation();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_ifStatement_nullCheck_noElse() =>
-      super.test_ifStatement_nullCheck_noElse();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_named_parameter_no_default_unused_required() =>
-      super.test_named_parameter_no_default_unused_required();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_removed_if_element_doesnt_introduce_nullability() =>
-      super.test_removed_if_element_doesnt_introduce_nullability();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_unnecessary_cast_remove() =>
-      super.test_unnecessary_cast_remove();
-}
-
 /// Tests of the provisional API, where the driver is reset between calls to
 /// `prepareInput` and `processInput`, ensuring that the migration algorithm
 /// sees different AST and element objects during different phases.
@@ -4124,9 +4534,6 @@
 class _ProvisionalApiTestWithReset extends _ProvisionalApiTestBase
     with _ProvisionalApiTestCases {
   @override
-  bool get _useFixBuilder => false;
-
-  @override
   bool get _usePermissiveMode => false;
 
   @override
diff --git a/pkg/nnbd_migration/test/api_test_base.dart b/pkg/nnbd_migration/test/api_test_base.dart
index 7e05f35..664a411 100644
--- a/pkg/nnbd_migration/test/api_test_base.dart
+++ b/pkg/nnbd_migration/test/api_test_base.dart
@@ -24,6 +24,6 @@
   @override
   void reportException(
       Source source, AstNode node, Object exception, StackTrace stackTrace) {
-    fail('Exception reported: $exception');
+    fail('Exception reported: $exception\n$stackTrace');
   }
 }
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 71b31b2..d72d823 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2,7 +2,6 @@
 // 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/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -700,6 +699,332 @@
         hard: false);
   }
 
+  Future<void> test_assign_to_bound_as() async {
+    // TODO(mfairhurst): support downcast to type params with bounds
+    await analyze('''
+class C<T> {}
+void f(Object o) {
+  o as C<int>;
+}
+''');
+    // For now, edge to `anyNode`, because the true bound is inferred.
+    assertEdge(decoratedTypeAnnotation('int').node, anyNode, hard: true);
+  }
+
+  Future<void> test_assign_to_bound_class_alias() async {
+    await analyze('''
+class C<T extends Object/*1*/> {}
+class D<T extends Object/*2*/> {}
+mixin M<T extends Object/*3*/> {}
+class F = C<int> with M<String> implements D<num>;
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object/*1*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('num').node,
+        decoratedTypeAnnotation('Object/*2*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('String').node,
+        decoratedTypeAnnotation('Object/*3*/').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_class_extends() async {
+    await analyze('''
+class A<T extends Object> {}
+class C extends A<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_class_implements() async {
+    await analyze('''
+class A<T extends Object> {}
+class C implements A<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_class_with() async {
+    await analyze('''
+class A<T extends Object> {}
+class C extends Object with A<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_extension_extended_type() async {
+    await analyze('''
+class C<T extends Object> {}
+extension E on C<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_field_formal_typed() async {
+    await analyze('''
+class C<T extends Object> {}
+class D {
+  dynamic i;
+  D(C<int> this.i);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_field_formal_typed_function() async {
+    await analyze('''
+class C<T extends Object> {}
+class D {
+  dynamic i;
+  D(this.i(C<int> name));
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_for() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  for (C<int> c = null ;;) {}
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_for_element() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  [for (C<int> c = null ;;) c];
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_for_in() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  for (C<int> c in []) {}
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_for_in_element() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  [for (C<int> c in []) c];
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_function_invocation_type_argument() async {
+    await analyze('''
+void f<T extends Object>() {}
+void main() {
+  (f)<int>();
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_in_type_argument() async {
+    await analyze('''
+class C<T extends Object> {}
+C<C<int>> f() => null;
+''');
+    assertEdge(decoratedTypeAnnotation('C<int>').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_in_return_type() async {
+    await analyze('''
+class C<T extends Object> {}
+C<int> f() => null;
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_instance_creation() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  C<int>();
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_list_literal() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  <C<int>>[];
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_local_variable() async {
+    await analyze('''
+class C<T extends Object> {}
+main() {
+  C<int> c = null;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_map_literal() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  <C<int>, C<String>>{};
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('String').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_method_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+class D {
+  f<U extends C<int>>() {}
+}
+''');
+  }
+
+  Future<void> test_assign_to_bound_method_call_type_argument() async {
+    await analyze('''
+void f<T extends Object>() {}
+void main() {
+  f<int>();
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_mixin_implements() async {
+    await analyze('''
+class A<T extends Object> {}
+mixin C implements A<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_mixin_on() async {
+    await analyze('''
+class A<T extends Object> {}
+mixin C on A<int> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_mixin_type_parameter_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+mixin M<T extends C<int>> {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_redirecting_constructor_argument() async {
+    await analyze('''
+class A<T extends Object> {}
+class C {
+  factory C() = D<A<int>>;
+}
+class D<U> implements C {}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_set_literal() async {
+    await analyze('''
+class C<T extends Object> {}
+void main() {
+  <C<int>>{};
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int').node,
+        decoratedTypeAnnotation('Object').node,
+        hard: true);
+  }
+
+  Future<void> test_assign_to_bound_within_bound() async {
+    await analyze('''
+class A<T extends Object> {}
+class B<T extends A<int>> {}
+  ''');
+    var aBound = decoratedTypeAnnotation('Object').node;
+    var aBoundInt = decoratedTypeAnnotation('int').node;
+    assertEdge(aBoundInt, aBound, hard: true);
+  }
+
+  Future<void> test_assign_to_bound_within_bound_method() async {
+    await analyze('''
+class C<T extends Object> {}
+void f<T extends C<int>>() {}
+''');
+    var cBound = decoratedTypeAnnotation('Object').node;
+    var fcInt = decoratedTypeAnnotation('int').node;
+    assertEdge(fcInt, cBound, hard: true);
+  }
+
   Future<void> test_assign_type_parameter_to_bound() async {
     await analyze('''
 class C<T extends List<int>> {
@@ -1778,6 +2103,22 @@
         substitutionNode(bType.typeArguments[0].node, bInA.node));
   }
 
+  Future<void> test_conditionalExpression_generic_typeParameter_bound() async {
+    await analyze('''
+List<num> f<T extends List<num>>(bool b, List<num> x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('List<num> x');
+    var bType = decoratedTypeAnnotation('T y');
+    var bBound = decoratedTypeAnnotation('List<num>>');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(
+        resultType.node, aType.node, substitutionNode(bBound.node, bType.node));
+    assertLUB(resultType.typeArguments[0].node, aType.typeArguments[0].node,
+        bBound.typeArguments[0].node);
+  }
+
   Future<void> test_conditionalExpression_left_non_null() async {
     await analyze('''
 int f(bool b, int i) {
@@ -1937,6 +2278,83 @@
     assertLUB(nullable_conditional, nullable_t, inSet(alwaysPlus));
   }
 
+  Future<void> test_conditionalExpression_typeParameter_bound() async {
+    await analyze('''
+num f<T extends num>(bool b, num x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('num x');
+    var bType = decoratedTypeAnnotation('T y');
+    var bBound = decoratedTypeAnnotation('num>');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(
+        resultType.node, aType.node, substitutionNode(bBound.node, bType.node));
+  }
+
+  Future<void> test_conditionalExpression_typeParameter_bound_bound() async {
+    await analyze('''
+num f<T extends R, R extends num>(bool b, num x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('num x');
+    var bType = decoratedTypeAnnotation('T y');
+    var bBound = decoratedTypeAnnotation('R,');
+    var bBoundBound = decoratedTypeAnnotation('num>');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(
+        resultType.node,
+        aType.node,
+        substitutionNode(
+            bBoundBound.node, substitutionNode(bBound.node, bType.node)));
+  }
+
+  Future<void> test_conditionalExpression_typeParameter_dynamic() async {
+    // "dynamic" can short circuit LUB, incorrectly we may lose nullabilities.
+    await analyze('''
+dynamic f<T extends num>(bool b, dynamic x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('dynamic x');
+    var bType = decoratedTypeAnnotation('T y');
+    var bBound = decoratedTypeAnnotation('num>');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(
+        resultType.node, aType.node, substitutionNode(bBound.node, bType.node));
+  }
+
+  Future<void> test_conditionalExpression_typeParameters_bound() async {
+    await analyze('''
+num f<T extends num, R extends num>(bool b, R x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('R x');
+    var bType = decoratedTypeAnnotation('T y');
+    var aBound = decoratedTypeAnnotation('num>');
+    var bBound = decoratedTypeAnnotation('num,');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, substitutionNode(aBound.node, aType.node),
+        substitutionNode(bBound.node, bType.node));
+  }
+
+  Future<void>
+      test_conditionalExpression_typeParameters_bound_left_to_right() async {
+    await analyze('''
+R f<T extends R, R>(bool b, R x, T y) {
+  return (b ? x : y);
+}
+''');
+    var aType = decoratedTypeAnnotation('R x');
+    var bType = decoratedTypeAnnotation('T y');
+    var bBound = decoratedTypeAnnotation('R,');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(
+        resultType.node, aType.node, substitutionNode(bBound.node, bType.node));
+  }
+
   Future<void> test_constructor_default_parameter_value_bool() async {
     await analyze('''
 class C {
@@ -5605,7 +6023,8 @@
     await analyze('''
 Future<int> f() async => throw '';
 ''');
-    assertNoEdge(always, anyNode);
+    assertNoEdge(always, decoratedTypeAnnotation('Future<int>').node);
+    assertNoEdge(always, decoratedTypeAnnotation('int').node);
   }
 
   Future<void> test_return_from_async_closureBody_future() async {
@@ -6415,28 +6834,29 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
   }
 
-  Future<void> test_typeName_union_with_bound() async {
+  Future<void> test_typeName_with_bound() async {
     await analyze('''
 class C<T extends Object> {}
 void f(C c) {}
 ''');
     var cType = decoratedTypeAnnotation('C c');
     var cBound = decoratedTypeAnnotation('Object');
-    assertUnion(cType.typeArguments[0].node, cBound.node);
+    assertEdge(cType.typeArguments[0].node, cBound.node, hard: true);
   }
 
-  Future<void> test_typeName_union_with_bound_function_type() async {
+  Future<void> test_typeName_with_bound_function_type() async {
     await analyze('''
 class C<T extends int Function()> {}
 void f(C c) {}
 ''');
     var cType = decoratedTypeAnnotation('C c');
     var cBound = decoratedGenericFunctionTypeAnnotation('int Function()');
-    assertUnion(cType.typeArguments[0].node, cBound.node);
-    assertUnion(cType.typeArguments[0].returnType.node, cBound.returnType.node);
+    assertEdge(cType.typeArguments[0].node, cBound.node, hard: true);
+    assertEdge(cType.typeArguments[0].returnType.node, cBound.returnType.node,
+        hard: true);
   }
 
-  Future<void> test_typeName_union_with_bounds() async {
+  Future<void> test_typeName_with_bounds() async {
     await analyze('''
 class C<T extends Object, U extends Object> {}
 void f(C c) {}
@@ -6444,8 +6864,8 @@
     var cType = decoratedTypeAnnotation('C c');
     var tBound = decoratedTypeAnnotation('Object,');
     var uBound = decoratedTypeAnnotation('Object>');
-    assertUnion(cType.typeArguments[0].node, tBound.node);
-    assertUnion(cType.typeArguments[1].node, uBound.node);
+    assertEdge(cType.typeArguments[0].node, tBound.node, hard: true);
+    assertEdge(cType.typeArguments[1].node, uBound.node, hard: true);
   }
 
   Future<void> test_variableDeclaration() async {
diff --git a/pkg/nnbd_migration/test/edit_plan_test.dart b/pkg/nnbd_migration/test/edit_plan_test.dart
index 85538b8..8833866 100644
--- a/pkg/nnbd_migration/test/edit_plan_test.dart
+++ b/pkg/nnbd_migration/test/edit_plan_test.dart
@@ -947,6 +947,106 @@
     expect(changes.keys, [declaration.offset]);
   }
 
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_change_arguments() async {
+    await analyze('f(x) => x?.m(0);');
+    var methodInvocation = findNode.methodInvocation('?.');
+    checkPlan(
+        planner.removeNullAwarenessFromMethodInvocation(methodInvocation,
+            argumentListPlan:
+                planner.passThrough(methodInvocation.argumentList, innerPlans: [
+              planner.replace(
+                  findNode.integerLiteral('0'), [AtomicEdit.insert('1')])
+            ])),
+        'f(x) => x.m(1);');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_change_methodName() async {
+    await analyze('f(x) => x?.m();');
+    checkPlan(
+        planner.removeNullAwarenessFromMethodInvocation(
+            findNode.methodInvocation('?.'),
+            methodNamePlan: planner
+                .replace(findNode.simple('m'), [AtomicEdit.insert('n')])),
+        'f(x) => x.n();');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_change_target() async {
+    await analyze('f(x) => x?.m();');
+    checkPlan(
+        planner.removeNullAwarenessFromMethodInvocation(
+            findNode.methodInvocation('?.'),
+            targetPlan: planner
+                .replace(findNode.simple('x?.'), [AtomicEdit.insert('y')])),
+        'f(x) => y.m();');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_change_typeArguments() async {
+    await analyze('f(x) => x?.m<int>();');
+    var methodInvocation = findNode.methodInvocation('?.');
+    checkPlan(
+        planner.removeNullAwarenessFromMethodInvocation(methodInvocation,
+            typeArgumentsPlan: planner
+                .passThrough(methodInvocation.typeArguments, innerPlans: [
+              planner
+                  .replace(findNode.simple('int'), [AtomicEdit.insert('num')])
+            ])),
+        'f(x) => x.m<num>();');
+  }
+
+  Future<void> test_removeNullAwarenessFromMethodInvocation_simple() async {
+    await analyze('f(x) => x?.m();');
+    checkPlan(
+        planner.removeNullAwarenessFromMethodInvocation(
+            findNode.methodInvocation('?.')),
+        'f(x) => x.m();');
+  }
+
+  Future<void> test_removeNullAwarenessFromPropertyAccess_change_both() async {
+    await analyze('f(x) => x?.y;');
+    checkPlan(
+        planner.removeNullAwarenessFromPropertyAccess(
+            findNode.propertyAccess('?.'),
+            targetPlan: planner
+                .replace(findNode.simple('x?.'), [AtomicEdit.insert('z')]),
+            propertyNamePlan: planner
+                .replace(findNode.simple('y'), [AtomicEdit.insert('w')])),
+        'f(x) => z.w;');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromPropertyAccess_change_propertyName() async {
+    await analyze('f(x) => x?.y;');
+    checkPlan(
+        planner.removeNullAwarenessFromPropertyAccess(
+            findNode.propertyAccess('?.'),
+            propertyNamePlan: planner
+                .replace(findNode.simple('y'), [AtomicEdit.insert('w')])),
+        'f(x) => x.w;');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromPropertyAccess_change_target() async {
+    await analyze('f(x) => x?.y;');
+    checkPlan(
+        planner.removeNullAwarenessFromPropertyAccess(
+            findNode.propertyAccess('?.'),
+            targetPlan: planner
+                .replace(findNode.simple('x?.'), [AtomicEdit.insert('z')])),
+        'f(x) => z.y;');
+  }
+
+  Future<void> test_removeNullAwarenessFromPropertyAccess_simple() async {
+    await analyze('f(x) => x?.y;');
+    checkPlan(
+        planner.removeNullAwarenessFromPropertyAccess(
+            findNode.propertyAccess('?.')),
+        'f(x) => x.y;');
+  }
+
   Future<void> test_replace_expression() async {
     await analyze('var x = 1 + 2 * 3;');
     checkPlan(planner.replace(findNode.binary('*'), [AtomicEdit.insert('6')]),
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index 4beab66..cea68fe 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -447,6 +447,69 @@
     expect(previewInfo.applyTo(code), 'f(a, b, c) => a < b | c;');
   }
 
+  Future<void> test_removeNullAwarenessFromMethodInvocation() async {
+    await analyze('f(x) => x?.m();');
+    var methodInvocation = findNode.methodInvocation('?.');
+    var previewInfo = run(
+        {methodInvocation: const RemoveNullAwarenessFromMethodInvocation()});
+    expect(previewInfo.applyTo(code), 'f(x) => x.m();');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_changeArgument() async {
+    await analyze('f(x) => x?.m(x);');
+    var methodInvocation = findNode.methodInvocation('?.');
+    var argument = findNode.simple('x);');
+    var previewInfo = run({
+      methodInvocation: const RemoveNullAwarenessFromMethodInvocation(),
+      argument: const NullCheck(null)
+    });
+    expect(previewInfo.applyTo(code), 'f(x) => x.m(x!);');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_changeTarget() async {
+    await analyze('f(x) => (x as dynamic)?.m();');
+    var methodInvocation = findNode.methodInvocation('?.');
+    var cast = findNode.as_('as');
+    var previewInfo = run({
+      methodInvocation: const RemoveNullAwarenessFromMethodInvocation(),
+      cast: const RemoveAs()
+    });
+    expect(previewInfo.applyTo(code), 'f(x) => x.m();');
+  }
+
+  Future<void>
+      test_removeNullAwarenessFromMethodInvocation_changeTypeArgument() async {
+    await analyze('f(x) => x?.m<int>();');
+    var methodInvocation = findNode.methodInvocation('?.');
+    var typeAnnotation = findNode.typeAnnotation('int');
+    var previewInfo = run({
+      methodInvocation: const RemoveNullAwarenessFromMethodInvocation(),
+      typeAnnotation: const MakeNullable(MockDecoratedType(MockDartType()))
+    });
+    expect(previewInfo.applyTo(code), 'f(x) => x.m<int?>();');
+  }
+
+  Future<void> test_removeNullAwarenessFromPropertyAccess() async {
+    await analyze('f(x) => x?.y;');
+    var propertyAccess = findNode.propertyAccess('?.');
+    var previewInfo =
+        run({propertyAccess: const RemoveNullAwarenessFromPropertyAccess()});
+    expect(previewInfo.applyTo(code), 'f(x) => x.y;');
+  }
+
+  Future<void> test_removeNullAwarenessFromPropertyAccess_changeTarget() async {
+    await analyze('f(x) => (x as dynamic)?.y;');
+    var propertyAccess = findNode.propertyAccess('?.');
+    var cast = findNode.as_('as');
+    var previewInfo = run({
+      propertyAccess: const RemoveNullAwarenessFromPropertyAccess(),
+      cast: const RemoveAs()
+    });
+    expect(previewInfo.applyTo(code), 'f(x) => x.y;');
+  }
+
   Future<void> test_requiredAnnotationToRequiredKeyword_prefixed() async {
     addMetaPackage();
     await analyze('''
@@ -513,6 +576,8 @@
 }
 
 class MockDartType implements DartType {
+  const MockDartType();
+
   @override
   noSuchMethod(Invocation invocation) {
     return super.noSuchMethod(invocation);
@@ -523,7 +588,7 @@
   @override
   final DartType type;
 
-  MockDecoratedType(this.type);
+  const MockDecoratedType(this.type);
 
   @override
   NullabilityNode get node => NullabilityNode.forTypeAnnotation(0);
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 370d4ce..f33574c 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -38,16 +38,25 @@
 
 @reflectiveTest
 class FixBuilderTest extends EdgeBuilderTestBase {
-  static const isNullCheck = TypeMatcher<NullCheck>();
+  static final isAddRequiredKeyword =
+      havingInnerMatcher(TypeMatcher<AddRequiredKeyword>(), isNoChange);
 
-  static const isAddRequiredKeyword = TypeMatcher<AddRequiredKeyword>();
+  static final isMakeNullable =
+      havingInnerMatcher(TypeMatcher<MakeNullable>(), isNoChange);
 
-  static const isMakeNullable = TypeMatcher<MakeNullable>();
+  static const isNoChange = TypeMatcher<NoChange>();
 
-  static const isRemoveAs = TypeMatcher<RemoveAs>();
+  static final isNullCheck =
+      havingInnerMatcher(TypeMatcher<NullCheck>(), isNoChange);
 
-  static const isRequiredAnnotationToRequiredKeyword =
-      TypeMatcher<RequiredAnnotationToRequiredKeyword>();
+  static const isRemoveNullAwarenessFromPropertyAccess =
+      TypeMatcher<RemoveNullAwarenessFromPropertyAccess>();
+
+  static final isRemoveAs =
+      havingInnerMatcher(TypeMatcher<RemoveAs>(), isNoChange);
+
+  static final isRequiredAnnotationToRequiredKeyword = havingInnerMatcher(
+      TypeMatcher<RequiredAnnotationToRequiredKeyword>(), isNoChange);
 
   DartType get dynamicType => postMigrationTypeProvider.dynamicType;
 
@@ -2251,6 +2260,41 @@
         findNode.propertyAccess('c?.toString'), 'String Function()?');
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40313')
+  Future<void> test_propertyAccess_nullAware_potentiallyNullable() async {
+    // In the code example below, the `?.` is not changed to `.` because `T`
+    // might be instantiated to `int?`, in which case the null check is still
+    // needed.
+    await analyze('''
+class C<T extends int/*?*/> {
+  f(T t) => t?.isEven;
+}
+''');
+    visitSubexpression(findNode.propertyAccess('?.'), 'bool?');
+  }
+
+  Future<void> test_propertyAccess_nullAware_removeNullAwareness() async {
+    await analyze('_f(int/*!*/ i) => i?.isEven;');
+    var propertyAccess = findNode.propertyAccess('?.');
+    visitSubexpression(propertyAccess, 'bool',
+        changes: {propertyAccess: isRemoveNullAwarenessFromPropertyAccess});
+  }
+
+  Future<void>
+      test_propertyAccess_nullAware_removeNullAwareness_nullCheck() async {
+    await analyze('''
+class C {
+  int/*?*/ i;
+}
+int/*!*/ f(C/*!*/ c) => c?.i;
+''');
+    var propertyAccess = findNode.propertyAccess('?.');
+    visitSubexpression(propertyAccess, 'int', changes: {
+      propertyAccess: havingInnerMatcher(const TypeMatcher<NullCheck>(),
+          isRemoveNullAwarenessFromPropertyAccess)
+    });
+  }
+
   Future<void> test_propertyAccess_nullAware_substituted() async {
     await analyze('''
 abstract class _C<T> {
@@ -2622,7 +2666,7 @@
       {Map<AstNode, Matcher> changes = const <Expression, Matcher>{},
       Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
     var fixBuilder = _createFixBuilder(testUnit);
-    fixBuilder.visitAll(testUnit);
+    fixBuilder.visitAll();
     expect(scopedChanges(fixBuilder, testUnit), changes);
     expect(scopedProblems(fixBuilder, testUnit), problems);
   }
@@ -2632,7 +2676,7 @@
       {Map<AstNode, Matcher> changes = const <Expression, Matcher>{},
       Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
     var fixBuilder = _createFixBuilder(node);
-    fixBuilder.visitAll(node.thisOrAncestorOfType<CompilationUnit>());
+    fixBuilder.visitAll();
     var targetInfo = _computeAssignmentTargetInfo(node, fixBuilder);
     if (expectedReadType == null) {
       expect(targetInfo.readType, null);
@@ -2650,7 +2694,7 @@
       {Map<AstNode, Matcher> changes = const <Expression, Matcher>{},
       Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
     var fixBuilder = _createFixBuilder(node);
-    fixBuilder.visitAll(node.thisOrAncestorOfType<CompilationUnit>());
+    fixBuilder.visitAll();
     expect(scopedChanges(fixBuilder, node), changes);
     expect(scopedProblems(fixBuilder, node), problems);
   }
@@ -2659,7 +2703,7 @@
       {Map<AstNode, Matcher> changes = const <Expression, Matcher>{},
       Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
     var fixBuilder = _createFixBuilder(node);
-    fixBuilder.visitAll(node.thisOrAncestorOfType<CompilationUnit>());
+    fixBuilder.visitAll();
     var type = node.staticType;
     expect(type.getDisplayString(withNullability: true), expectedType);
     expect(scopedChanges(fixBuilder, node), changes);
@@ -2670,7 +2714,7 @@
       {Map<AstNode, Matcher> changes = const <AstNode, Matcher>{},
       Map<AstNode, Set<Problem>> problems = const <AstNode, Set<Problem>>{}}) {
     var fixBuilder = _createFixBuilder(node);
-    fixBuilder.visitAll(node.thisOrAncestorOfType<CompilationUnit>());
+    fixBuilder.visitAll();
     var type = node.type;
     expect(type.getDisplayString(withNullability: true), expectedType);
     expect(scopedChanges(fixBuilder, node), changes);
@@ -2694,8 +2738,15 @@
   FixBuilder _createFixBuilder(AstNode scope) {
     var unit = scope.thisOrAncestorOfType<CompilationUnit>();
     var definingLibrary = unit.declaredElement.library;
-    return FixBuilder(testSource, decoratedClassHierarchy, typeProvider,
-        typeSystem, variables, definingLibrary);
+    return FixBuilder(
+        testSource,
+        decoratedClassHierarchy,
+        typeProvider,
+        typeSystem,
+        variables,
+        definingLibrary,
+        null,
+        scope.thisOrAncestorOfType<CompilationUnit>());
   }
 
   bool _isInScope(AstNode node, AstNode scope) {
@@ -2704,6 +2755,11 @@
         null;
   }
 
+  static TypeMatcher<NestableChange> havingInnerMatcher(
+          TypeMatcher<NestableChange> typeMatcher, Matcher innerMatcher) =>
+      typeMatcher.having(
+          (nullCheck) => nullCheck.inner, 'inner change', innerMatcher);
+
   static Matcher isEliminateDeadIf(bool knownValue) =>
       TypeMatcher<EliminateDeadIf>()
           .having((c) => c.conditionValue, 'conditionValue', knownValue);
diff --git a/pkg/nnbd_migration/test/instrumentation_test.dart b/pkg/nnbd_migration/test/instrumentation_test.dart
index 473b669..a99d220 100644
--- a/pkg/nnbd_migration/test/instrumentation_test.dart
+++ b/pkg/nnbd_migration/test/instrumentation_test.dart
@@ -19,7 +19,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(_InstrumentationTest);
-    defineReflectiveTests(_InstrumentationTestWithFixBuilder);
   });
 }
 
@@ -94,16 +93,19 @@
   }
 
   @override
+  void prepareForUpdate() {
+    test.changes = null;
+    test.propagationSteps.clear();
+  }
+
+  @override
   void propagationStep(PropagationInfo info) {
     test.propagationSteps.add(info);
   }
 }
 
 @reflectiveTest
-class _InstrumentationTest extends _InstrumentationTestBase {
-  @override
-  bool get useFixBuilder => false;
-}
+class _InstrumentationTest extends _InstrumentationTestBase {}
 
 abstract class _InstrumentationTestBase extends AbstractContextTest {
   NullabilityNodeInfo always;
@@ -135,15 +137,13 @@
 
   Source source;
 
-  bool get useFixBuilder;
-
-  Future<void> analyze(String content) async {
+  Future<void> analyze(String content, {bool removeViaComments = false}) async {
     var sourcePath = convertPath('/home/test/lib/test.dart');
     newFile(sourcePath, content: content);
     var listener = new TestMigrationListener();
     var migration = NullabilityMigration(listener,
         instrumentation: _InstrumentationClient(this),
-        useFixBuilder: useFixBuilder);
+        removeViaComments: removeViaComments);
     var result = await session.getResolvedUnit(sourcePath);
     source = result.unit.declaredElement.source;
     findNode = FindNode(content, result.unit);
@@ -295,16 +295,20 @@
 }
 ''');
     var intAnnotation = findNode.typeAnnotation('int');
-    expect(changes, isNotEmpty);
-    for (var change in changes.values) {
-      expect(change, isNotEmpty);
-      for (var edit in change) {
-        var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardElse);
-        expect(info.fixReasons.single,
-            same(explicitTypeNullability[intAnnotation]));
-      }
-    }
+    expect(changes, hasLength(2));
+    // Change #1: drop the if-condition.
+    var dropCondition = changes[findNode.statement('if').offset].single;
+    expect(dropCondition.isDeletion, true);
+    expect(dropCondition.info.description,
+        NullabilityFixDescription.discardCondition);
+    expect(dropCondition.info.fixReasons.single,
+        same(explicitTypeNullability[intAnnotation]));
+    // Change #2: drop the else.
+    var dropElse = changes[findNode.statement('return i').end].single;
+    expect(dropElse.isDeletion, true);
+    expect(dropElse.info.description, NullabilityFixDescription.discardElse);
+    expect(dropElse.info.fixReasons.single,
+        same(explicitTypeNullability[intAnnotation]));
   }
 
   Future<void> test_fix_reason_discard_else_empty_then() async {
@@ -321,7 +325,7 @@
       expect(change, isNotEmpty);
       for (var edit in change) {
         var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardElse);
+        expect(info.description, NullabilityFixDescription.discardIf);
         expect(info.fixReasons.single,
             same(explicitTypeNullability[intAnnotation]));
       }
@@ -351,7 +355,6 @@
     }
   }
 
-  @FailingTest(reason: 'Produces no changes')
   Future<void> test_fix_reason_discard_then_no_else() async {
     await analyze('''
 _f(int/*!*/ i) {
@@ -366,7 +369,7 @@
       expect(change, isNotEmpty);
       for (var edit in change) {
         var info = edit.info;
-        expect(info.description, NullabilityFixDescription.discardThen);
+        expect(info.description, NullabilityFixDescription.discardIf);
         expect(info.fixReasons.single,
             same(explicitTypeNullability[intAnnotation]));
       }
@@ -422,7 +425,33 @@
     expect(reasons.single, same(explicitTypeNullability[intAnnotation]));
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38472')
+  Future<void> test_fix_reason_remove_question_from_question_dot() async {
+    await analyze('_f(int/*!*/ i) => i?.isEven;');
+    expect(changes, isNotEmpty);
+    for (var change in changes.values) {
+      expect(change, isNotEmpty);
+      for (var edit in change) {
+        var info = edit.info;
+        expect(info.description, NullabilityFixDescription.removeNullAwareness);
+        expect(info.fixReasons, isEmpty);
+      }
+    }
+  }
+
+  Future<void>
+      test_fix_reason_remove_question_from_question_dot_method() async {
+    await analyze('_f(int/*!*/ i) => i?.abs();');
+    expect(changes, isNotEmpty);
+    for (var change in changes.values) {
+      expect(change, isNotEmpty);
+      for (var edit in change) {
+        var info = edit.info;
+        expect(info.description, NullabilityFixDescription.removeNullAwareness);
+        expect(info.fixReasons, isEmpty);
+      }
+    }
+  }
+
   Future<void> test_fix_reason_remove_unnecessary_cast() async {
     await analyze('''
 _f(Object x) {
@@ -451,7 +480,6 @@
     expect(dropTrailingParen.info, null);
   }
 
-  @FailingTest(reason: 'Produces no changes')
   Future<void> test_fix_reason_rewrite_required() async {
     addMetaPackage();
     await analyze('''
@@ -1208,7 +1236,7 @@
 class C<T> {
   void f(T t) {}
 }
-voig g(C<int> x, int y) {
+void g(C<int> x, int y) {
   x.f(y);
 }
 ''');
@@ -1231,24 +1259,3 @@
         (e) => e.sourceNode == node && e.destinationNode == never && e.isHard);
   }
 }
-
-@reflectiveTest
-class _InstrumentationTestWithFixBuilder extends _InstrumentationTestBase {
-  @override
-  bool get useFixBuilder => true;
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_fix_reason_discard_then_no_else() =>
-      super.test_fix_reason_discard_then_no_else();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_fix_reason_remove_unnecessary_cast() =>
-      super.test_fix_reason_remove_unnecessary_cast();
-
-  /// Test fails under the pre-FixBuilder implementation; passes now.
-  @override
-  Future<void> test_fix_reason_rewrite_required() =>
-      super.test_fix_reason_rewrite_required();
-}
diff --git a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
index bcaea0c..2dc12ff 100644
--- a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
+++ b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
@@ -4,14 +4,10 @@
 
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/timestamped_data.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:mockito/mockito.dart';
-import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/nullability_migration_impl.dart';
-import 'package:nnbd_migration/src/potential_modification.dart';
 import 'package:nnbd_migration/src/variables.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 main() {
@@ -29,70 +25,6 @@
   void setUp() {
     variables = VariablesMock();
   }
-
-  void test_modification_columnLineInfo() {
-    final text = 'void f() {}\nint g() => null;';
-    final offset = text.indexOf('int') + 3;
-    final potentialModification = _PotentialModificationMock(
-        _NullabilityFixDescriptionMock(
-            'Add ?', NullabilityFixKind.makeTypeNullable),
-        false,
-        [SourceEdit(offset, 0, '?')]);
-    final listener = NullabilityMigrationListenerMock();
-    final source = SourceMock(text);
-    when(variables.getPotentialModifications()).thenReturn({
-      source: [potentialModification]
-    });
-
-    nullabilityMigrationImpl.broadcast(variables, listener, null);
-
-    final capturedSuggestions =
-        verify(listener.addSuggestion(captureAny, captureAny)).captured;
-    expect(capturedSuggestions, hasLength(2));
-    var descriptions = capturedSuggestions[0];
-    var location = capturedSuggestions[1] as Location;
-    expect(descriptions, 'Add ?');
-    expect(location.offset, offset);
-    expect(location.length, 0);
-    expect(location.file, '/test.dart');
-    expect(location.startLine, 2);
-    expect(location.startColumn, 4);
-    verifyNever(listener.reportException(any, any, any, any));
-    final edit =
-        verify(listener.addEdit(any, captureAny)).captured.single as SourceEdit;
-    expect(edit.offset, offset);
-    expect(edit.length, 0);
-    expect(edit.replacement, '?');
-  }
-
-  void test_noModifications_notReported() {
-    final potentialModification = _PotentialModificationMock.empty(
-        _NullabilityFixDescriptionMock(
-            'foo', NullabilityFixKind.noModification));
-    final listener = NullabilityMigrationListenerMock();
-    final source = SourceMock('');
-    when(variables.getPotentialModifications()).thenReturn({
-      source: [potentialModification]
-    });
-
-    nullabilityMigrationImpl.broadcast(variables, listener, null);
-
-    verifyNever(listener.addSuggestion(any, any));
-    verifyNever(listener.reportException(any, any, any, any));
-    verifyNever(listener.addEdit(any, any));
-  }
-
-  void test_noPotentialChanges_notReported() {
-    final listener = NullabilityMigrationListenerMock();
-    final source = SourceMock('');
-    when(variables.getPotentialModifications()).thenReturn({source: []});
-
-    nullabilityMigrationImpl.broadcast(variables, listener, null);
-
-    verifyNever(listener.addSuggestion(any, any));
-    verifyNever(listener.reportException(any, any, any, any));
-    verifyNever(listener.addEdit(any, any));
-  }
 }
 
 class NullabilityMigrationListenerMock extends Mock
@@ -107,33 +39,3 @@
 }
 
 class VariablesMock extends Mock implements Variables {}
-
-class _NullabilityFixDescriptionMock implements NullabilityFixDescription {
-  @override
-  final String appliedMessage;
-  @override
-  final NullabilityFixKind kind;
-
-  _NullabilityFixDescriptionMock(this.appliedMessage, this.kind);
-}
-
-class _PotentialModificationMock extends PotentialModification {
-  @override
-  final NullabilityFixDescription description;
-
-  @override
-  final bool isEmpty;
-
-  @override
-  final Iterable<SourceEdit> modifications;
-
-  _PotentialModificationMock(
-      this.description, this.isEmpty, this.modifications);
-
-  _PotentialModificationMock.empty(this.description)
-      : isEmpty = false,
-        modifications = [];
-
-  @override
-  Iterable<FixReasonInfo> get reasons => const [];
-}
diff --git a/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart b/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart
new file mode 100644
index 0000000..874c6a4
--- /dev/null
+++ b/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, 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';
+
+import 'package:nnbd_migration/src/utilities/multi_future_tracker.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MultiFutureTrackerTest);
+  });
+}
+
+@reflectiveTest
+class MultiFutureTrackerTest {
+  MultiFutureTracker testTracker;
+
+  tearDown() {
+    // This will leak futures on certain kinds of test failures.  But it is
+    // a test, so we don't care.
+    testTracker = null;
+  }
+
+  Future<void> test_multiFutureBlocksOnLimit() async {
+    var completer1 = Completer();
+
+    testTracker = MultiFutureTracker(1);
+    await testTracker.addFutureFromClosure(() => completer1.future);
+    // The second future added shouldn't be executing until the first
+    // future is complete.
+    var secondInQueue = testTracker.addFutureFromClosure(() async {
+      expect(completer1.isCompleted, isTrue);
+    });
+
+    completer1.complete();
+    await secondInQueue;
+    return await testTracker.wait();
+  }
+
+  Future<void> test_doesNotBlockWithoutLimit() async {
+    var completer1 = Completer();
+
+    // Limit is set above the number of futures we are adding.
+    testTracker = MultiFutureTracker(10);
+    await testTracker.addFutureFromClosure(() => completer1.future);
+    // The second future added should be executing even though the first
+    // future is not complete.  A test failure will time out.
+    await testTracker.addFutureFromClosure(() async {
+      expect(completer1.isCompleted, isFalse);
+      completer1.complete();
+    });
+
+    return await testTracker.wait();
+  }
+}
diff --git a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
new file mode 100644
index 0000000..aca5806
--- /dev/null
+++ b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SubprocessLauncherTest);
+  });
+}
+
+@reflectiveTest
+class SubprocessLauncherTest {
+  Function(String) outputCallback;
+  List<String> output;
+  Directory tempDir;
+
+  void setUp() async {
+    output = [];
+    outputCallback = output.add;
+    tempDir = await Directory.systemTemp.createTemp();
+  }
+
+  void tearDown() async {
+    await tempDir.delete(recursive: true);
+  }
+
+  Future<void> test_subprocessRunsValidExecutable() async {
+    SubprocessLauncher launcher =
+        SubprocessLauncher('test_subprocessRunsValidExecutable');
+
+    await launcher.runStreamed(Platform.resolvedExecutable, ['--version'],
+        perLine: outputCallback);
+    expect(output, anyElement(contains('Dart')));
+  }
+
+  Future<void> test_subprocessPassesArgs() async {
+    SubprocessLauncher launcher =
+        SubprocessLauncher('test_subprocessPassesArgs');
+    File testScript =
+        File(path.join(tempDir.path, 'subprocess_test_script.dart'));
+    await testScript.writeAsString(r'''
+      import 'dart:io';
+
+      main(List<String> args) {
+        print('args: $args');
+      }''');
+
+    await launcher.runStreamed(
+        Platform.resolvedExecutable, [testScript.path, 'testArgument'],
+        perLine: outputCallback);
+    expect(output, anyElement(contains('args: [testArgument]')));
+  }
+
+  Future<void> test_subprocessPassesEnvironment() async {
+    SubprocessLauncher launcher =
+        SubprocessLauncher('test_subprocessPassesEnvironment');
+    File testScript =
+        File(path.join(tempDir.path, 'subprocess_test_script.dart'));
+    await testScript.writeAsString(r'''
+      import 'dart:io';
+
+      main(List<String> args) {
+        print('environment: ${Platform.environment}');
+      }''');
+
+    await launcher.runStreamed(Platform.resolvedExecutable, [testScript.path],
+        environment: {'__SUBPROCESS_PASSES_ENVIRONMENT_TEST': 'yes'},
+        perLine: outputCallback);
+    expect(
+        output,
+        anyElement(contains(RegExp(
+            '^environment: .*__SUBPROCESS_PASSES_ENVIRONMENT_TEST: yes'))));
+  }
+
+  Future<void> test_subprocessSetsWorkingDirectory() async {
+    SubprocessLauncher launcher =
+        SubprocessLauncher('test_subprocessSetsWorkingDirectory');
+    File testScript =
+        File(path.join(tempDir.path, 'subprocess_test_script.dart'));
+    await testScript.writeAsString(r'''
+      import 'dart:io';
+
+      main() {
+        print('working directory: ${Directory.current.path}');
+      }''');
+
+    await launcher.runStreamed(Platform.resolvedExecutable, [testScript.path],
+        workingDirectory: tempDir.path, perLine: outputCallback);
+    expect(
+        output,
+        anyElement(contains(
+            'working directory: ${tempDir.resolveSymbolicLinksSync()}')));
+  }
+
+  Future<void> test_subprocessThrowsOnNonzeroExitCode() async {
+    SubprocessLauncher launcher =
+        SubprocessLauncher('test_subprocessThrowsOnNonzeroExitCode');
+    File testScript =
+        File(path.join(tempDir.path, 'subprocess_test_script.dart'));
+    await testScript.writeAsString(r'''
+      import 'dart:io';
+
+      main() {
+        exit(1);
+      }''');
+    await expectLater(
+        () async => await launcher.runStreamed(
+            Platform.resolvedExecutable, [testScript.path],
+            perLine: outputCallback),
+        throwsA(TypeMatcher<ProcessException>()));
+  }
+}
diff --git a/pkg/nnbd_migration/test/utilities/test_all.dart b/pkg/nnbd_migration/test/utilities/test_all.dart
index 7c14545..8a172cc 100644
--- a/pkg/nnbd_migration/test/utilities/test_all.dart
+++ b/pkg/nnbd_migration/test/utilities/test_all.dart
@@ -4,10 +4,14 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'multi_future_tracker_test.dart' as multi_future_tracker_test;
 import 'scoped_set_test.dart' as scoped_set_test;
+import 'subprocess_launcher_test.dart' as subprocess_launcher_test;
 
 main() {
   defineReflectiveSuite(() {
+    multi_future_tracker_test.main();
     scoped_set_test.main();
+    subprocess_launcher_test.main();
   });
 }
diff --git a/pkg/nnbd_migration/tool/src/package.dart b/pkg/nnbd_migration/tool/src/package.dart
index ff34331..adf37f2 100644
--- a/pkg/nnbd_migration/tool/src/package.dart
+++ b/pkg/nnbd_migration/tool/src/package.dart
@@ -7,15 +7,10 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:nnbd_migration/src/fantasyland/fantasy_workspace.dart';
+import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
 import 'package:path/path.dart' as path;
 
-import 'multi_future_tracker.dart';
-import 'subprocess_launcher.dart';
-
-/// Route all executions of pub through this [MultiFutureTracker] to avoid
-/// parallel executions of the pub command.
-final MultiFutureTracker _pubTracker = MultiFutureTracker(1);
-
 /// Return a resolved path including the home directory in place of tilde
 /// references.
 String resolveTildePath(String originalPath) {
@@ -78,10 +73,31 @@
 
 /// Abstraction for an unmanaged package.
 class ManualPackage extends Package {
-  ManualPackage(this.packagePath) : super(packagePath);
+  final String _packagePath;
+  ManualPackage(this._packagePath) : super(_packagePath);
 
   @override
-  final String packagePath;
+  List<String> get migrationPaths => [_packagePath];
+}
+
+/// Abstraction for a fantasy-land package.
+class FantasyLandPackage extends Package {
+  final String name;
+  final FantasyWorkspace fantasyLand;
+
+  FantasyLandPackage._(this.name, this.fantasyLand) : super('${name}__flat');
+
+  static Future<FantasyLandPackage> fantasyLandPackageFactory(
+      String name, Playground playground) async {
+    return FantasyLandPackage._(
+        name,
+        await buildFantasyLand(name, [],
+            Directory(path.join(playground.playgroundPath, '${name}__flat'))));
+  }
+
+  @override
+  // TODO(jcollins-g): traverse [fantasyLand.subPackages] and calculate paths to migrate.
+  List<String> get migrationPaths => throw UnimplementedError;
 }
 
 /// Abstraction for a package fetched via Git.
@@ -140,9 +156,9 @@
             workingDirectory: packagePath);
         // TODO(jcollins-g): allow for migrating dependencies?
       }
-      await _pubTracker.addFutureFromClosure(() =>
+      await pubTracker.addFutureFromClosure(() =>
           launcher.runStreamed('pub', ['get'], workingDirectory: packagePath));
-      await _pubTracker.wait();
+      await pubTracker.wait();
     }
   }
 
@@ -151,12 +167,14 @@
       _launcher ??= SubprocessLauncher('$name-$label', _playground.env);
 
   String _packagePath;
-  @override
   String get packagePath =>
       // TODO(jcollins-g): allow packages from subdirectories of clones
       _packagePath ??= path.join(_playground.playgroundPath, '$name-$label');
 
   @override
+  List<String> get migrationPaths => [_packagePath];
+
+  @override
   String toString() {
     return '$_clonePath ($label)' + (_keepUpdated ? ' [synced]' : '');
   }
@@ -170,7 +188,7 @@
 
   @override
   // TODO: implement packagePath
-  String get packagePath => null;
+  List<String> get migrationPaths => throw UnimplementedError();
 }
 
 /// Abstraction for a package located within pkg or third_party/pkg.
@@ -194,10 +212,10 @@
 
   /* late final */ String _packagePath;
   @override
-  String get packagePath => _packagePath;
+  List<String> get migrationPaths => [_packagePath];
 
   @override
-  String toString() => path.relative(packagePath, from: thisSdkRepo);
+  String toString() => path.relative(_packagePath, from: thisSdkRepo);
 }
 
 /// Base class for pub, github, SDK, or possibly other package sources.
@@ -206,8 +224,8 @@
 
   Package(this.name);
 
-  /// Returns the root directory of the package.
-  String get packagePath;
+  /// Returns the set of directories for this package.
+  List<String> get migrationPaths;
 
   @override
   String toString() => name;
diff --git a/pkg/nnbd_migration/tool/src/subprocess_launcher.dart b/pkg/nnbd_migration/tool/src/subprocess_launcher.dart
deleted file mode 100644
index 1cb38d8..0000000
--- a/pkg/nnbd_migration/tool/src/subprocess_launcher.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// 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.
-
-// TODO(jcollins-g): Merge this with similar utilities in dartdoc
-// and extract into a separate package, generate testing and mirrors, and
-// reimport that into the SDK, before cut and paste gets out of hand.
-
-/// This is a modified version of dartdoc's
-/// SubprocessLauncher from test/src/utils.dart, for use with the
-/// nnbd_migration script.
-
-import 'dart:convert';
-import 'dart:io';
-
-final RegExp quotables = RegExp(r'[ "\r\n\$]');
-
-/// SubprocessLauncher manages one or more launched, non-interactive
-/// subprocesses.  It handles I/O streams, parses JSON output if
-/// available, and logs debugging information so the user can see exactly
-/// what was run.
-class SubprocessLauncher {
-  final String context;
-  final Map<String, String> environmentDefaults;
-
-  String get prefix => context.isNotEmpty ? '$context: ' : '';
-
-  /// From flutter:dev/tools/dartdoc.dart, modified.
-  static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
-      {String prefix = '', Iterable<String> Function(String line) filter}) {
-    assert(prefix != null);
-    if (filter == null) filter = (line) => [line];
-    return stream
-        .transform(utf8.decoder)
-        .transform(const LineSplitter())
-        .expand(filter)
-        .listen((String line) {
-      if (line != null) {
-        output.write('$prefix$line'.trim());
-        output.write('\n');
-      }
-    }).asFuture();
-  }
-
-  SubprocessLauncher(this.context, [Map<String, String> environment])
-      : this.environmentDefaults = environment ?? <String, String>{};
-
-  /// A wrapper around start/await process.exitCode that will display the
-  /// output of the executable continuously and fail on non-zero exit codes.
-  /// It will also parse any valid JSON objects (one per line) it encounters
-  /// on stdout/stderr, and return them.  Returns null if no JSON objects
-  /// were encountered, or if DRY_RUN is set to 1 in the execution environment.
-  ///
-  /// Makes running programs in grinder similar to set -ex for bash, even on
-  /// Windows (though some of the bashisms will no longer make sense).
-  /// TODO(jcollins-g): refactor to return a stream of stderr/stdout lines
-  ///                   and their associated JSON objects.
-  Future<Iterable<Map>> runStreamed(String executable, List<String> arguments,
-      {String workingDirectory,
-      Map<String, String> environment,
-      bool includeParentEnvironment = true,
-      void Function(String) perLine}) async {
-    environment ??= {};
-    environment.addAll(environmentDefaults);
-    List<Map> jsonObjects;
-
-    /// Parses json objects generated by the subprocess.  If a json object
-    /// contains the key 'message' or the keys 'data' and 'text', return that
-    /// value as a collection of lines suitable for printing.
-    Iterable<String> jsonCallback(String line) {
-      if (perLine != null) perLine(line);
-      Map result;
-      try {
-        result = json.decoder.convert(line) as Map;
-      } catch (FormatException) {
-        // ignore
-      }
-      if (result != null) {
-        jsonObjects ??= [];
-        jsonObjects.add(result);
-        if (result.containsKey('message')) {
-          line = result['message'] as String;
-        } else if (result.containsKey('data') &&
-            result['data'] is Map &&
-            (result['data'] as Map).containsKey('key')) {
-          line = result['data']['text'] as String;
-        }
-      }
-      return line.split('\n');
-    }
-
-    stderr.write('$prefix+ ');
-    if (workingDirectory != null) stderr.write('(cd "$workingDirectory" && ');
-    if (environment != null) {
-      stderr.write(environment.keys.map((String key) {
-        if (environment[key].contains(quotables)) {
-          return "$key='${environment[key]}'";
-        } else {
-          return "$key=${environment[key]}";
-        }
-      }).join(' '));
-      stderr.write(' ');
-    }
-    stderr.write('$executable');
-    if (arguments.isNotEmpty) {
-      for (String arg in arguments) {
-        if (arg.contains(quotables)) {
-          stderr.write(" '$arg'");
-        } else {
-          stderr.write(" $arg");
-        }
-      }
-    }
-    if (workingDirectory != null) stderr.write(')');
-    stderr.write('\n');
-
-    if (Platform.environment.containsKey('DRY_RUN')) return null;
-
-    String realExecutable = executable;
-    final List<String> realArguments = [];
-    if (Platform.isLinux) {
-      // Use GNU coreutils to force line buffering.  This makes sure that
-      // subprocesses that die due to fatal signals do not chop off the
-      // last few lines of their output.
-      //
-      // Dart does not actually do this (seems to flush manually) unless
-      // the VM crashes.
-      realExecutable = 'stdbuf';
-      realArguments.addAll(['-o', 'L', '-e', 'L']);
-      realArguments.add(executable);
-    }
-    realArguments.addAll(arguments);
-
-    Process process = await Process.start(realExecutable, realArguments,
-        workingDirectory: workingDirectory,
-        environment: environment,
-        includeParentEnvironment: includeParentEnvironment);
-    Future<void> stdoutFuture = _printStream(process.stdout, stdout,
-        prefix: prefix, filter: jsonCallback);
-    Future<void> stderrFuture = _printStream(process.stderr, stderr,
-        prefix: prefix, filter: jsonCallback);
-    await Future.wait([stderrFuture, stdoutFuture, process.exitCode]);
-
-    int exitCode = await process.exitCode;
-    if (exitCode != 0) {
-      throw ProcessException(executable, arguments,
-          "SubprocessLauncher got non-zero exitCode: $exitCode", exitCode);
-    }
-    return jsonObjects;
-  }
-}
diff --git a/pkg/nnbd_migration/tool/steamroll_ecosystem.sh b/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
index caa05b2..9af3926 100755
--- a/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
+++ b/pkg/nnbd_migration/tool/steamroll_ecosystem.sh
@@ -78,14 +78,32 @@
   echo "$1" >> "${repos_changed_this_run}"
 }
 
+
+function _pull_into_repo {
+  local branch="$1"
+  local revision="$2"
+  local sparse_param
+
+  if [ "${branch}" == "master" ] ; then
+    sparse_param=--depth=1
+  fi
+
+  [ -z "${revision}" ] && revision="${branch}"
+
+  git pull ${sparse_param} --rebase originHTTP "${revision}"
+}
+
 #
 # Add a git repository to the workspace.
 #
 # $1: the name of the repository
 # $2: branch to clone from
+# $3: revision to check out, or leave at HEAD if empty.  We can't use sparse
+#     clones in this case.
 function add_repo_to_workspace {
   local repo_name="$1"
   local branch="$2"
+  local revision
   local clone
 
   local curr_head
@@ -94,18 +112,6 @@
   if already_done_this_run "_repos/${repo_name}" ; then return 0 ; fi
   log_this_run "_repos/${repo_name}"
 
-  if [ -d "_repos/${repo_name}" ] ; then
-    pushd "_repos/${repo_name}"
-    prev_head="$(git rev-parse HEAD)"
-    ${NO_UPDATE} git pull originHTTP ${branch}
-    curr_head="$(git rev-parse HEAD)"
-    if [ "${prev_head}" != "${curr_head}" ] ; then
-      log_repo_changed_this_run "${repo_name}"
-    fi
-    popd
-    return $?
-  fi
-
   case "${repo_name}" in
     archive) clone="git@github.com:brendan-duncan/${repo_name}.git" ;;
     build_verify) clone="git@github.com:kevmoo/${repo_name}.git" ;;
@@ -114,6 +120,10 @@
     git) clone="git@github.com:kevmoo/${repo_name}.git" ;;
     node-interop) clone="git@github.com:pulyaevskiy/node-interop.git" ;;
     node_preamble) clone="git@github.com:mbullington/${repo_name}.dart.git" ;;
+    package_config)
+      clone="git@github.com:dart-lang/${repo_name}.git"
+      revision=1.1.0
+      ;;
     source_gen_test) clone="git@github.com:kevmoo/${repo_name}.git" ;;
     quiver-dart) clone="git@github.com:google/${repo_name}.git" ;;
     uuid) clone="git@github.com:Daegalus/dart-uuid.git" ;;
@@ -124,6 +134,19 @@
     ;;
   esac
 
+  if [ -d "_repos/${repo_name}" ] ; then
+    pushd "_repos/${repo_name}"
+    prev_head="$(git rev-parse HEAD)"
+    ${NO_UPDATE} _pull_into_repo "${branch}" "${revision}"
+    curr_head="$(git rev-parse HEAD)"
+    if [ "${prev_head}" != "${curr_head}" ] ; then
+      log_repo_changed_this_run "${repo_name}"
+    fi
+    git checkout -b "${branch}"
+    popd
+    return $?
+  fi
+
   mkdir -p _repos
   pushd "_repos"
   git init "${repo_name}"
@@ -142,7 +165,7 @@
   echo "!**/.dart_tool/package_config.json" >> .git/info/sparse-checkout
   # TODO(jcollins-g): Usual bag of tricks does not work to stop git pull from
   # prompting and force it to hard fail if authentication is required.  Why?
-  if ! git pull --depth=1 originHTTP ; then
+  if ! _pull_into_repo ${branch} ${revision} ; then
     echo error cloning: "${clone}".  Cleaning up
     popd
     # We remove the repository here so that if you're iteratively adding new
@@ -162,12 +185,73 @@
 # Returns false if we ran out of retries.
 function pub_get_with_retries {
   for try in 1 2 3 4 5 ; do
-    if pub get ; then return 0 ; fi
+    if pub get --no-precompile ; then return 0 ; fi
     sleep $[$try * $try]
   done
   return 1
 }
 
+#
+# Puts to stdout a list of the package names for the dependencies of a package.
+#
+# Uses pub (super slow).
+#
+# $1: directory name
+function generate_package_names_with_pub {
+  local directory_name="$1"
+  if [ -n "${ONE_PUB_ONLY}" ] && [ "${ONE_PUB_ONLY}" != "$1" ] ; then
+    return 0
+  fi
+  [ -z "${directory_name}" ] && directory_name=.
+  pushd "${directory_name}" >/dev/null
+  pub_get_with_retries >/dev/null
+  popd >/dev/null
+  # HACK ALERT: assumes '.pub-cache' is in the path of the real pub cache.
+  # Packages referring to other packages via path in pubspec.yaml are not
+  # supported at all and we do not include dependencies derived that way
+  # exclusively.
+  grep -v '^#' "${directory_name}/.packages" | grep '.pub-cache' | cut -f 1 -d :
+}
+
+# Returns true if we can use yq, or false if there is a path package dependency.
+function _can_use_yq {
+  for k in dependencies dev_dependencies ; do
+    if yq r "$1/pubspec.yaml" "${k}.*.path" | egrep -q -v '^(- null|null)$' ; then
+      return 1
+    fi
+  done
+  return 0
+}
+
+# Prints package and version number, one per line, to stdout.
+function _generate_yq_helper {
+  yq r "$1/pubspec.yaml" dependencies | egrep '^\w+:' | sed 's/:/ /'
+  yq r "$1/pubspec.yaml" dev_dependencies | egrep '^\w+:' | sed 's/:/ /'
+}
+
+#
+# Puts to stdout a list of the package names for the dependencies of a package.
+#
+# Parses yaml (fast), but requires the 'yq' program.
+#
+# $1: directory name
+function generate_package_names_with_yq {
+  local directory_name="$1"
+  local package
+  local version
+  if _can_use_yq "${directory_name}" ; then
+    _generate_yq_helper "${directory_name}" | while read package version ; do
+      if [ ! -z "${version}" ] ; then
+        echo "${package}"
+      else
+        echo "assert: should have a version number or we should have used pub" >&2
+        return 1
+      fi
+    done
+  else
+    generate_package_names_with_pub "${directory_name}"
+  fi
+}
 
 #
 # Add a package, recursively, to the workspace.  A package may add its own
@@ -248,6 +332,9 @@
       make_clone_from_package json_annotation "${repo}" master json_annotation ;;
     json_serializable) repo=json_serializable
       make_clone_from_package json_serializable "${repo}" master json_serializable ;;
+    package_config) repo=package_config
+      # TODO(jcollins-g): remove pin after https://github.com/dart-lang/sdk/issues/40208
+      make_clone_from_package package_config "${repo}" 2453cd2e78c2db56ee2669ced17ce70dd00bf576 ;;
     protobuf) repo=protobuf
       make_clone_from_package protobuf "${repo}" master protobuf ;;
     scratch_space) repo=build
@@ -288,19 +375,23 @@
       add_package_to_workspace "$n"
     done
   else
-    pushd "${package_name}"
+    # HACK ALERT: some packages have dependencies only available via path. Add
+    # those here.
+    case "${package_name}" in
+      analyzer)
+        add_package_to_workspace "analysis_tool"
+        ;;
+    esac
     if [ -n "${NO_UPDATE}" ] || repo_changed_this_run "${repo}" ; then
-      pub_get_with_retries
-      popd
-      # HACK ALERT: assumes '.pub-cache' is in the path of the real pub cache.
-      # Packages referring to other packages via path in pubspec.yaml are not
-      # supported at all and we do not include dependencies derived that way
-      # exclusively.
-      for n in $(grep -v '^#' "${package_name}/.packages" | grep '.pub-cache' | cut -f 1 -d :) ; do
-        add_package_to_workspace "$n"
-      done
-    else
-      popd
+      if [ -z "${ONE_PUB_ONLY}" ] ; then
+        for n in $(generate_package_names_with_yq "${package_name}") ; do
+          add_package_to_workspace "$n"
+        done
+      else
+        for n in $(generate_package_names_with_pub "${package_name}") ; do
+          add_package_to_workspace "$n"
+        done
+      fi
     fi
   fi
   rm -f "${package_name}/.packages"
@@ -329,10 +420,19 @@
 # we always have to re-pub-get.  This is useful in debugging the script and
 # iteratively adding repository configurations.
 #
+# Set "ONE_PUB_ONLY" to the package being migrated to restrict running pub to
+# one package only.  This has the impact of only pulling in dev dependencies
+# for the top level package.
+#
 # This script might be able to update your existing workspace, or it might
 # trash it completely.  Make backups.
 #
 function main {
+  if ! which yq ; then
+    echo "missing: yq.  apt-get install yq or brew install yq" >&2
+    return 2
+  fi
+
   if [ -z "$1" -o -z "$2" ] ; then
     echo usage: $0 source_package_name workspace_dir
     return 2
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
index 7b600c2..f607a7b 100644
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ b/pkg/nnbd_migration/tool/trial_migration.dart
@@ -17,9 +17,9 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:args/args.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/utilities/multi_future_tracker.dart';
 import 'package:path/path.dart' as path;
 
-import 'src/multi_future_tracker.dart';
 import 'src/package.dart';
 
 main(List<String> args) async {
@@ -61,9 +61,8 @@
   for (var package in packages) {
     print('Migrating $package');
     listener.currentPackage = package.name;
-    var testUri = thisSdkUri.resolve(package.packagePath);
     var contextCollection = AnalysisContextCollectionImpl(
-        includedPaths: [testUri.toFilePath()], sdkPath: sdk.sdkPath);
+        includedPaths: package.migrationPaths, sdkPath: sdk.sdkPath);
 
     var files = <String>{};
     var previousExceptionCount = listener.numExceptions;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 6f10b91..32c34d5 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -73,6 +73,7 @@
 analyzer_plugin/tool/*: SkipByDesign # Only meant to run on vm
 build_integration/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
 compiler/tool/*: SkipByDesign # Only meant to run on vm
+dartdev/test/command_test: SkipByDesign # Only meant to run on vm (uses dart:io)
 dartfix/test/*: SkipByDesign # Only meant to run on vm
 front_end/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
 front_end/tool/*: SkipByDesign # Only meant to run on vm
diff --git a/pkg/smith/lib/builder.dart b/pkg/smith/lib/builder.dart
new file mode 100644
index 0000000..9d72e6b
--- /dev/null
+++ b/pkg/smith/lib/builder.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2020, 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 'configuration.dart';
+
+/// A step that is run on a builder to build and test certain configurations of
+/// the Dart SDK.
+///
+/// Each step on a builder runs a script the with provided arguments. If the
+/// script is 'tools/test.py' (which is the default if no script is given in
+/// the test matrix), the step is called a 'test step'. Test steps must include
+/// the '--named_configuration' (for short '-n') option to select the named
+/// [Configuration] to test.
+///
+/// Test steps and steps with `isTestRunner == true` are expected to produce
+/// test results that are collected during the run of the builder and checked
+/// against the expected results to determine the success or failure of the
+/// build.
+class Step {
+  final String name;
+  final String script;
+  final List<String> arguments;
+  final Map<String, String> environment;
+  final String fileSet;
+  final int shards;
+  final bool isTestRunner;
+  final Configuration testedConfiguration;
+
+  Step(this.name, String script, this.arguments, this.environment, this.fileSet,
+      this.shards, this.isTestRunner, this.testedConfiguration)
+      : script = script ?? testScriptName;
+
+  static const testScriptName = "tools/test.py";
+
+  bool get isTestStep => script == testScriptName;
+
+  /// Create a [Step] from the 'step template' [map], values for supported
+  /// variables [configuration], and the list of supported named configurations.
+  static Step parse(Map map, Map<String, String> configuration,
+      List<Configuration> configurations) {
+    var arguments = (map["arguments"] as List ?? [])
+        .map((argument) => _expandVariables(argument as String, configuration))
+        .toList();
+    var testedConfigurations = <Configuration>[];
+    var script = map["script"] as String ?? testScriptName;
+    if (script == testScriptName) {
+      // TODO(karlklose): replace with argument parser that can handle all
+      // arguments to test.py.
+      for (var argument in arguments) {
+        var names = <String>[];
+        if (argument.startsWith("--named_configuration")) {
+          names.addAll(argument
+              .substring("--named_configuration".length)
+              .split(",")
+              .map((s) => s.trim()));
+        } else if (argument.startsWith("-n")) {
+          names.addAll(
+              argument.substring("-n".length).split(",").map((s) => s.trim()));
+        } else {
+          continue;
+        }
+        for (var name in names) {
+          var matchingConfigurations =
+              configurations.where((c) => c.name == name);
+          if (matchingConfigurations.isEmpty) {
+            throw FormatException("Undefined configuration: $name");
+          }
+          testedConfigurations.add(matchingConfigurations.single);
+        }
+      }
+      if (testedConfigurations.length > 1) {
+        throw FormatException("Step tests multiple configurations: $arguments");
+      }
+    }
+    return Step(
+        map["name"] as String,
+        script,
+        arguments,
+        <String, String>{...?map["environment"]},
+        map["fileset"] as String,
+        map["shards"] as int,
+        map["testRunner"] as bool ?? false,
+        testedConfigurations.isEmpty ? null : testedConfigurations.single);
+  }
+}
+
+/// A builder runs a list of [Step]s to build and test certain configurations of
+/// the Dart SDK.
+///
+/// Groups of builders are defined in the 'builder_configurations' section of
+/// the test matrix.
+class Builder {
+  final String name;
+  final String description;
+  final List<Step> steps;
+  final System system;
+  final Mode mode;
+  final Architecture arch;
+  final Runtime runtime;
+  final List<Configuration> testedConfigurations;
+
+  Builder(this.name, this.description, this.steps, this.system, this.mode,
+      this.arch, this.runtime, this.testedConfigurations);
+
+  /// Create a [Builder] from its name, a list of 'step templates', the
+  /// supported named configurations and a description.
+  ///
+  /// The 'step templates' can contain the variables `${system}`, `${mode}`,
+  /// `${arch}`, and `${runtime}. The values for these variables are inferred
+  /// from the builder's name.
+  static Builder parse(String builderName, List<Map> steps,
+      List<Configuration> configurations, String description) {
+    var builderParts = builderName.split("-");
+    var systemName = _findPart(builderParts, System.names);
+    var modeName = _findPart(builderParts, Mode.names);
+    var archName = _findPart(builderParts, Architecture.names);
+    var runtimeName = _findPart(builderParts, Runtime.names);
+    var parsedSteps = steps
+        .map((step) => Step.parse(
+            step,
+            {
+              "system": systemName,
+              "mode": modeName,
+              "arch": archName,
+              "runtime": runtimeName,
+            },
+            configurations))
+        .toList();
+    var testedConfigurations = _getTestedConfigurations(parsedSteps);
+    return Builder(
+        builderName,
+        description,
+        parsedSteps,
+        _findIfNotNull(System.find, systemName),
+        _findIfNotNull(Mode.find, modeName),
+        _findIfNotNull(Architecture.find, archName),
+        _findIfNotNull(Runtime.find, runtimeName),
+        testedConfigurations);
+  }
+}
+
+/// Tries to replace a variable named [variableName] with [value] and throws
+/// and exception if the variable is used but `value == null`.
+String _tryReplace(String string, String variableName, String value) {
+  var variable = "\${$variableName}";
+  if (string.contains(variable)) {
+    if (value == null) {
+      throw FormatException("Undefined value for '$variableName' in '$string'");
+    }
+    return string.replaceAll(variable, value);
+  } else {
+    return string;
+  }
+}
+
+/// Replace the use of supported variable names with the their value given
+/// in [values] and throws an exception if an unsupported variable name is used.
+String _expandVariables(String string, Map<String, String> values) {
+  for (var variable in ["system", "mode", "arch", "runtime"]) {
+    string = _tryReplace(string, variable, values[variable]);
+  }
+  return string;
+}
+
+List<Configuration> _getTestedConfigurations(List<Step> steps) {
+  return steps
+      .where((step) => step.isTestStep)
+      .map((step) => step.testedConfiguration)
+      .toList();
+}
+
+T _findIfNotNull<T>(T Function(String) find, String name) {
+  return name != null ? find(name) : null;
+}
+
+String _findPart(List<String> builderParts, List<String> parts) {
+  return builderParts.firstWhere((part) => parts.contains(part),
+      orElse: () => null);
+}
+
+List<Builder> parseBuilders(
+    List<Map> builderConfigurations, List<Configuration> configurations) {
+  var builders = <Builder>[];
+  var names = <String>{};
+  for (var builderConfiguration in builderConfigurations) {
+    var meta = builderConfiguration["meta"] as Map ?? <String, String>{};
+    var builderNames = <String>[...?builderConfiguration["builders"]];
+    var steps = <Map>[...?builderConfiguration["steps"]];
+    for (var builderName in builderNames) {
+      if (!names.add(builderName)) {
+        throw FormatException('Duplicate builder name: "$builderName"');
+      }
+      builders.add(Builder.parse(
+          builderName, steps, configurations, meta["description"] as String));
+    }
+  }
+  return builders;
+}
diff --git a/pkg/smith/lib/smith.dart b/pkg/smith/lib/smith.dart
index 7118870..5faf52c 100644
--- a/pkg/smith/lib/smith.dart
+++ b/pkg/smith/lib/smith.dart
@@ -1,5 +1,6 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+export 'builder.dart';
 export 'configuration.dart';
 export 'test_matrix.dart';
diff --git a/pkg/smith/lib/test_matrix.dart b/pkg/smith/lib/test_matrix.dart
index 74adce7..0b8d003 100644
--- a/pkg/smith/lib/test_matrix.dart
+++ b/pkg/smith/lib/test_matrix.dart
@@ -4,12 +4,14 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'builder.dart';
 import 'configuration.dart';
 
 /// The manifest that defines the set of supported test [Configuration]s and
-/// how they are run on the bots.
+/// how they are run on the [Builders]s.
 class TestMatrix {
   final List<Configuration> configurations;
+  final List<Builder> builders;
 
   /// Reads a test matrix from the file at [path].
   static TestMatrix fromPath(String path) {
@@ -18,7 +20,8 @@
   }
 
   static TestMatrix fromJson(Map<String, dynamic> json) {
-    var configurationsJson = json["configurations"] as Map<String, dynamic>;
+    var configurationsJson =
+        json["configurations"] as Map<String, dynamic> ?? <String, dynamic>{};
 
     // Keep track of the configurations and which templates they were expanded
     // from.
@@ -30,7 +33,7 @@
       for (var configuration in Configuration.expandTemplate(
           template, options as Map<String, dynamic>)) {
         for (var existing in configurations) {
-          // Make the names don't collide.
+          // Make sure the names don't collide.
           if (configuration.name == existing.name) {
             throw FormatException(
                 'Configuration "${configuration.name}" already exists.');
@@ -48,8 +51,11 @@
       }
     });
 
-    return TestMatrix._(configurations);
+    var builderConfigurations = <Map>[...?json["builder_configurations"]];
+    var builders = parseBuilders(builderConfigurations, configurations);
+
+    return TestMatrix._(configurations, builders);
   }
 
-  TestMatrix._(this.configurations);
+  TestMatrix._(this.configurations, this.builders);
 }
diff --git a/pkg/smith/pubspec.yaml b/pkg/smith/pubspec.yaml
index 0b80a7d..abd81b3 100644
--- a/pkg/smith/pubspec.yaml
+++ b/pkg/smith/pubspec.yaml
@@ -6,6 +6,8 @@
 publish_to: none
 environment:
   sdk: "^2.3.0"
+dependencies:
+  args: any
 dev_dependencies:
   expect:
     path: ../expect
diff --git a/pkg/smith/test/builder_test.dart b/pkg/smith/test/builder_test.dart
new file mode 100644
index 0000000..d7d671a
--- /dev/null
+++ b/pkg/smith/test/builder_test.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'package:expect/minitest.dart';
+
+import 'package:smith/smith.dart';
+
+import 'test_helpers.dart';
+
+final configurations = Configuration.expandTemplate(
+    "foo-(ia32|x64|arm)-(none|dart2js|dartk)-(debug|release)-(d8|vm)-"
+    "(linux|mac|win)",
+    {});
+
+void main() {
+  group("Step", () {
+    test("non-test step", () {
+      var step = Step.parse({
+        "script": "foo.py",
+        "name": "foo",
+      }, {}, configurations);
+      expect(step.isTestStep, isFalse);
+      expect(step.testedConfiguration, null);
+    });
+    test("explicit test step", () {
+      var step = Step.parse({
+        "name": "foo",
+        "script": "tools/test.py",
+        "arguments": ["-nfoo-x64-none-debug-d8-linux"]
+      }, {}, configurations);
+      expect(step.isTestStep, isTrue);
+      expect(step.testedConfiguration.name, "foo-x64-none-debug-d8-linux");
+    });
+    test("implicit test step", () {
+      var step = Step.parse({
+        "name": "foo",
+        "arguments": ["-nfoo-x64-none-debug-d8-linux"]
+      }, {}, configurations);
+      expect(step.isTestStep, isTrue);
+      expect(step.testedConfiguration.name, "foo-x64-none-debug-d8-linux");
+    });
+    test("a step can only test one configuration", () {
+      expectFormatError(
+          "Step tests multiple configurations: "
+          "[-nfoo-x64-none-debug-d8-linux, -nfoo-x64-none-release-d8-linux]",
+          () {
+        Step.parse({
+          "name": "foo",
+          "arguments": [
+            "-nfoo-x64-none-debug-d8-linux",
+            "-nfoo-x64-none-release-d8-linux"
+          ]
+        }, {}, configurations);
+      });
+    });
+    test("a test step using the long option name", () {
+      var step = Step.parse({
+        "name": "foo",
+        "arguments": ["--named_configuration foo-x64-none-debug-d8-linux"]
+      }, {}, configurations);
+      expect(step.isTestStep, isTrue);
+      expect(step.testedConfiguration.name, "foo-x64-none-debug-d8-linux");
+    });
+    test("a test step using multiple values for the argument", () {
+      expectFormatError(
+          "Step tests multiple configurations: [-n foo-x64-none-debug-d8-linux,"
+          "foo-x64-none-release-d8-linux]", () {
+        Step.parse({
+          "name": "foo",
+          "arguments": [
+            "-n foo-x64-none-debug-d8-linux,foo-x64-none-release-d8-linux"
+          ]
+        }, {}, configurations);
+      });
+    });
+    test("step arguments can contain arbitrary options and flags", () {
+      var step = Step.parse({
+        "name": "foo",
+        "arguments": ["-nfoo-x64-none-debug-d8-linux", "--bar", "-b=az"]
+      }, {}, configurations);
+      expect(step.isTestStep, isTrue);
+      expect(step.testedConfiguration.name, "foo-x64-none-debug-d8-linux");
+    });
+    test("in non-test steps, argument -n can have arbitrary values", () {
+      var step = Step.parse({
+        "script": "foo.py",
+        "name": "foo",
+        "arguments": ["-n not-a-configuration"]
+      }, {}, configurations);
+      expect(step.isTestStep, isFalse);
+    });
+  });
+  group("Builder", () {
+    test("'system' is parsed from builder name", () {
+      expectTestedConfigurations({
+        "builders": ["foo-linux", "foo-mac", "foo-win"],
+        "steps": [
+          {
+            "name": "foo",
+            "arguments": [r"-nfoo-x64-none-debug-d8-${system}"]
+          }
+        ],
+      }, [
+        "foo-x64-none-debug-d8-linux",
+        "foo-x64-none-debug-d8-mac",
+        "foo-x64-none-debug-d8-win"
+      ]);
+    });
+  });
+  test("'mode' is parsed from builder name", () {
+    expectTestedConfigurations({
+      "builders": ["foo-debug", "foo-release"],
+      "steps": [
+        {
+          "name": "foo",
+          "arguments": [r"-nfoo-x64-none-${mode}-d8-linux"]
+        }
+      ],
+    }, [
+      "foo-x64-none-debug-d8-linux",
+      "foo-x64-none-release-d8-linux"
+    ]);
+  });
+  test("'arch' is parsed from builder name", () {
+    expectTestedConfigurations({
+      "builders": ["foo-ia32", "foo-x64", "foo-arm"],
+      "steps": [
+        {
+          "name": "foo",
+          "arguments": [r"-nfoo-${arch}-none-debug-d8-linux"]
+        }
+      ],
+    }, [
+      "foo-ia32-none-debug-d8-linux",
+      "foo-x64-none-debug-d8-linux",
+      "foo-arm-none-debug-d8-linux"
+    ]);
+  });
+  test("'runtime' is parsed from builder name", () {
+    expectTestedConfigurations({
+      "builders": ["foo-d8", "foo-vm"],
+      "steps": [
+        {
+          "name": "foo",
+          "arguments": [r"-nfoo-x64-none-debug-${runtime}-linux"]
+        }
+      ],
+    }, [
+      "foo-x64-none-debug-d8-linux",
+      "foo-x64-none-debug-vm-linux"
+    ]);
+  });
+  test("'system' is not implied by builder name", () {
+    expectFormatError(
+        r"Undefined value for 'system' in "
+        r"'-nfoo-x64-none-debug-d8-${system}'", () {
+      parseBuilders([
+        {
+          "builders": ["foo"],
+          "steps": [
+            {
+              "name": "foo",
+              "arguments": [r"-nfoo-x64-none-debug-d8-${system}"]
+            }
+          ],
+        }
+      ], configurations);
+    });
+  });
+  test("'mode' is not implied by builder name", () {
+    expectFormatError(
+        r"Undefined value for 'mode' in "
+        r"'-nfoo-x64-none-${mode}-d8-linux'", () {
+      parseBuilders([
+        {
+          "builders": ["foo"],
+          "steps": [
+            {
+              "name": "foo",
+              "arguments": [r"-nfoo-x64-none-${mode}-d8-linux"]
+            }
+          ],
+        }
+      ], configurations);
+    });
+  });
+  test("'arch' is not implied by builder name", () {
+    expectFormatError(
+        r"Undefined value for 'arch' in "
+        r"'-nfoo-${arch}-none-debug-d8-linux'", () {
+      parseBuilders([
+        {
+          "builders": ["foo"],
+          "steps": [
+            {
+              "name": "foo",
+              "arguments": [r"-nfoo-${arch}-none-debug-d8-linux"]
+            }
+          ],
+        }
+      ], configurations);
+    });
+  });
+  test("'runtime' is not implied by builder name", () {
+    expectFormatError(
+        r"Undefined value for 'runtime' in "
+        r"'-nfoo-x64-none-debug-${runtime}-linux'", () {
+      parseBuilders([
+        {
+          "builders": ["foo"],
+          "steps": [
+            {
+              "name": "foo",
+              "arguments": [r"-nfoo-x64-none-debug-${runtime}-linux"]
+            }
+          ],
+        }
+      ], configurations);
+    });
+  });
+}
+
+void expectTestedConfigurations(
+    Map builderConfiguration, List<String> expectedConfigurations) {
+  var builders = parseBuilders([builderConfiguration], configurations);
+  int numberOfConfigurations = expectedConfigurations.length;
+  expect(builders.length, numberOfConfigurations);
+  for (var builderId = 0; builderId < numberOfConfigurations; builderId++) {
+    var builder = builders[builderId];
+    expect(builder.steps.length, 1);
+    var step = builder.steps[0];
+    expect(step.isTestStep, isTrue);
+  }
+  expect(builders.map((b) => b.steps[0].testedConfiguration.name).toList(),
+      equals(expectedConfigurations));
+}
diff --git a/pkg/smith/test/configuration_test.dart b/pkg/smith/test/configuration_test.dart
index 96df5e3..bf2c631 100644
--- a/pkg/smith/test/configuration_test.dart
+++ b/pkg/smith/test/configuration_test.dart
@@ -5,6 +5,8 @@
 
 import 'package:smith/smith.dart';
 
+import 'test_helpers.dart';
+
 void main() {
   group("Configuration", () {
     test("equality", () {
@@ -439,22 +441,3 @@
     });
   });
 }
-
-void expectParseError(String name, Map<String, dynamic> options, String error) {
-  try {
-    var configuration = Configuration.parse(name, options);
-    fail("Expected FormatException but got $configuration.");
-  } on FormatException catch (ex) {
-    expect(ex.message, equals(error));
-  }
-}
-
-void expectExpandError(
-    String template, Map<String, dynamic> options, String error) {
-  try {
-    var configurations = Configuration.expandTemplate(template, options);
-    fail("Expected FormatException but got $configurations.");
-  } on FormatException catch (ex) {
-    expect(ex.message, equals(error));
-  }
-}
diff --git a/pkg/smith/test/test_helpers.dart b/pkg/smith/test/test_helpers.dart
new file mode 100644
index 0000000..c44ee2c
--- /dev/null
+++ b/pkg/smith/test/test_helpers.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'package:expect/minitest.dart';
+
+import 'package:smith/smith.dart';
+
+void expectParseError(String name, Map<String, dynamic> options, String error) {
+  try {
+    var configuration = Configuration.parse(name, options);
+    fail("Expected FormatException but got $configuration.");
+  } on FormatException catch (ex) {
+    expect(ex.message, equals(error));
+  }
+}
+
+void expectFormatError(String error, test()) {
+  try {
+    test();
+  } on FormatException catch (e) {
+    expect(e.message, equals(error));
+    // This is the exception we expected, do nothing.
+    return;
+  } catch (e) {
+    fail("Expected FormatException '$error' but got ${e.runtimeType}: $e");
+  }
+  fail("Expected exception '$error' did not occur");
+}
+
+void expectExpandError(
+    String template, Map<String, dynamic> options, String error) {
+  try {
+    var configurations = Configuration.expandTemplate(template, options);
+    fail("Expected FormatException but got $configurations.");
+  } on FormatException catch (ex) {
+    expect(ex.message, equals(error));
+  }
+}
diff --git a/pkg/smith/test/test_matrix_test.dart b/pkg/smith/test/test_matrix_test.dart
index 7c20a66..e4acbca 100644
--- a/pkg/smith/test/test_matrix_test.dart
+++ b/pkg/smith/test/test_matrix_test.dart
@@ -19,7 +19,8 @@
               "enable-asserts": true
             },
           },
-        }
+        },
+        "builder_configurations": [],
       });
 
       expect(
@@ -59,6 +60,66 @@
             }
           });
     });
+
+    test("two builders have same name", () {
+      expectJsonError('Duplicate builder name: "front-end-linux-release-x64"', {
+        "builder_configurations": [
+          {
+            "builders": [
+              "front-end-linux-release-x64",
+              "front-end-linux-release-x64"
+            ],
+          },
+        ]
+      });
+    });
+
+    test("two builders have same name in different configurations", () {
+      expectJsonError('Duplicate builder name: "front-end-linux-release-x64"', {
+        "builder_configurations": [
+          {
+            "builders": ["front-end-linux-release-x64"],
+          },
+          {
+            "builders": ["front-end-linux-release-x64"],
+          },
+        ]
+      });
+    });
+
+    test("a builder step refers to existing configuration", () {
+      TestMatrix.fromJson({
+        "configurations": {"fasta-linux": {}},
+        "builder_configurations": [
+          {
+            "builders": ["front-end-linux-release-x64"],
+            "steps": [
+              {
+                "name": "fasta sdk tests",
+                "arguments": [r"-nfasta-${system}"],
+              },
+            ],
+          },
+        ]
+      });
+    });
+
+    test("a builder step refers to non-existing configuration", () {
+      expectJsonError('Undefined configuration: fasta-linux', {
+        "configurations": {"fasta-win": {}},
+        "builder_configurations": [
+          {
+            "builders": ["front-end-linux-release-x64"],
+            "steps": [
+              {
+                "name": "fasta sdk tests",
+                "arguments": [r"-nfasta-${system}"],
+              },
+            ],
+          },
+        ]
+      });
+    });
   });
 }
 
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 1ba0fe4..0f6a1f3 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -183,8 +183,6 @@
   baseUrl: "/root_dart/$testJSDir",
   paths: {
     "dart_sdk": "/root_build/gen/utils/dartdevc/$sdkPath",
-    "browser-source-map-support":
-      "/root_dart/third_party/node-source-map-support/browser-source-map-support",
 $packagePaths
   },
   waitSeconds: 30,
@@ -194,9 +192,8 @@
 <script type="text/javascript"
         src="/root_dart/third_party/requirejs/require.js"></script>
 <script type="text/javascript">
-requirejs(["$testName", "dart_sdk", "browser-source-map-support", "async_helper"],
-    function($testId, sdk, sm, async_helper) {
-  sm.install();
+requirejs(["$testName", "dart_sdk", "async_helper"],
+    function($testId, sdk, async_helper) {
   sdk._isolate_helper.startRootIsolate(function() {}, []);
   sdk._debugger.registerDevtoolsFormatter();
 
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 8aa5cf5..b6b1707 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -9,6 +9,7 @@
 
 import 'package:status_file/expectation.dart';
 import 'package:test_runner/src/static_error.dart';
+import 'package:dart2js_tools/deobfuscate_stack_trace.dart';
 
 import 'browser_controller.dart';
 import 'command.dart';
@@ -269,7 +270,12 @@
   final BrowserTestOutput _result;
   final Expectation _outcome;
 
-  factory BrowserCommandOutput(Command command, BrowserTestOutput result) {
+  /// Directory that is being served under `http:/.../root_build/` to browser
+  /// tests.
+  final String _buildDirectory;
+
+  factory BrowserCommandOutput(
+      BrowserTestCommand command, BrowserTestOutput result) {
     Expectation outcome;
 
     var parsedResult =
@@ -297,12 +303,24 @@
       }
     }
 
-    return BrowserCommandOutput._internal(command, result, outcome,
-        parsedResult, encodeUtf8(""), encodeUtf8(stderr));
+    return BrowserCommandOutput._internal(
+        command,
+        result,
+        outcome,
+        parsedResult,
+        command.configuration.buildDirectory,
+        encodeUtf8(""),
+        encodeUtf8(stderr));
   }
 
-  BrowserCommandOutput._internal(Command command, BrowserTestOutput result,
-      this._outcome, this._jsonResult, List<int> stdout, List<int> stderr)
+  BrowserCommandOutput._internal(
+      Command command,
+      BrowserTestOutput result,
+      this._outcome,
+      this._jsonResult,
+      this._buildDirectory,
+      List<int> stdout,
+      List<int> stderr)
       : _result = result,
         super(command, 0, result.didTimeout, stdout, stderr, result.duration,
             false, 0);
@@ -364,13 +382,25 @@
 
     void _showError(String header, event) {
       output.subsection(header);
-      output.write((event["value"] as String).trim());
+      var value = event["value"] as String;
       if (event["stack_trace"] != null) {
-        var stack = (event["stack_trace"] as String).trim().split("\n");
-        output.writeAll(stack);
+        value = '$value\n${event["stack_trace"] as String}';
       }
-
       showedError = true;
+      output.write(value);
+
+      // Skip deobfuscation if there is no indication that there is a stack
+      // trace in the string value.
+      if (!value.contains(RegExp('\\.js:'))) return;
+      var stringStack = value
+          // Convert `http:` URIs to relative `file:` URIs.
+          .replaceAll(RegExp('http://[^/]*/root_build/'), '$_buildDirectory/')
+          .replaceAll(RegExp('http://[^/]*/root_dart/'), '')
+          // Remove query parameters (seen in .html URIs).
+          .replaceAll(RegExp('\\?[^:]*:'), ':');
+      // TODO(sigmund): change internal deobfuscation code to avoid spurious
+      // error messages when files do not have a corresponding source-map.
+      _deobfuscateAndWriteStack(stringStack, output);
     }
 
     for (var event in _jsonResult.events) {
@@ -993,6 +1023,16 @@
     }
     return Expectation.pass;
   }
+
+  void describe(TestCase testCase, Progress progress, OutputWriter output) {
+    super.describe(testCase, progress, output);
+    var decodedOut = decodeUtf8(stdout)
+        .replaceAll('\r\n', '\n')
+        .replaceAll('\r', '\n')
+        .trim();
+
+    _deobfuscateAndWriteStack(decodedOut, output);
+  }
 }
 
 class ScriptCommandOutput extends CommandOutput {
@@ -1185,3 +1225,16 @@
     return outcome;
   }
 }
+
+void _deobfuscateAndWriteStack(String stack, OutputWriter output) {
+  try {
+    var deobfuscatedStack = deobfuscateStackTrace(stack);
+    if (deobfuscatedStack == stack) return;
+    output.subsection('Deobfuscated error and stack');
+    output.write(deobfuscatedStack);
+  } catch (e, st) {
+    output.subsection('Warning: not able to deobfuscate stack');
+    output.writeAll(['input: $stack', 'error: $e', 'stack trace: $st']);
+    return;
+  }
+}
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 6c413d7..ba2f2da 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -68,7 +68,8 @@
       this.outputDirectory,
       this.reproducingArguments,
       this.fastTestsOnly,
-      this.printPassingStdout})
+      this.printPassingStdout,
+      this.useQemu})
       : _packages = packages;
 
   final Map<String, RegExp> selectors;
@@ -97,6 +98,7 @@
   final bool writeResults;
   final bool writeLogs;
   final bool printPassingStdout;
+  final bool useQemu;
 
   Architecture get architecture => configuration.architecture;
   Compiler get compiler => configuration.compiler;
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index a9707d5..cedfc85 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -188,6 +188,8 @@
     _Option.bool('use_elf',
         'Directly generate an ELF shared libraries for precompilation.',
         hide: true),
+    _Option.bool('use_qemu', 'Use qemu to test arm32 on x64 host machines.',
+        hide: true),
     _Option.bool('keep_generated_files', 'Keep any generated files.',
         abbr: 'k'),
     _Option.int('timeout', 'Timeout in seconds.', abbr: 't'),
@@ -749,7 +751,8 @@
           reproducingArguments:
               _reproducingCommand(data, namedConfiguration != null),
           fastTestsOnly: data["fast_tests"] as bool,
-          printPassingStdout: data["print_passing_stdout"] as bool);
+          printPassingStdout: data["print_passing_stdout"] as bool,
+          useQemu: data["use_qemu"] as bool);
 
       if (configuration.validate()) {
         result.add(configuration);
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 78bfe6b..b377f637 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -273,6 +273,10 @@
     if (type == 'application/kernel-ir-fully-linked') {
       executable = dartVmExecutableFileName;
     }
+    if (_configuration.useQemu) {
+      arguments.insertAll(0, ['-L', '/usr/arm-linux-gnueabihf/', executable]);
+      executable = 'qemu-arm';
+    }
     return [VMCommand(executable, arguments, environmentOverrides)];
   }
 }
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index 16ebe40..ac6729b 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -17,6 +17,8 @@
     path: ../smith
   status_file:
     path: ../status_file
+  dart2js_tools:
+    path: ../dart2js_tools
 dependency_overrides:
   # Other packages in the dependency graph have normal hosted dependencies on
   # this, so just override it to force the local one.
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index 289135b..e51bcb4 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -147,7 +147,7 @@
         continue;
       }
       final Set<Expectation> expectedOutcomes = processExpectedOutcomes(
-          expectations.expectations(description.shortName));
+          expectations.expectations(description.shortName), description);
       final StringBuffer sb = new StringBuffer();
       final Step lastStep = steps.isNotEmpty ? steps.last : null;
       final Iterator<Step> iterator = steps.iterator;
@@ -269,7 +269,8 @@
     }
   }
 
-  Set<Expectation> processExpectedOutcomes(Set<Expectation> outcomes) {
+  Set<Expectation> processExpectedOutcomes(
+      Set<Expectation> outcomes, TestDescription description) {
     return outcomes;
   }
 
diff --git a/pkg/vm/bin/convert_stack_traces.dart b/pkg/vm/bin/convert_stack_traces.dart
deleted file mode 100644
index 6d0e926..0000000
--- a/pkg/vm/bin/convert_stack_traces.dart
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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";
-import "dart:convert";
-import "dart:io" as io;
-
-import 'package:args/args.dart' show ArgParser, ArgResults;
-import 'package:vm/dwarf/convert.dart';
-import 'package:vm/dwarf/dwarf.dart';
-
-final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
-  ..addOption('elf',
-      abbr: 'e',
-      help: 'Path to ELF file with debugging information',
-      defaultsTo: null,
-      valueHelp: 'FILE')
-  ..addOption('input',
-      abbr: 'i',
-      help: 'Path to input file',
-      defaultsTo: null,
-      valueHelp: 'FILE')
-  ..addOption('location',
-      abbr: 'l',
-      help: 'PC address to convert to a file name and line number',
-      defaultsTo: null,
-      valueHelp: 'INT')
-  ..addOption('output',
-      abbr: 'o',
-      help: 'Path to output file',
-      defaultsTo: null,
-      valueHelp: 'FILE')
-  ..addFlag('verbose',
-      abbr: 'v',
-      help: 'Translate all frames, not just frames for user or library code',
-      defaultsTo: false);
-
-final String _usage = '''
-Usage: convert_stack_traces [options]
-
-Takes text that includes DWARF-based stack traces with PC addresses and
-outputs the same text, but with the DWARF stack traces converted to stack traces
-that contain function names, file names, and line numbers.
-
-Reads from the file named by the argument to -i/--input as input, or stdin if
-no input flag is given.
-
-Outputs the converted contents to the file named by the argument to
--o/--output, or stdout if no output flag is given.
-
-The -e/-elf option must be provided, and DWARF debugging information is
-read from the file named by its argument.
-
-When the -v/--verbose option is given, the converter translates all frames, not
-just those corresponding to user or library code.
-
-If an -l/--location option is provided, then the file and line number
-information for the given location is looked up and output instead.
-
-Options:
-${_argParser.usage}
-''';
-
-const int _badUsageExitCode = 1;
-
-Future<void> main(List<String> arguments) async {
-  final ArgResults options = _argParser.parse(arguments);
-
-  if ((options.rest.length > 0) || (options['elf'] == null)) {
-    print(_usage);
-    io.exitCode = _badUsageExitCode;
-    return;
-  }
-
-  int location = null;
-  if (options['location'] != null) {
-    location = int.tryParse(options['location']);
-    if (location == null) {
-      // Try adding an initial "0x", as DWARF stack traces don't normally
-      // include the hex marker on the PC addresses.
-      location = int.tryParse("0x" + options['location']);
-    }
-    if (location == null) {
-      print("Location could not be parsed as an int: ${options['location']}\n");
-      print(_usage);
-      io.exitCode = _badUsageExitCode;
-      return;
-    }
-  }
-
-  final dwarf = Dwarf.fromFile(options['elf']);
-
-  final output = options['output'] != null
-      ? io.File(options['output']).openWrite()
-      : io.stdout;
-  final verbose = options['verbose'];
-
-  var convertedStream;
-  if (location != null) {
-    final frames = dwarf
-        .callInfo(location, includeInternalFrames: verbose)
-        ?.map((CallInfo c) => c.toString());
-    if (frames == null) {
-      throw "No call information found for PC 0x${location.toRadixString(16)}";
-    }
-    convertedStream = Stream.fromIterable(frames);
-  } else {
-    final input = options['input'] != null
-        ? io.File(options['input']).openRead()
-        : io.stdin;
-
-    convertedStream = input
-        .transform(utf8.decoder)
-        .transform(const LineSplitter())
-        .transform(
-            DwarfStackTraceDecoder(dwarf, includeInternalFrames: verbose));
-  }
-
-  await convertedStream.forEach(output.writeln);
-  await output.flush();
-  await output.close();
-}
diff --git a/pkg/vm/lib/dwarf/convert.dart b/pkg/vm/lib/dwarf/convert.dart
deleted file mode 100644
index 9bcdf50..0000000
--- a/pkg/vm/lib/dwarf/convert.dart
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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";
-import "dart:math";
-
-import "dwarf.dart";
-
-String _stackTracePiece(CallInfo call, int depth) => "#${depth}\t${call}";
-
-final _traceStart = 'Warning: This VM has been configured to produce '
-    'stack traces that violate the Dart standard.';
-final _traceInstructionsStartRE = RegExp(r'isolate_instructions: ([0-9a-f]+) '
-    r'vm_instructions: ([0-9a-f]+)$');
-final _traceLineRE =
-    RegExp(r'    #(\d{2}) abs ([0-9a-f]+)(?: virt [0-9a-f]+)? (.*)$');
-
-enum InstructionSection { vm, isolate }
-
-class PCOffset {
-  final int offset;
-  final InstructionSection section;
-
-  PCOffset(this.offset, this.section);
-
-  int virtualAddress(Dwarf dwarf) {
-    switch (section) {
-      case InstructionSection.vm:
-        return dwarf.convertToVMVirtualAddress(offset);
-      case InstructionSection.isolate:
-        return dwarf.convertToIsolateVirtualAddress(offset);
-    }
-  }
-
-  int get hashCode => offset.hashCode;
-
-  bool operator ==(Object other) {
-    return other is PCOffset &&
-        offset == other.offset &&
-        section == other.section;
-  }
-}
-
-class StackTraceHeader {
-  final int _isolateStart;
-  final int _vmStart;
-
-  StackTraceHeader(this._isolateStart, this._vmStart);
-
-  factory StackTraceHeader.fromMatch(Match match) {
-    if (match == null) {
-      return null;
-    }
-    final isolateAddr = int.parse("0x" + match[1]);
-    final vmAddr = int.parse("0x" + match[2]);
-    return StackTraceHeader(isolateAddr, vmAddr);
-  }
-
-  PCOffset convertAbsoluteAddress(int address) {
-    int isolateOffset = address - _isolateStart;
-    int vmOffset = address - _vmStart;
-    if (vmOffset > 0 && vmOffset == min(vmOffset, isolateOffset)) {
-      return PCOffset(vmOffset, InstructionSection.vm);
-    } else {
-      return PCOffset(isolateOffset, InstructionSection.isolate);
-    }
-  }
-}
-
-PCOffset retrievePCOffset(StackTraceHeader header, Match match) {
-  assert(header != null && match != null);
-  final address = int.parse("0x" + match[2]);
-  return header.convertAbsoluteAddress(address);
-}
-
-// Returns the [PCOffset] for each frame's absolute PC address if [lines]
-// contains one or more DWARF stack traces.
-Iterable<PCOffset> collectPCOffsets(Iterable<String> lines) {
-  final ret = <PCOffset>[];
-  StackTraceHeader header = null;
-  for (var line in lines) {
-    if (line.endsWith(_traceStart)) {
-      header = null;
-    }
-    final startMatch = _traceInstructionsStartRE.firstMatch(line);
-    if (startMatch != null) {
-      header = StackTraceHeader.fromMatch(startMatch);
-      continue;
-    }
-    final lineMatch = _traceLineRE.firstMatch(line);
-    if (lineMatch != null) {
-      ret.add(retrievePCOffset(header, lineMatch));
-    }
-  }
-  return ret;
-}
-
-// Scans a stream of lines for Dart DWARF-based stack traces (i.e., Dart stack
-// traces where the frame entries include PC addresses). For each stack frame
-// found, the transformer attempts to locate a function name, file name and line
-// number using the provided DWARF information.
-//
-// If no information is found, or the line is not a stack frame, the line is
-// output to the sink unchanged.
-//
-// If the located information corresponds to Dart internals, the frame will be
-// dropped.
-//
-// Otherwise, at least one altered stack frame is generated and replaces the
-// stack frame portion of the original line. If the PC address corresponds to
-// inlined code, then multiple stack frames may be generated. When multiple
-// stack frames are generated, only the first replaces the stack frame portion
-// of the original line, and the remaining frames are separately output.
-class DwarfStackTraceDecoder extends StreamTransformerBase<String, String> {
-  final Dwarf _dwarf;
-  final bool includeInternalFrames;
-
-  DwarfStackTraceDecoder(this._dwarf, {this.includeInternalFrames = false});
-
-  Stream<String> bind(Stream<String> stream) => Stream<String>.eventTransformed(
-      stream,
-      (sink) => _DwarfStackTraceEventSink(sink, _dwarf,
-          includeInternalFrames: includeInternalFrames));
-}
-
-class _DwarfStackTraceEventSink implements EventSink<String> {
-  final EventSink<String> _sink;
-  final Dwarf _dwarf;
-  final bool includeInternalFrames;
-  int _cachedDepth = 0;
-  StackTraceHeader _cachedHeader = null;
-
-  _DwarfStackTraceEventSink(this._sink, this._dwarf,
-      {this.includeInternalFrames = false});
-
-  void close() => _sink.close();
-  void addError(Object e, [StackTrace st]) => _sink.addError(e, st);
-  Future addStream(Stream<String> stream) => stream.forEach(add);
-
-  void add(String line) {
-    // Reset any stack-related state when we see the start of a new
-    // stacktrace.
-    if (line.endsWith(_traceStart)) {
-      _cachedDepth = 0;
-      _cachedHeader = null;
-    }
-    final startMatch = _traceInstructionsStartRE.firstMatch(line);
-    if (startMatch != null) {
-      _cachedHeader = StackTraceHeader.fromMatch(startMatch);
-      _sink.add(line);
-      return;
-    }
-    final lineMatch = _traceLineRE.firstMatch(line);
-    if (lineMatch == null) {
-      _sink.add(line);
-      return;
-    }
-    final location =
-        retrievePCOffset(_cachedHeader, lineMatch).virtualAddress(_dwarf);
-    final callInfo = _dwarf
-        .callInfo(location, includeInternalFrames: includeInternalFrames)
-        ?.toList();
-    if (callInfo == null) {
-      // If we can't get appropriate information for the stack trace line,
-      // then just return the line unchanged.
-      _sink.add(line);
-      return;
-    } else if (callInfo.isEmpty) {
-      // No lines to output (as this corresponds to Dart internals).
-      return;
-    }
-    _sink.add(line.substring(0, lineMatch.start) +
-        _stackTracePiece(callInfo.first, _cachedDepth++));
-    for (int i = 1; i < callInfo.length; i++) {
-      _sink.add(_stackTracePiece(callInfo[i], _cachedDepth++));
-    }
-  }
-}
diff --git a/pkg/vm/lib/dwarf/dwarf.dart b/pkg/vm/lib/dwarf/dwarf.dart
deleted file mode 100644
index 204e747..0000000
--- a/pkg/vm/lib/dwarf/dwarf.dart
+++ /dev/null
@@ -1,1038 +0,0 @@
-// 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:math';
-
-import 'elf.dart';
-import 'reader.dart';
-
-int _initialLengthValue(Reader reader) {
-  final length = reader.readBytes(4);
-  if (length == 0xffffffff) {
-    throw FormatException("64-bit DWARF format detected");
-  } else if (length > 0xfffffff0) {
-    throw FormatException("Unrecognized reserved initial length value");
-  }
-  return length;
-}
-
-enum _Tag {
-  compileUnit,
-  inlinedSubroutine,
-  subprogram,
-}
-
-const _tags = <int, _Tag>{
-  0x11: _Tag.compileUnit,
-  0x1d: _Tag.inlinedSubroutine,
-  0x2e: _Tag.subprogram,
-};
-
-const _tagStrings = <_Tag, String>{
-  _Tag.compileUnit: "DW_TAG_compile_unit",
-  _Tag.inlinedSubroutine: "DW_TAG_inlined_subroutine",
-  _Tag.subprogram: "DW_TAG_subroutine",
-};
-
-enum _AttributeName {
-  abstractOrigin,
-  callColumn,
-  callFile,
-  callLine,
-  compilationDirectory,
-  declarationColumn,
-  declarationFile,
-  declarationLine,
-  highProgramCounter,
-  lowProgramCounter,
-  inline,
-  name,
-  producer,
-  sibling,
-  statementList,
-}
-
-const _attributeNames = <int, _AttributeName>{
-  0x01: _AttributeName.sibling,
-  0x03: _AttributeName.name,
-  0x10: _AttributeName.statementList,
-  0x11: _AttributeName.lowProgramCounter,
-  0x12: _AttributeName.highProgramCounter,
-  0x1b: _AttributeName.compilationDirectory,
-  0x20: _AttributeName.inline,
-  0x25: _AttributeName.producer,
-  0x31: _AttributeName.abstractOrigin,
-  0x39: _AttributeName.declarationColumn,
-  0x3a: _AttributeName.declarationFile,
-  0x3b: _AttributeName.declarationLine,
-  0x57: _AttributeName.callColumn,
-  0x58: _AttributeName.callFile,
-  0x59: _AttributeName.callLine,
-};
-
-const _attributeNameStrings = <_AttributeName, String>{
-  _AttributeName.sibling: "DW_AT_sibling",
-  _AttributeName.name: "DW_AT_name",
-  _AttributeName.statementList: "DW_AT_stmt_list",
-  _AttributeName.lowProgramCounter: "DW_AT_low_pc",
-  _AttributeName.highProgramCounter: "DW_AT_high_pc",
-  _AttributeName.compilationDirectory: "DW_AT_comp_dir",
-  _AttributeName.inline: "DW_AT_inline",
-  _AttributeName.producer: "DW_AT_producer",
-  _AttributeName.abstractOrigin: "DW_AT_abstract_origin",
-  _AttributeName.declarationColumn: "DW_AT_decl_column",
-  _AttributeName.declarationFile: "DW_AT_decl_file",
-  _AttributeName.declarationLine: "DW_AT_decl_line",
-  _AttributeName.callColumn: "DW_AT_call_column",
-  _AttributeName.callFile: "DW_AT_call_file",
-  _AttributeName.callLine: "DW_AT_call_line",
-};
-
-enum _AttributeForm {
-  address,
-  constant,
-  reference4,
-  sectionOffset,
-  string,
-}
-
-const _attributeForms = <int, _AttributeForm>{
-  0x01: _AttributeForm.address,
-  0x08: _AttributeForm.string,
-  0x0f: _AttributeForm.constant,
-  0x13: _AttributeForm.reference4,
-  0x17: _AttributeForm.sectionOffset,
-};
-
-const _attributeFormStrings = <_AttributeForm, String>{
-  _AttributeForm.address: "DW_FORM_addr",
-  _AttributeForm.string: "DW_FORM_string",
-  _AttributeForm.constant: "DW_FORM_udata",
-  _AttributeForm.reference4: "DW_FORM_ref4",
-  _AttributeForm.sectionOffset: "DW_FORM_sec_offset",
-};
-
-class _Attribute {
-  final _AttributeName name;
-  final _AttributeForm form;
-
-  _Attribute(this.name, this.form);
-}
-
-class _Abbreviation {
-  final Reader reader;
-
-  _Tag tag;
-  bool children;
-  List<_Attribute> attributes;
-
-  _Abbreviation.fromReader(Reader this.reader) {
-    _read();
-  }
-
-  // Constants from the DWARF specification.
-  static const _DW_CHILDREN_no = 0x00;
-  static const _DW_CHILDREN_yes = 0x01;
-
-  bool _readChildren() {
-    switch (reader.readByte()) {
-      case _DW_CHILDREN_no:
-        return false;
-      case _DW_CHILDREN_yes:
-        return true;
-      default:
-        throw FormatException("Expected DW_CHILDREN_no or DW_CHILDREN_yes");
-    }
-  }
-
-  void _read() {
-    reader.reset();
-    final tagInt = reader.readLEB128EncodedInteger();
-    if (!_tags.containsKey(tagInt)) {
-      throw FormatException("Unexpected DW_TAG value 0x${paddedHex(tagInt)}");
-    }
-    tag = _tags[tagInt];
-    children = _readChildren();
-    attributes = <_Attribute>[];
-    while (!reader.done) {
-      final nameInt = reader.readLEB128EncodedInteger();
-      final formInt = reader.readLEB128EncodedInteger();
-      if (nameInt == 0 && formInt == 0) {
-        break;
-      }
-      if (!_attributeNames.containsKey(nameInt)) {
-        throw FormatException("Unexpected DW_AT value 0x${paddedHex(nameInt)}");
-      }
-      if (!_attributeForms.containsKey(formInt)) {
-        throw FormatException(
-            "Unexpected DW_FORM value 0x${paddedHex(formInt)}");
-      }
-      attributes
-          .add(_Attribute(_attributeNames[nameInt], _attributeForms[formInt]));
-    }
-  }
-
-  String toString() {
-    var ret = "    Tag: ${_tagStrings[tag]}\n"
-        "    Children: ${children ? "DW_CHILDREN_yes" : "DW_CHILDREN_no"}\n"
-        "    Attributes:\n";
-    for (final attribute in attributes) {
-      ret += "      ${_attributeNameStrings[attribute.name]}: "
-          "${_attributeFormStrings[attribute.form]}\n";
-    }
-    return ret;
-  }
-}
-
-class _AbbreviationsTable {
-  final Reader reader;
-
-  Map<int, _Abbreviation> _abbreviations;
-
-  _AbbreviationsTable.fromReader(this.reader) {
-    _read();
-  }
-
-  bool containsKey(int code) => _abbreviations.containsKey(code);
-  _Abbreviation operator [](int code) => _abbreviations[code];
-
-  void _read() {
-    reader.reset();
-    _abbreviations = <int, _Abbreviation>{};
-    while (!reader.done) {
-      final code = reader.readLEB128EncodedInteger();
-      // Code of 0 marks end of abbreviations table.
-      if (code == 0) {
-        break;
-      }
-      final abbrev = _Abbreviation.fromReader(reader.shrink(reader.offset));
-      _abbreviations[code] = abbrev;
-      reader.seek(abbrev.reader.offset);
-    }
-  }
-
-  String toString() =>
-      "Abbreviations table:\n\n" +
-      _abbreviations.keys
-          .map((k) => "  Abbreviation $k:\n" + _abbreviations[k].toString())
-          .join("\n");
-}
-
-class DebugInformationEntry {
-  final Reader reader;
-  final CompilationUnit compilationUnit;
-
-  // The index of the entry in the abbreviation table for this DIE. If 0, then
-  // this is not actually a full DIE, but an end marker for a list of entries.
-  int code;
-  Map<_Attribute, Object> attributes;
-  List<DebugInformationEntry> children;
-
-  DebugInformationEntry.fromReader(this.reader, this.compilationUnit) {
-    _read();
-  }
-
-  Object _readAttribute(_Attribute attribute) {
-    switch (attribute.form) {
-      case _AttributeForm.string:
-        return reader.readNullTerminatedString();
-      case _AttributeForm.address:
-        return reader.readBytes(compilationUnit.addressSize);
-      case _AttributeForm.sectionOffset:
-        return reader.readBytes(4);
-      case _AttributeForm.constant:
-        return reader.readLEB128EncodedInteger();
-      case _AttributeForm.reference4:
-        return reader.readBytes(4);
-    }
-  }
-
-  String _nameOfOrigin(int offset) {
-    if (!compilationUnit.referenceTable.containsKey(offset)) {
-      throw ArgumentError(
-          "${paddedHex(offset)} is not the offset of an abbreviated unit");
-    }
-    final origin = compilationUnit.referenceTable[offset];
-    assert(origin.containsKey(_AttributeName.name));
-    return origin[_AttributeName.name] as String;
-  }
-
-  String _attributeValueToString(_Attribute attribute, Object value) {
-    switch (attribute.form) {
-      case _AttributeForm.string:
-        return value as String;
-      case _AttributeForm.address:
-        return paddedHex(value as int, compilationUnit.addressSize);
-      case _AttributeForm.sectionOffset:
-        return paddedHex(value as int, 4);
-      case _AttributeForm.constant:
-        return value.toString();
-      case _AttributeForm.reference4:
-        return paddedHex(value as int, 4) +
-            " (origin: ${_nameOfOrigin(value as int)})";
-    }
-  }
-
-  int get _unitOffset => reader.start - compilationUnit.reader.start;
-
-  void _read() {
-    reader.reset();
-    code = reader.readLEB128EncodedInteger();
-    // DIEs with an abbreviation table index of 0 are list end markers.
-    if (code == 0) {
-      return;
-    }
-    if (!compilationUnit.abbreviations.containsKey(code)) {
-      throw FormatException("Unknown abbreviation code 0x${paddedHex(code)}");
-    }
-    final abbreviation = compilationUnit.abbreviations[code];
-    attributes = <_Attribute, Object>{};
-    for (final attribute in abbreviation.attributes) {
-      attributes[attribute] = _readAttribute(attribute);
-    }
-    compilationUnit.referenceTable[_unitOffset] = this;
-    if (!abbreviation.children) return;
-    children = <DebugInformationEntry>[];
-    while (!reader.done) {
-      final child = DebugInformationEntry.fromReader(
-          reader.shrink(reader.offset), compilationUnit);
-      reader.seek(child.reader.offset);
-      if (child.code == 0) {
-        break;
-      }
-      children.add(child);
-    }
-  }
-
-  _Attribute _attributeForName(_AttributeName name) => attributes.keys
-      .firstWhere((_Attribute k) => k.name == name, orElse: () => null);
-
-  bool containsKey(_AttributeName name) => _attributeForName(name) != null;
-
-  Object operator [](_AttributeName name) {
-    final key = _attributeForName(name);
-    if (key == null) {
-      return null;
-    }
-    return attributes[key];
-  }
-
-  DebugInformationEntry get abstractOrigin {
-    final index = this[_AttributeName.abstractOrigin] as int;
-    return compilationUnit.referenceTable[index];
-  }
-
-  int get lowPC => this[_AttributeName.lowProgramCounter] as int;
-
-  int get highPC => this[_AttributeName.highProgramCounter] as int;
-
-  bool containsPC(int virtualAddress) =>
-      lowPC != null && lowPC <= virtualAddress && virtualAddress < highPC;
-
-  String get name => this[_AttributeName.name] as String;
-
-  int get callFileIndex => this[_AttributeName.callFile] as int;
-
-  int get callLine => this[_AttributeName.callLine] as int;
-
-  _Tag get tag => compilationUnit.abbreviations[code].tag;
-
-  List<CallInfo> callInfo(int address, LineNumberProgram lineNumberProgram) {
-    String callFilename(int index) => lineNumberProgram.filesInfo[index].name;
-    if (!containsPC(address)) {
-      return null;
-    }
-    final inlined = tag == _Tag.inlinedSubroutine;
-    for (final unit in children) {
-      final callInfo = unit.callInfo(address, lineNumberProgram);
-      if (callInfo == null) {
-        continue;
-      }
-      if (tag != _Tag.compileUnit) {
-        callInfo.add(CallInfo(
-            function: abstractOrigin.name,
-            inlined: inlined,
-            filename: callFilename(unit.callFileIndex),
-            line: unit.callLine));
-      }
-      return callInfo;
-    }
-    if (tag == _Tag.compileUnit) {
-      return null;
-    }
-    final filename = lineNumberProgram.filename(address);
-    final line = lineNumberProgram.lineNumber(address);
-    return [
-      CallInfo(
-          function: abstractOrigin.name,
-          inlined: inlined,
-          filename: filename,
-          line: line)
-    ];
-  }
-
-  String toString() {
-    var ret =
-        "Abbreviated unit (code $code, offset ${paddedHex(_unitOffset)}):\n";
-    for (final attribute in attributes.keys) {
-      ret += "  ${_attributeNameStrings[attribute.name]} => "
-          "${_attributeValueToString(attribute, attributes[attribute])}\n";
-    }
-    if (children == null || children.length == 0) {
-      ret += "Has no children.\n\n";
-      return ret;
-    }
-    ret += "Has ${children.length} " +
-        (children.length == 1 ? "child" : "children") +
-        "\n\n";
-    for (int i = 0; i < children.length; i++) {
-      ret += "Child ${i} of unit at offset ${paddedHex(_unitOffset)}:\n";
-      ret += children[i].toString();
-    }
-    return ret;
-  }
-}
-
-class CompilationUnit {
-  final Reader reader;
-  final Dwarf dwarf;
-
-  int size;
-  int version;
-  int abbreviationOffset;
-  int addressSize;
-  List<DebugInformationEntry> contents;
-  Map<int, DebugInformationEntry> referenceTable;
-
-  CompilationUnit.fromReader(this.reader, this.dwarf) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    size = _initialLengthValue(reader);
-    // An empty unit is an ending marker.
-    if (size == 0) {
-      return;
-    }
-    version = reader.readBytes(2);
-    if (version != 2) {
-      throw FormatException("Expected DWARF version 2, got $version");
-    }
-    abbreviationOffset = reader.readBytes(4);
-    if (!dwarf.abbreviationTables.containsKey(abbreviationOffset)) {
-      throw FormatException("No abbreviation table found for offset "
-          "0x${paddedHex(abbreviationOffset, 4)}");
-    }
-    addressSize = reader.readByte();
-    contents = <DebugInformationEntry>[];
-    referenceTable = <int, DebugInformationEntry>{};
-    while (!reader.done) {
-      final subunit =
-          DebugInformationEntry.fromReader(reader.shrink(reader.offset), this);
-      reader.seek(subunit.reader.offset);
-      if (subunit.code == 0) {
-        break;
-      }
-      assert(subunit.tag == _Tag.compileUnit);
-      contents.add(subunit);
-    }
-  }
-
-  Iterable<CallInfo> callInfo(int address) {
-    for (final unit in contents) {
-      final lineNumberProgram =
-          dwarf.lineNumberInfo[unit[_AttributeName.statementList]];
-      final callInfo = unit.callInfo(address, lineNumberProgram);
-      if (callInfo != null) {
-        return callInfo;
-      }
-    }
-    return null;
-  }
-
-  _AbbreviationsTable get abbreviations =>
-      dwarf.abbreviationTables[abbreviationOffset];
-
-  String toString() =>
-      "Compilation unit:\n"
-          "  Version: $version\n"
-          "  Abbreviation offset: ${paddedHex(abbreviationOffset, 4)}\n"
-          "  Address size: $addressSize\n\n" +
-      contents.map((DebugInformationEntry u) => u.toString()).join();
-}
-
-class DebugInfo {
-  final Reader reader;
-  final Dwarf dwarf;
-
-  List<CompilationUnit> units;
-
-  DebugInfo.fromReader(this.reader, this.dwarf) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    units = <CompilationUnit>[];
-    while (!reader.done) {
-      final unit =
-          CompilationUnit.fromReader(reader.shrink(reader.offset), dwarf);
-      reader.seek(unit.reader.offset);
-      if (unit.size == 0) {
-        break;
-      }
-      units.add(unit);
-    }
-  }
-
-  Iterable<CallInfo> callInfo(int address) {
-    for (final unit in units) {
-      final callInfo = unit.callInfo(address);
-      if (callInfo != null) {
-        return callInfo;
-      }
-    }
-    return null;
-  }
-
-  String toString() =>
-      "Debug information:\n\n" +
-      units.map((CompilationUnit u) => u.toString()).join();
-}
-
-class FileEntry {
-  final Reader reader;
-
-  String name;
-  int directoryIndex;
-  int lastModified;
-  int size;
-
-  FileEntry.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    name = reader.readNullTerminatedString();
-    if (name == "") {
-      return;
-    }
-    directoryIndex = reader.readLEB128EncodedInteger();
-    lastModified = reader.readLEB128EncodedInteger();
-    size = reader.readLEB128EncodedInteger();
-  }
-
-  String toString() => "File name: $name\n"
-      "  Directory index: $directoryIndex\n"
-      "  Last modified: $lastModified\n"
-      "  Size: $size\n";
-}
-
-class FileInfo {
-  final Reader reader;
-
-  Map<int, FileEntry> _files;
-
-  FileInfo.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    _files = <int, FileEntry>{};
-    int index = 1;
-    while (!reader.done) {
-      final file = FileEntry.fromReader(reader.shrink(reader.offset));
-      reader.seek(file.reader.offset);
-      // An empty null-terminated string marks the table end.
-      if (file.name == "") {
-        break;
-      }
-      _files[index] = file;
-      index++;
-    }
-  }
-
-  bool containsKey(int index) => _files.containsKey(index);
-  FileEntry operator [](int index) => _files[index];
-
-  String toString() {
-    if (_files.isEmpty) {
-      return "No file information.\n";
-    }
-
-    var ret = "File information:\n";
-
-    final indexHeader = "Entry";
-    final dirIndexHeader = "Dir";
-    final modifiedHeader = "Time";
-    final sizeHeader = "Size";
-    final nameHeader = "Name";
-
-    final indexStrings = _files
-        .map((int i, FileEntry f) => MapEntry<int, String>(i, i.toString()));
-    final dirIndexStrings = _files.map((int i, FileEntry f) =>
-        MapEntry<int, String>(i, f.directoryIndex.toString()));
-    final modifiedStrings = _files.map((int i, FileEntry f) =>
-        MapEntry<int, String>(i, f.lastModified.toString()));
-    final sizeStrings = _files.map(
-        (int i, FileEntry f) => MapEntry<int, String>(i, f.size.toString()));
-
-    final maxIndexLength = indexStrings.values
-        .fold(indexHeader.length, (int acc, String s) => max(acc, s.length));
-    final maxDirIndexLength = dirIndexStrings.values
-        .fold(dirIndexHeader.length, (int acc, String s) => max(acc, s.length));
-    final maxModifiedLength = modifiedStrings.values
-        .fold(modifiedHeader.length, (int acc, String s) => max(acc, s.length));
-    final maxSizeLength = sizeStrings.values
-        .fold(sizeHeader.length, (int acc, String s) => max(acc, s.length));
-
-    ret += " ${indexHeader.padRight(maxIndexLength)}";
-    ret += " ${dirIndexHeader.padRight(maxDirIndexLength)}";
-    ret += " ${modifiedHeader.padRight(maxModifiedLength)}";
-    ret += " ${sizeHeader.padRight(maxSizeLength)}";
-    ret += " $nameHeader\n";
-
-    for (final index in _files.keys) {
-      ret += " ${indexStrings[index].padRight(maxIndexLength)}";
-      ret += " ${dirIndexStrings[index].padRight(maxDirIndexLength)}";
-      ret += " ${modifiedStrings[index].padRight(maxModifiedLength)}";
-      ret += " ${sizeStrings[index].padRight(maxSizeLength)}";
-      ret += " ${_files[index].name}\n";
-    }
-
-    return ret;
-  }
-}
-
-class LineNumberState {
-  final defaultIsStatement;
-
-  int address;
-  int fileIndex;
-  int line;
-  int column;
-  bool isStatement;
-  bool basicBlock;
-  bool endSequence;
-
-  LineNumberState(bool this.defaultIsStatement) {
-    reset();
-  }
-
-  void reset() {
-    address = 0;
-    fileIndex = 1;
-    line = 1;
-    column = 0;
-    isStatement = defaultIsStatement;
-    basicBlock = false;
-    endSequence = false;
-  }
-
-  LineNumberState clone() {
-    final clone = LineNumberState(defaultIsStatement);
-    clone.address = address;
-    clone.fileIndex = fileIndex;
-    clone.line = line;
-    clone.column = column;
-    clone.isStatement = isStatement;
-    clone.basicBlock = basicBlock;
-    clone.endSequence = endSequence;
-    return clone;
-  }
-
-  String toString() => "Current line number state machine registers:\n"
-      "  Address: ${paddedHex(address)}\n"
-      "  File index: $fileIndex\n"
-      "  Line number: $line\n"
-      "  Column number: $column\n"
-      "  Is ${isStatement ? "" : "not "}a statement.\n"
-      "  Is ${basicBlock ? "" : "not "}at the beginning of a basic block.\n"
-      "  Is ${endSequence ? "" : "not "}just after the end of a sequence.\n";
-}
-
-class LineNumberProgram {
-  final Reader reader;
-
-  int size;
-  int version;
-  int headerLength;
-  int minimumInstructionLength;
-  bool defaultIsStatement;
-  int lineBase;
-  int lineRange;
-  int opcodeBase;
-  Map<int, int> standardOpcodeLengths;
-  List<String> includeDirectories;
-  FileInfo filesInfo;
-  List<LineNumberState> calculatedMatrix;
-  Map<int, LineNumberState> cachedLookups;
-
-  LineNumberProgram.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    size = _initialLengthValue(reader);
-    if (size == 0) {
-      return;
-    }
-    version = reader.readBytes(2);
-    headerLength = reader.readBytes(4);
-    minimumInstructionLength = reader.readByte();
-    switch (reader.readByte()) {
-      case 0:
-        defaultIsStatement = false;
-        break;
-      case 1:
-        defaultIsStatement = true;
-        break;
-      default:
-        throw FormatException("Unexpected value for default_is_stmt");
-    }
-    lineBase = reader.readByte(signed: true);
-    lineRange = reader.readByte();
-    opcodeBase = reader.readByte();
-    standardOpcodeLengths = <int, int>{};
-    // Standard opcode numbering starts at 1.
-    for (int i = 1; i < opcodeBase; i++) {
-      standardOpcodeLengths[i] = reader.readLEB128EncodedInteger();
-    }
-    includeDirectories = <String>[];
-    while (!reader.done) {
-      final directory = reader.readNullTerminatedString();
-      if (directory == "") {
-        break;
-      }
-      includeDirectories.add(directory);
-    }
-    filesInfo = FileInfo.fromReader(reader.shrink(reader.offset));
-    reader.seek(filesInfo.reader.offset);
-    // Header length doesn't include the 4-byte length or 2-byte version fields.
-    assert(reader.offset == headerLength + 6);
-    calculatedMatrix = <LineNumberState>[];
-    final currentState = LineNumberState(defaultIsStatement);
-    while (!reader.done) {
-      _applyNextOpcode(currentState);
-    }
-    if (calculatedMatrix.length == 0) {
-      throw FormatException("No line number information generated by program");
-    }
-    // Set the offset to the declared size in case of padding.  The declared
-    // size does not include the size of the size field itself.
-    reader.seek(size + 4);
-    cachedLookups = <int, LineNumberState>{};
-  }
-
-  void _addStateToMatrix(LineNumberState state) {
-    calculatedMatrix.add(state.clone());
-  }
-
-  void _applyNextOpcode(LineNumberState state) {
-    void applySpecialOpcode(int opcode) {
-      final adjustedOpcode = opcode - opcodeBase;
-      state.address = adjustedOpcode ~/ lineRange;
-      state.line += lineBase + (adjustedOpcode % lineRange);
-    }
-
-    final opcode = reader.readByte();
-    if (opcode >= opcodeBase) {
-      return applySpecialOpcode(opcode);
-    }
-    switch (opcode) {
-      case 0: // Extended opcodes
-        final extendedLength = reader.readByte();
-        final subOpcode = reader.readByte();
-        switch (subOpcode) {
-          case 0:
-            throw FormatException(
-                "Attempted to execute extended opcode ${subOpcode} (padding?)");
-          case 1: // DW_LNE_end_sequence
-            state.endSequence = true;
-            _addStateToMatrix(state);
-            state.reset();
-            break;
-          case 2: // DW_LNE_set_address
-            // The length includes the subopcode.
-            final valueLength = extendedLength - 1;
-            assert(valueLength == 4 || valueLength == 8);
-            final newAddress = reader.readBytes(valueLength);
-            state.address = newAddress;
-            break;
-          case 3: // DW_LNE_define_file
-            throw FormatException("DW_LNE_define_file instruction not handled");
-          default:
-            throw FormatException(
-                "Extended opcode ${subOpcode} not in DWARF 2");
-        }
-        break;
-      case 1: // DW_LNS_copy
-        _addStateToMatrix(state);
-        state.basicBlock = false;
-        break;
-      case 2: // DW_LNS_advance_pc
-        final increment = reader.readLEB128EncodedInteger();
-        state.address += minimumInstructionLength * increment;
-        break;
-      case 3: // DW_LNS_advance_line
-        state.line += reader.readLEB128EncodedInteger(signed: true);
-        break;
-      case 4: // DW_LNS_set_file
-        state.fileIndex = reader.readLEB128EncodedInteger();
-        break;
-      case 5: // DW_LNS_set_column
-        state.column = reader.readLEB128EncodedInteger();
-        break;
-      case 6: // DW_LNS_negate_stmt
-        state.isStatement = !state.isStatement;
-        break;
-      case 7: // DW_LNS_set_basic_block
-        state.basicBlock = true;
-        break;
-      case 8: // DW_LNS_const_add_pc
-        applySpecialOpcode(255);
-        break;
-      case 9: // DW_LNS_fixed_advance_pc
-        state.address += reader.readBytes(2);
-        break;
-      default:
-        throw FormatException("Standard opcode ${opcode} not in DWARF 2");
-    }
-  }
-
-  bool containsKey(int address) {
-    assert(calculatedMatrix.last.endSequence);
-    return address >= calculatedMatrix.first.address &&
-        address < calculatedMatrix.last.address;
-  }
-
-  LineNumberState operator [](int address) {
-    if (cachedLookups.containsKey(address)) {
-      return cachedLookups[address];
-    }
-    if (!containsKey(address)) {
-      return null;
-    }
-    // Since the addresses are generated in increasing order, we can do a
-    // binary search to find the right state.
-    assert(calculatedMatrix != null && calculatedMatrix.isNotEmpty);
-    var minIndex = 0;
-    var maxIndex = calculatedMatrix.length - 1;
-    while (true) {
-      if (minIndex == maxIndex || minIndex + 1 == maxIndex) {
-        final found = calculatedMatrix[minIndex];
-        cachedLookups[address] = found;
-        return found;
-      }
-      final index = minIndex + ((maxIndex - minIndex) ~/ 2);
-      final compared = calculatedMatrix[index].address.compareTo(address);
-      if (compared == 0) {
-        return calculatedMatrix[index];
-      } else if (compared < 0) {
-        minIndex = index;
-      } else if (compared > 0) {
-        maxIndex = index;
-      }
-    }
-  }
-
-  String filename(int address) {
-    final state = this[address];
-    if (state == null) {
-      return null;
-    }
-    return filesInfo[state.fileIndex].name;
-  }
-
-  int lineNumber(int address) {
-    final state = this[address];
-    if (state == null) {
-      return null;
-    }
-    return state.line;
-  }
-
-  String toString() {
-    var ret = "  Size: $size\n"
-        "  Version: $version\n"
-        "  Header length: $headerLength\n"
-        "  Min instruction length: $minimumInstructionLength\n"
-        "  Default value of is_stmt: $defaultIsStatement\n"
-        "  Line base: $lineBase\n"
-        "  Line range: $lineRange\n"
-        "  Opcode base: $opcodeBase\n"
-        "  Standard opcode lengths:\n";
-    for (int i = 1; i < opcodeBase; i++) {
-      ret += "    Opcode $i: ${standardOpcodeLengths[i]}\n";
-    }
-
-    if (includeDirectories.isEmpty) {
-      ret += "No include directories.\n";
-    } else {
-      ret += "Include directories:\n";
-      for (final dir in includeDirectories) {
-        ret += "    $dir\n";
-      }
-    }
-
-    ret += "${filesInfo}\nResults of line number program:\n";
-    ret += calculatedMatrix.map((LineNumberState s) => s.toString()).join();
-
-    return ret;
-  }
-}
-
-class LineNumberInfo {
-  final Reader reader;
-
-  Map<int, LineNumberProgram> programs;
-
-  LineNumberInfo.fromReader(this.reader) {
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    programs = <int, LineNumberProgram>{};
-    while (!reader.done) {
-      final start = reader.offset;
-      final program = LineNumberProgram.fromReader(reader.shrink(start));
-      reader.seek(program.reader.offset);
-      if (program.size == 0) {
-        break;
-      }
-      programs[start] = program;
-    }
-  }
-
-  bool containsKey(int address) => programs.containsKey(address);
-  LineNumberProgram operator [](int address) => programs[address];
-
-  String toString() =>
-      "Line number information:\n\n" +
-      programs
-          .map((int i, LineNumberProgram p) =>
-              MapEntry(i, "Line number program @ 0x${paddedHex(i)}:\n$p\n"))
-          .values
-          .join();
-}
-
-// TODO(11617): Replace calls to these functions with a general hashing solution
-// once available.
-int _hashCombine(int hash, int value) {
-  hash = 0x1fffffff & (hash + value);
-  hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
-  return hash ^ (hash >> 6);
-}
-
-int _hashFinish(int hash) {
-  hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
-  hash = hash ^ (hash >> 11);
-  return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
-}
-
-class CallInfo {
-  final bool inlined;
-  final String function;
-  final String filename;
-  final int line;
-
-  CallInfo({this.inlined = false, this.function, this.filename, this.line});
-
-  int get hashCode => _hashFinish(_hashCombine(
-      _hashCombine(
-          _hashCombine(_hashCombine(0, inlined.hashCode), function.hashCode),
-          filename.hashCode),
-      line.hashCode));
-
-  bool operator ==(Object other) {
-    if (other is CallInfo) {
-      return inlined == other.inlined &&
-          function == other.function &&
-          filename == other.filename &&
-          line == other.line;
-    }
-    return false;
-  }
-
-  String toString() =>
-      "${function} (${filename}:${line <= 0 ? "??" : line.toString()})";
-}
-
-class Dwarf {
-  final Elf elf;
-  Map<int, _AbbreviationsTable> abbreviationTables;
-  DebugInfo debugInfo;
-  LineNumberInfo lineNumberInfo;
-  int vmStartAddress;
-  int isolateStartAddress;
-
-  Dwarf.fromElf(Elf this.elf) {
-    _loadSections();
-  }
-
-  factory Dwarf.fromFile(String filename) {
-    final elf = Elf.fromFile(filename);
-    return Dwarf.fromElf(elf);
-  }
-
-  void _loadSections() {
-    final abbrevSection = elf.namedSection(".debug_abbrev").first;
-    abbreviationTables = <int, _AbbreviationsTable>{};
-    var abbreviationOffset = 0;
-    while (abbreviationOffset < abbrevSection.reader.length) {
-      final table = _AbbreviationsTable.fromReader(
-          abbrevSection.reader.shrink(abbreviationOffset));
-      abbreviationTables[abbreviationOffset] = table;
-      abbreviationOffset += table.reader.offset;
-    }
-    assert(abbreviationOffset == abbrevSection.reader.length);
-
-    final lineNumberSection = elf.namedSection(".debug_line").first;
-    lineNumberInfo = LineNumberInfo.fromReader(lineNumberSection.reader);
-
-    final infoSection = elf.namedSection(".debug_info").first;
-    debugInfo = DebugInfo.fromReader(infoSection.reader, this);
-
-    final textSegments = elf.namedSection(".text");
-    if (textSegments.length != 2) {
-      throw FormatException(
-          "Expected two text segments for VM and isolate instructions");
-    }
-
-    final textAddresses = textSegments.map((s) => s.headerEntry.addr).toList();
-    vmStartAddress = textAddresses[0];
-    isolateStartAddress = textAddresses[1];
-  }
-
-  Iterable<CallInfo> callInfo(int address,
-      {bool includeInternalFrames = false}) {
-    final calls = debugInfo.callInfo(address);
-    if (calls != null && !includeInternalFrames) {
-      return calls.where((CallInfo c) => c.line > 0);
-    }
-    return calls;
-  }
-
-  int convertToVMVirtualAddress(int textOffset) {
-    return textOffset + vmStartAddress;
-  }
-
-  int convertToIsolateVirtualAddress(int textOffset) {
-    return textOffset + isolateStartAddress;
-  }
-
-  String toString() =>
-      "DWARF debugging information:\n\n" +
-      abbreviationTables
-          .map((int i, _AbbreviationsTable t) =>
-              MapEntry(i, "(Offset ${paddedHex(i)}) $t"))
-          .values
-          .join() +
-      "\n$debugInfo\n$lineNumberInfo";
-}
diff --git a/pkg/vm/lib/dwarf/elf.dart b/pkg/vm/lib/dwarf/elf.dart
deleted file mode 100644
index 0f0845b..0000000
--- a/pkg/vm/lib/dwarf/elf.dart
+++ /dev/null
@@ -1,560 +0,0 @@
-// 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:typed_data';
-import 'dart:io';
-
-import 'reader.dart';
-
-int _readElfBytes(Reader reader, int bytes, int alignment) {
-  final alignOffset = reader.offset % alignment;
-  if (alignOffset != 0) {
-    // Move the reader to the next aligned position.
-    reader.seek(reader.offset - alignOffset + alignment);
-  }
-  return reader.readBytes(bytes);
-}
-
-// Reads an Elf{32,64}_Addr.
-int _readElfAddress(Reader reader) {
-  return _readElfBytes(reader, reader.wordSize, reader.wordSize);
-}
-
-// Reads an Elf{32,64}_Off.
-int _readElfOffset(Reader reader) {
-  return _readElfBytes(reader, reader.wordSize, reader.wordSize);
-}
-
-// Reads an Elf{32,64}_Half.
-int _readElfHalf(Reader reader) {
-  return _readElfBytes(reader, 2, 2);
-}
-
-// Reads an Elf{32,64}_Word.
-int _readElfWord(Reader reader) {
-  return _readElfBytes(reader, 4, 4);
-}
-
-// Reads an Elf64_Xword.
-int _readElfXword(Reader reader) {
-  switch (reader.wordSize) {
-    case 4:
-      throw "Internal reader error: reading Elf64_Xword in 32-bit ELF file";
-    case 8:
-      return _readElfBytes(reader, 8, 8);
-    default:
-      throw "Unsupported word size ${reader.wordSize}";
-  }
-}
-
-// Used in cases where the value read for a given field is Elf32_Word on 32-bit
-// and Elf64_Xword on 64-bit.
-int _readElfNative(Reader reader) {
-  switch (reader.wordSize) {
-    case 4:
-      return _readElfWord(reader);
-    case 8:
-      return _readElfXword(reader);
-    default:
-      throw "Unsupported word size ${reader.wordSize}";
-  }
-}
-
-class ElfHeader {
-  final Reader startingReader;
-
-  int wordSize;
-  Endian endian;
-  int entry;
-  int flags;
-  int headerSize;
-  int programHeaderOffset;
-  int sectionHeaderOffset;
-  int programHeaderCount;
-  int sectionHeaderCount;
-  int programHeaderEntrySize;
-  int sectionHeaderEntrySize;
-  int sectionHeaderStringsIndex;
-
-  int get programHeaderSize => programHeaderCount * programHeaderEntrySize;
-  int get sectionHeaderSize => sectionHeaderCount * sectionHeaderEntrySize;
-
-  // Constants used within the ELF specification.
-  static const _ELFMAG = "\x7fELF";
-  static const _ELFCLASS32 = 0x01;
-  static const _ELFCLASS64 = 0x02;
-  static const _ELFDATA2LSB = 0x01;
-  static const _ELFDATA2MSB = 0x02;
-
-  ElfHeader.fromReader(Reader this.startingReader) {
-    _read();
-  }
-
-  static bool startsWithMagicNumber(Reader reader) {
-    reader.reset();
-    for (final sigByte in _ELFMAG.codeUnits) {
-      if (reader.readByte() != sigByte) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  int _readWordSize(Reader reader) {
-    switch (reader.readByte()) {
-      case _ELFCLASS32:
-        return 4;
-      case _ELFCLASS64:
-        return 8;
-      default:
-        throw FormatException("Unexpected e_ident[EI_CLASS] value");
-    }
-  }
-
-  int get calculatedHeaderSize => 0x18 + 3 * wordSize + 0x10;
-
-  Endian _readEndian(Reader reader) {
-    switch (reader.readByte()) {
-      case _ELFDATA2LSB:
-        return Endian.little;
-      case _ELFDATA2MSB:
-        return Endian.big;
-      default:
-        throw FormatException("Unexpected e_indent[EI_DATA] value");
-    }
-  }
-
-  void _read() {
-    startingReader.reset();
-    for (final sigByte in _ELFMAG.codeUnits) {
-      if (startingReader.readByte() != sigByte) {
-        throw FormatException("Not an ELF file");
-      }
-    }
-    wordSize = _readWordSize(startingReader);
-    final fileSize = startingReader.bdata.buffer.lengthInBytes;
-    if (fileSize < calculatedHeaderSize) {
-      throw FormatException("ELF file too small for header: "
-          "file size ${fileSize} < "
-          "calculated header size $calculatedHeaderSize");
-    }
-    endian = _readEndian(startingReader);
-    if (startingReader.readByte() != 0x01) {
-      throw FormatException("Unexpected e_ident[EI_VERSION] value");
-    }
-
-    // After this point, we need the reader to be correctly set up re: word
-    // size and endianness, since we start reading more than single bytes.
-    final reader = Reader.fromTypedData(startingReader.bdata,
-        wordSize: wordSize, endian: endian);
-    reader.seek(startingReader.offset);
-
-    // Skip rest of e_ident/e_type/e_machine, i.e. move to e_version.
-    reader.seek(0x14, absolute: true);
-    if (_readElfWord(reader) != 0x01) {
-      throw FormatException("Unexpected e_version value");
-    }
-
-    entry = _readElfAddress(reader);
-    programHeaderOffset = _readElfOffset(reader);
-    sectionHeaderOffset = _readElfOffset(reader);
-    flags = _readElfWord(reader);
-    headerSize = _readElfHalf(reader);
-    programHeaderEntrySize = _readElfHalf(reader);
-    programHeaderCount = _readElfHalf(reader);
-    sectionHeaderEntrySize = _readElfHalf(reader);
-    sectionHeaderCount = _readElfHalf(reader);
-    sectionHeaderStringsIndex = _readElfHalf(reader);
-
-    if (headerSize != calculatedHeaderSize) {
-      throw FormatException("Stored ELF header size ${headerSize} != "
-          "calculated ELF header size $calculatedHeaderSize");
-    }
-    if (fileSize < programHeaderOffset) {
-      throw FormatException("File is truncated before program header");
-    }
-    if (fileSize < programHeaderOffset + programHeaderSize) {
-      throw FormatException("File is truncated within the program header");
-    }
-    if (fileSize < sectionHeaderOffset) {
-      throw FormatException("File is truncated before section header");
-    }
-    if (fileSize < sectionHeaderOffset + sectionHeaderSize) {
-      throw FormatException("File is truncated within the section header");
-    }
-  }
-
-  String toString() {
-    var ret = "Format is ${wordSize * 8} bits\n";
-    switch (endian) {
-      case Endian.little:
-        ret += "Little-endian format\n";
-        break;
-      case Endian.big:
-        ret += "Big-endian format\n";
-        break;
-    }
-    ret += "Entry point: 0x${paddedHex(entry, wordSize)}\n"
-        "Flags: 0x${paddedHex(flags, 4)}\n"
-        "Header size: ${headerSize}\n"
-        "Program header offset: "
-        "0x${paddedHex(programHeaderOffset, wordSize)}\n"
-        "Program header entry size: ${programHeaderEntrySize}\n"
-        "Program header entry count: ${programHeaderCount}\n"
-        "Section header offset: "
-        "0x${paddedHex(sectionHeaderOffset, wordSize)}\n"
-        "Section header entry size: ${sectionHeaderEntrySize}\n"
-        "Section header entry count: ${sectionHeaderCount}\n"
-        "Section header strings index: ${sectionHeaderStringsIndex}\n";
-    return ret;
-  }
-}
-
-class ProgramHeaderEntry {
-  Reader reader;
-
-  int type;
-  int flags;
-  int offset;
-  int vaddr;
-  int paddr;
-  int filesz;
-  int memsz;
-  int align;
-
-  // p_type constants from ELF specification.
-  static const _PT_NULL = 0;
-  static const _PT_LOAD = 1;
-  static const _PT_DYNAMIC = 2;
-  static const _PT_PHDR = 6;
-
-  ProgramHeaderEntry.fromReader(Reader this.reader) {
-    assert(reader.wordSize == 4 || reader.wordSize == 8);
-    _read();
-  }
-
-  void _read() {
-    reader.reset();
-    type = _readElfWord(reader);
-    if (reader.wordSize == 8) {
-      flags = _readElfWord(reader);
-    }
-    offset = _readElfOffset(reader);
-    vaddr = _readElfAddress(reader);
-    paddr = _readElfAddress(reader);
-    filesz = _readElfNative(reader);
-    memsz = _readElfNative(reader);
-    if (reader.wordSize == 4) {
-      flags = _readElfWord(reader);
-    }
-    align = _readElfNative(reader);
-  }
-
-  static const _typeStrings = <int, String>{
-    _PT_NULL: "PT_NULL",
-    _PT_LOAD: "PT_LOAD",
-    _PT_DYNAMIC: "PT_DYNAMIC",
-    _PT_PHDR: "PT_PHDR",
-  };
-
-  static String _typeToString(int type) {
-    if (_typeStrings.containsKey(type)) {
-      return _typeStrings[type];
-    }
-    return "unknown (${paddedHex(type, 4)})";
-  }
-
-  String toString() => "Type: ${_typeToString(type)}\n"
-      "Flags: 0x${paddedHex(flags, 4)}\n"
-      "Offset: $offset (0x${paddedHex(offset, reader.wordSize)})\n"
-      "Virtual address: 0x${paddedHex(vaddr, reader.wordSize)}\n"
-      "Physical address: 0x${paddedHex(paddr, reader.wordSize)}\n"
-      "Size in file: $filesz\n"
-      "Size in memory: $memsz\n"
-      "Alignment: 0x${paddedHex(align, reader.wordSize)}\n";
-}
-
-class ProgramHeader {
-  final Reader reader;
-  final int entrySize;
-  final int entryCount;
-
-  List<ProgramHeaderEntry> _entries;
-
-  ProgramHeader.fromReader(Reader this.reader,
-      {int this.entrySize, int this.entryCount}) {
-    _read();
-  }
-
-  int get length => _entries.length;
-  ProgramHeaderEntry operator [](int index) => _entries[index];
-
-  void _read() {
-    reader.reset();
-    _entries = <ProgramHeaderEntry>[];
-    for (var i = 0; i < entryCount; i++) {
-      final entry = ProgramHeaderEntry.fromReader(
-          reader.shrink(i * entrySize, entrySize));
-      _entries.add(entry);
-    }
-  }
-
-  String toString() {
-    var ret = "";
-    for (var i = 0; i < length; i++) {
-      ret += "Entry $i:\n${this[i]}\n";
-    }
-    return ret;
-  }
-}
-
-class SectionHeaderEntry {
-  final Reader reader;
-
-  int nameIndex;
-  String name;
-  int type;
-  int flags;
-  int addr;
-  int offset;
-  int size;
-  int link;
-  int info;
-  int addrAlign;
-  int entrySize;
-
-  SectionHeaderEntry.fromReader(this.reader) {
-    _read();
-  }
-
-  // sh_type constants from ELF specification.
-  static const _SHT_NULL = 0;
-  static const _SHT_PROGBITS = 1;
-  static const _SHT_SYMTAB = 2;
-  static const _SHT_STRTAB = 3;
-  static const _SHT_HASH = 5;
-  static const _SHT_DYNAMIC = 6;
-  static const _SHT_NOBITS = 8;
-  static const _SHT_DYNSYM = 11;
-
-  void _read() {
-    reader.reset();
-    nameIndex = _readElfWord(reader);
-    type = _readElfWord(reader);
-    flags = _readElfNative(reader);
-    addr = _readElfAddress(reader);
-    offset = _readElfOffset(reader);
-    size = _readElfNative(reader);
-    link = _readElfWord(reader);
-    info = _readElfWord(reader);
-    addrAlign = _readElfNative(reader);
-    entrySize = _readElfNative(reader);
-  }
-
-  void setName(StringTable nameTable) {
-    name = nameTable[nameIndex];
-  }
-
-  static const _typeStrings = <int, String>{
-    _SHT_NULL: "SHT_NULL",
-    _SHT_PROGBITS: "SHT_PROGBITS",
-    _SHT_SYMTAB: "SHT_SYMTAB",
-    _SHT_STRTAB: "SHT_STRTAB",
-    _SHT_HASH: "SHT_HASH",
-    _SHT_DYNAMIC: "SHT_DYNAMIC",
-    _SHT_NOBITS: "SHT_NOBITS",
-    _SHT_DYNSYM: "SHT_DYNSYM",
-  };
-
-  static String _typeToString(int type) {
-    if (_typeStrings.containsKey(type)) {
-      return _typeStrings[type];
-    }
-    return "unknown (${paddedHex(type, 4)})";
-  }
-
-  String toString() => "Name: ${name} (@ ${nameIndex})\n"
-      "Type: ${_typeToString(type)}\n"
-      "Flags: 0x${paddedHex(flags, reader.wordSize)}\n"
-      "Address: 0x${paddedHex(addr, reader.wordSize)}\n"
-      "Offset: $offset (0x${paddedHex(offset, reader.wordSize)})\n"
-      "Size: $size\n"
-      "Link: $link\n"
-      "Info: 0x${paddedHex(info, 4)}\n"
-      "Address alignment: 0x${paddedHex(addrAlign, reader.wordSize)}\n"
-      "Entry size: ${entrySize}\n";
-}
-
-class SectionHeader {
-  final Reader reader;
-  final int entrySize;
-  final int entryCount;
-  final int stringsIndex;
-
-  List<SectionHeaderEntry> _entries;
-  StringTable nameTable = null;
-
-  SectionHeader.fromReader(this.reader,
-      {this.entrySize, this.entryCount, this.stringsIndex}) {
-    _read();
-  }
-
-  SectionHeaderEntry _readSectionHeaderEntry(int index) {
-    final ret = SectionHeaderEntry.fromReader(
-        reader.shrink(index * entrySize, entrySize));
-    if (nameTable != null) {
-      ret.setName(nameTable);
-    }
-    return ret;
-  }
-
-  void _read() {
-    reader.reset();
-    // Set up the section header string table first so we can use it
-    // for the other section header entries.
-    final nameTableEntry = _readSectionHeaderEntry(stringsIndex);
-    assert(nameTableEntry.type == SectionHeaderEntry._SHT_STRTAB);
-    nameTable = StringTable(nameTableEntry,
-        reader.refocus(nameTableEntry.offset, nameTableEntry.size));
-    nameTableEntry.setName(nameTable);
-
-    _entries = <SectionHeaderEntry>[];
-    for (var i = 0; i < entryCount; i++) {
-      // We don't need to reparse the shstrtab entry.
-      if (i == stringsIndex) {
-        _entries.add(nameTableEntry);
-      } else {
-        _entries.add(_readSectionHeaderEntry(i));
-      }
-    }
-  }
-
-  int get length => _entries.length;
-  SectionHeaderEntry operator [](int index) => _entries[index];
-
-  String toString() {
-    var ret = "";
-    for (var i = 0; i < length; i++) {
-      ret += "Entry $i:\n${this[i]}\n";
-    }
-    return ret;
-  }
-}
-
-class Section {
-  final Reader reader;
-  final SectionHeaderEntry headerEntry;
-
-  Section(this.headerEntry, this.reader);
-
-  factory Section.fromEntryAndReader(SectionHeaderEntry entry, Reader reader) {
-    switch (entry.type) {
-      case SectionHeaderEntry._SHT_STRTAB:
-        return StringTable(entry, reader);
-      default:
-        return Section(entry, reader);
-    }
-  }
-
-  int get length => reader.bdata.lengthInBytes;
-  String toString() => "an unparsed section of ${length} bytes\n";
-}
-
-class StringTable extends Section {
-  final _entries = Map<int, String>();
-
-  StringTable(SectionHeaderEntry entry, Reader reader) : super(entry, reader) {
-    while (!reader.done) {
-      _entries[reader.offset] = reader.readNullTerminatedString();
-    }
-  }
-
-  String operator [](int index) => _entries[index];
-
-  String toString() => _entries.keys.fold("a string table:\n",
-      (String acc, int key) => acc + "  $key => ${_entries[key]}\n");
-}
-
-class Elf {
-  final Reader startingReader;
-
-  ElfHeader header;
-  ProgramHeader programHeader;
-  SectionHeader sectionHeader;
-
-  Map<SectionHeaderEntry, Section> sections;
-
-  Elf.fromReader(this.startingReader) {
-    _read();
-  }
-  Elf.fromFile(String filename)
-      : this.fromReader(Reader.fromTypedData(File(filename).readAsBytesSync(),
-            // We provide null for the wordSize and endianness to ensure
-            // we don't accidentally call any methods that use them until
-            // we have gotten that information from the ELF header.
-            wordSize: null,
-            endian: null));
-
-  static bool startsWithMagicNumber(String filename) {
-    final file = File(filename).openSync();
-    var ret = true;
-    for (int code in ElfHeader._ELFMAG.codeUnits) {
-      if (file.readByteSync() != code) {
-        ret = false;
-        break;
-      }
-    }
-    file.closeSync();
-    return ret;
-  }
-
-  Iterable<Section> namedSection(String name) {
-    final ret = <Section>[];
-    for (var entry in sections.keys) {
-      if (entry.name == name) {
-        ret.add(sections[entry]);
-      }
-    }
-    if (ret.isEmpty) {
-      throw FormatException("No section named $name found in ELF file");
-    }
-    return ret;
-  }
-
-  void _read() {
-    startingReader.reset();
-    header = ElfHeader.fromReader(startingReader.copy());
-    // Now use the word size and endianness information from the header.
-    final reader = Reader.fromTypedData(startingReader.bdata,
-        wordSize: header.wordSize, endian: header.endian);
-    programHeader = ProgramHeader.fromReader(
-        reader.refocus(header.programHeaderOffset, header.programHeaderSize),
-        entrySize: header.programHeaderEntrySize,
-        entryCount: header.programHeaderCount);
-    sectionHeader = SectionHeader.fromReader(
-        reader.refocus(header.sectionHeaderOffset, header.sectionHeaderSize),
-        entrySize: header.sectionHeaderEntrySize,
-        entryCount: header.sectionHeaderCount,
-        stringsIndex: header.sectionHeaderStringsIndex);
-    sections = <SectionHeaderEntry, Section>{};
-    for (var i = 0; i < sectionHeader.length; i++) {
-      final entry = sectionHeader[i];
-      if (i == header.sectionHeaderStringsIndex) {
-        sections[entry] = sectionHeader.nameTable;
-      } else {
-        sections[entry] = Section.fromEntryAndReader(
-            entry, reader.refocus(entry.offset, entry.size));
-      }
-    }
-  }
-
-  String toString() {
-    String accumulateSection(String acc, SectionHeaderEntry entry) =>
-        acc + "\nSection ${entry.name} is ${sections[entry]}";
-    return "Header information:\n\n${header}"
-        "\nProgram header information:\n\n${programHeader}"
-        "\nSection header information:\n\n${sectionHeader}"
-        "${sections.keys.fold("", accumulateSection)}";
-  }
-}
diff --git a/pkg/vm/lib/dwarf/reader.dart b/pkg/vm/lib/dwarf/reader.dart
deleted file mode 100644
index c950ef5..0000000
--- a/pkg/vm/lib/dwarf/reader.dart
+++ /dev/null
@@ -1,147 +0,0 @@
-// 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 vm.elf.reader;
-
-import 'dart:typed_data';
-import 'dart:math';
-
-String paddedHex(int value, [int bytes = 0]) {
-  return value.toRadixString(16).padLeft(2 * bytes, '0');
-}
-
-class Reader {
-  final ByteData bdata;
-  final Endian endian;
-  final int wordSize;
-
-  int _offset = 0;
-
-  Reader.fromTypedData(TypedData data, {int this.wordSize, Endian this.endian})
-      : bdata =
-            ByteData.view(data.buffer, data.offsetInBytes, data.lengthInBytes);
-
-  Reader copy() =>
-      Reader.fromTypedData(bdata, wordSize: wordSize, endian: endian);
-
-  Reader shrink(int offset, [int size = -1]) {
-    if (size < 0) size = bdata.lengthInBytes - offset;
-    assert(offset >= 0 && offset < bdata.lengthInBytes);
-    assert(size >= 0 && (offset + size) <= bdata.lengthInBytes);
-    return Reader.fromTypedData(
-        ByteData.view(bdata.buffer, bdata.offsetInBytes + offset, size),
-        wordSize: wordSize,
-        endian: endian);
-  }
-
-  Reader refocus(int pos, [int size = -1]) {
-    if (size < 0) size = bdata.lengthInBytes - pos;
-    assert(pos >= 0 && pos < bdata.buffer.lengthInBytes);
-    assert(size >= 0 && (pos + size) <= bdata.buffer.lengthInBytes);
-    return Reader.fromTypedData(ByteData.view(bdata.buffer, pos, size),
-        wordSize: wordSize, endian: endian);
-  }
-
-  int get start => bdata.offsetInBytes;
-  int get offset => _offset;
-  int get length => bdata.lengthInBytes;
-  bool get done => _offset >= length;
-
-  void seek(int offset, {bool absolute = false}) {
-    final newOffset = (absolute ? 0 : _offset) + offset;
-    assert(newOffset >= 0 && newOffset < bdata.lengthInBytes);
-    _offset = newOffset;
-  }
-
-  void reset() {
-    seek(0, absolute: true);
-  }
-
-  int readBytes(int size, {bool signed = false}) {
-    assert(_offset + size < length);
-    int ret;
-    switch (size) {
-      case 1:
-        ret = signed ? bdata.getInt8(_offset) : bdata.getUint8(_offset);
-        break;
-      case 2:
-        ret = signed
-            ? bdata.getInt16(_offset, endian)
-            : bdata.getUint16(_offset, endian);
-        break;
-      case 4:
-        ret = signed
-            ? bdata.getInt32(_offset, endian)
-            : bdata.getUint32(_offset, endian);
-        break;
-      case 8:
-        ret = signed
-            ? bdata.getInt64(_offset, endian)
-            : bdata.getUint64(_offset, endian);
-        break;
-      default:
-        throw ArgumentError("invalid request to read $size bytes");
-    }
-    _offset += size;
-    return ret;
-  }
-
-  int readByte({bool signed = false}) => readBytes(1, signed: signed);
-  int readWord() => readBytes(wordSize);
-  String readNullTerminatedString() {
-    final start = bdata.offsetInBytes + _offset;
-    for (int i = 0; _offset + i < bdata.lengthInBytes; i++) {
-      if (bdata.getUint8(_offset + i) == 0) {
-        _offset += i + 1;
-        return String.fromCharCodes(bdata.buffer.asUint8List(start, i));
-      }
-    }
-    return String.fromCharCodes(
-        bdata.buffer.asUint8List(start, bdata.lengthInBytes - _offset));
-  }
-
-  int readLEB128EncodedInteger({bool signed = false}) {
-    var ret = 0;
-    var shift = 0;
-    for (var byte = readByte(); !done; byte = readByte()) {
-      ret |= (byte & 0x7f) << shift;
-      shift += 7;
-      if (byte & 0x80 == 0) {
-        if (signed && byte & 0x40 != 0) {
-          ret |= -(1 << shift);
-        }
-        break;
-      }
-    }
-    return ret;
-  }
-
-  String dumpCurrentReaderPosition({int maxSize = 0, int bytesPerLine = 16}) {
-    var baseData = ByteData.view(bdata.buffer, 0, bdata.buffer.lengthInBytes);
-    var startOffset = 0;
-    var endOffset = baseData.lengthInBytes;
-    final currentOffset = start + _offset;
-    if (maxSize != 0 && maxSize < baseData.lengthInBytes) {
-      var lowerWindow = currentOffset - (maxSize >> 1);
-      // Adjust so that we always start at the beginning of a line.
-      lowerWindow -= lowerWindow % bytesPerLine;
-      final upperWindow = lowerWindow + maxSize;
-      startOffset = max(startOffset, lowerWindow);
-      endOffset = min(endOffset, upperWindow);
-    }
-    var ret = "";
-    for (int i = startOffset; i < endOffset; i += bytesPerLine) {
-      ret += "0x" + paddedHex(i, 8) + " ";
-      for (int j = 0; j < bytesPerLine && i + j < endOffset; j++) {
-        var byte = baseData.getUint8(i + j);
-        ret += (i + j == currentOffset) ? "|" : " ";
-        ret += paddedHex(byte, 1);
-      }
-      ret += "\n";
-    }
-    return ret;
-  }
-
-  String toString() => dumpCurrentReaderPosition();
-}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index c20e175..c6b1aa0 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -32,7 +32,8 @@
         kernelForProgram,
         parseExperimentalArguments,
         parseExperimentalFlags,
-        printDiagnosticMessage;
+        printDiagnosticMessage,
+        resolveInputUri;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/ast.dart' show Component, Library, Reference;
@@ -46,7 +47,7 @@
 import 'bytecode/gen_bytecode.dart'
     show generateBytecode, createFreshComponentWithBytecode;
 import 'bytecode/options.dart' show BytecodeOptions;
-
+import 'http_filesystem.dart' show HttpAwareFileSystem;
 import 'target/install.dart' show installAdditionalTargets;
 import 'transformations/devirtualization.dart' as devirtualization
     show transformComponent;
@@ -197,9 +198,7 @@
   final fileSystem =
       createFrontEndFileSystem(fileSystemScheme, fileSystemRoots);
 
-  final Uri packagesUri = packages != null
-      ? convertFileOrUriArgumentToUri(fileSystem, packages)
-      : null;
+  final Uri packagesUri = packages != null ? resolveInputUri(packages) : null;
 
   final platformKernelUri = Uri.base.resolveUri(new Uri.file(platformKernel));
   final List<Uri> linkedDependencies = <Uri>[];
@@ -207,7 +206,7 @@
     linkedDependencies.add(platformKernelUri);
   }
 
-  Uri mainUri = convertFileOrUriArgumentToUri(fileSystem, input);
+  Uri mainUri = resolveInputUri(input);
   if (packagesUri != null) {
     mainUri = await convertToPackageUri(fileSystem, mainUri, packagesUri);
   }
@@ -556,16 +555,23 @@
 }
 
 /// Create a front-end file system.
-/// If requested, create a virtual mutli-root file system.
+///
+/// If requested, create a virtual mutli-root file system and/or an http aware
+/// file system.
 FileSystem createFrontEndFileSystem(
-    String multiRootFileSystemScheme, List<String> multiRootFileSystemRoots) {
+    String multiRootFileSystemScheme, List<String> multiRootFileSystemRoots,
+    {bool allowHttp}) {
+  allowHttp ??= false;
   FileSystem fileSystem = StandardFileSystem.instance;
+  if (allowHttp) {
+    fileSystem = HttpAwareFileSystem(fileSystem);
+  }
   if (multiRootFileSystemRoots != null &&
       multiRootFileSystemRoots.isNotEmpty &&
       multiRootFileSystemScheme != null) {
     final rootUris = <Uri>[];
     for (String root in multiRootFileSystemRoots) {
-      rootUris.add(Uri.base.resolveUri(new Uri.file(root)));
+      rootUris.add(resolveInputUri(root));
     }
     fileSystem = new MultiRootFileSystem(
         multiRootFileSystemScheme, rootUris, fileSystem);
@@ -573,32 +579,6 @@
   return fileSystem;
 }
 
-/// Convert command line argument [input] which is a file or URI to an
-/// absolute URI.
-///
-/// If virtual multi-root file system is used, or [input] can be parsed to a
-/// URI with 'package' or 'file' scheme, then [input] is interpreted as URI.
-/// Otherwise [input] is interpreted as a file path.
-Uri convertFileOrUriArgumentToUri(FileSystem fileSystem, String input) {
-  if (input == null) {
-    return null;
-  }
-  // If using virtual multi-root file system, input source argument should be
-  // specified as URI.
-  if (fileSystem is MultiRootFileSystem) {
-    return Uri.base.resolve(input);
-  }
-  try {
-    Uri uri = Uri.parse(input);
-    if (uri.scheme == 'package' || uri.scheme == 'file') {
-      return uri;
-    }
-  } on FormatException {
-    // Ignore, treat input argument as file path.
-  }
-  return Uri.base.resolveUri(new Uri.file(input));
-}
-
 /// Convert a URI which may use virtual file system schema to a real file URI.
 Future<Uri> asFileUri(FileSystem fileSystem, Uri uri) async {
   FileSystemEntity fse = fileSystem.entityForUri(uri);
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 5fe3681..ba1fe78 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -120,7 +120,7 @@
 /// Has an entry for all Abis. Empty entries document that every native
 /// type is aligned to it's own size in this ABI.
 ///
-/// See runtime/vm/compiler/ffi.cc for asserts in the VM that verify these
+/// See runtime/vm/ffi/abi.cc for asserts in the VM that verify these
 /// alignments.
 ///
 /// TODO(37470): Add uncommon primitive data types when we want to support them.
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 5dd9fe5..673264a 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -10,9 +10,9 @@
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/ast.dart' hide Statement, StatementVisitor;
 import 'package:kernel/ast.dart' as ast show Statement, StatementVisitor;
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart' show ClosedWorldClassHierarchy;
 import 'package:kernel/type_environment.dart'
-    show StaticTypeContext, TypeEnvironment;
+    show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;
 import 'package:kernel/type_algebra.dart' show Substitution;
 
 import 'calls.dart';
@@ -478,7 +478,7 @@
 class SummaryCollector extends RecursiveVisitor<TypeExpr> {
   final Target target;
   final TypeEnvironment _environment;
-  final ClassHierarchy _hierarchy;
+  final ClosedWorldClassHierarchy _hierarchy;
   final EntryPointsListener _entryPointsListener;
   final TypesBuilder _typesBuilder;
   final NativeCodeOracle _nativeCodeOracle;
@@ -905,20 +905,46 @@
   void _mergeVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
     assertx(dst.length == src.length);
     for (int i = 0; i < dst.length; ++i) {
-      if (!identical(dst[i], src[i])) {
-        if (dst[i] == null || src[i] == null) {
-          dst[i] = null;
-        } else if (dst[i] is EmptyType) {
-          dst[i] = src[i];
-        } else if (src[i] is! EmptyType) {
-          final Join join = _makeJoin(i, dst[i]);
-          join.values.add(src[i]);
-          dst[i] = join;
-        }
+      final TypeExpr dstValue = dst[i];
+      final TypeExpr srcValue = src[i];
+      if (identical(dstValue, srcValue)) {
+        continue;
+      }
+      if (dstValue == null || srcValue == null) {
+        dst[i] = null;
+      } else if (dstValue is EmptyType) {
+        dst[i] = srcValue;
+      } else if (dstValue is Join && dstValue.values.contains(srcValue)) {
+        continue;
+      } else if (srcValue is EmptyType) {
+        continue;
+      } else if (srcValue is Join && srcValue.values.contains(dstValue)) {
+        dst[i] = srcValue;
+      } else {
+        final Join join = _makeJoin(i, dst[i]);
+        join.values.add(src[i]);
+        dst[i] = join;
       }
     }
   }
 
+  void _copyVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
+    assertx(dst.length == src.length);
+    for (int i = 0; i < dst.length; ++i) {
+      dst[i] = src[i];
+    }
+  }
+
+  bool _isIdenticalState(List<TypeExpr> state1, List<TypeExpr> state2) {
+    assertx(state1.length == state2.length);
+    for (int i = 0; i < state1.length; ++i) {
+      if (!identical(state1[i], state2[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   List<Join> _insertJoinsForModifiedVariables(TreeNode node, bool isTry) {
     final List<Join> joins = new List<Join>(_variablesInfo.numVariables);
     for (var i in _variablesInfo.getModifiedVariables(node)) {
@@ -1000,12 +1026,20 @@
   }
 
   TypeExpr _makeNarrow(TypeExpr arg, Type type) {
-    if (arg is Type) {
-      // TODO(alexmarkov): more constant folding
+    if (arg is Narrow) {
+      if (arg.type == type) {
+        return arg;
+      }
+      if (type == const AnyType() && arg.type is! NullableType) {
+        return arg;
+      }
+    } else if (arg is Type) {
       if ((arg is NullableType) && (arg.baseType == const AnyType())) {
-        debugPrint("Optimized _Narrow of dynamic");
         return type;
       }
+      if (type == const AnyType()) {
+        return (arg is NullableType) ? arg.baseType : arg;
+      }
     }
     Narrow narrow = new Narrow(arg, type);
     _summary.add(narrow);
@@ -1126,6 +1160,136 @@
     _returnValue = savedReturn;
   }
 
+  // Tests subtypes ignoring any nullabilities.
+  bool _isSubtype(DartType subtype, DartType supertype) => _environment
+      .isSubtypeOf(subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
+
+  static final Name _equalsName = new Name('==');
+  final _cachedHasOverriddenEquals = <Class, bool>{};
+
+  bool _hasOverriddenEquals(DartType type) {
+    if (type is InterfaceType) {
+      final Class cls = type.classNode;
+      final cachedResult = _cachedHasOverriddenEquals[cls];
+      if (cachedResult != null) {
+        return cachedResult;
+      }
+      for (Class c
+          in _hierarchy.computeSubtypesInformation().getSubtypesOf(cls)) {
+        if (!c.isAbstract) {
+          final candidate = _hierarchy.getDispatchTarget(c, _equalsName);
+          assertx(candidate != null);
+          assertx(!candidate.isAbstract);
+          if (candidate != _environment.coreTypes.objectEquals) {
+            _cachedHasOverriddenEquals[cls] = true;
+            return true;
+          }
+        }
+      }
+      _cachedHasOverriddenEquals[cls] = false;
+      return false;
+    }
+    return true;
+  }
+
+  // Visits bool expression and updates trueState and falseState with
+  // variable values in case of `true` and `false` outcomes.
+  // On entry _variableValues, trueState and falseState should be the same.
+  // On exit _variableValues is null, so caller should explicitly pick
+  // either trueState or falseState.
+  void _visitCondition(
+      Expression node, List<TypeExpr> trueState, List<TypeExpr> falseState) {
+    assertx(_isIdenticalState(_variableValues, trueState));
+    assertx(_isIdenticalState(_variableValues, falseState));
+    if (node is Not) {
+      _visitCondition(node.operand, falseState, trueState);
+      _variableValues = null;
+      return;
+    } else if (node is LogicalExpression) {
+      assertx(node.operator == '||' || node.operator == '&&');
+      final isOR = (node.operator == '||');
+      _visitCondition(node.left, trueState, falseState);
+      if (isOR) {
+        // expr1 || expr2
+        _variableValues = _cloneVariableValues(falseState);
+        final trueStateAfterRHS = _cloneVariableValues(_variableValues);
+        _visitCondition(node.right, trueStateAfterRHS, falseState);
+        _mergeVariableValues(trueState, trueStateAfterRHS);
+      } else {
+        // expr1 && expr2
+        _variableValues = _cloneVariableValues(trueState);
+        final falseStateAfterRHS = _cloneVariableValues(_variableValues);
+        _visitCondition(node.right, trueState, falseStateAfterRHS);
+        _mergeVariableValues(falseState, falseStateAfterRHS);
+      }
+      _variableValues = null;
+      return;
+    } else if (node is VariableGet ||
+        (node is AsExpression && node.operand is VariableGet)) {
+      // 'x' or 'x as{TypeError} core::bool', where x is a variable.
+      _addUse(_visit(node));
+      final variableGet =
+          (node is AsExpression ? node.operand : node) as VariableGet;
+      final int varIndex = _variablesInfo.varIndex[variableGet.variable];
+      if (_variableCells[varIndex] == null) {
+        trueState[varIndex] = _boolTrue;
+        falseState[varIndex] = _boolFalse;
+      }
+      _variableValues = null;
+      return;
+    } else if (node is MethodInvocation &&
+        node.receiver is VariableGet &&
+        node.name.name == '==') {
+      assertx(node.arguments.positional.length == 1 &&
+          node.arguments.types.isEmpty &&
+          node.arguments.named.isEmpty);
+      final lhs = node.receiver as VariableGet;
+      final rhs = node.arguments.positional.single;
+      if (rhs is NullLiteral) {
+        // 'x == null', where x is a variable.
+        _addUse(_visit(node));
+        final int varIndex = _variablesInfo.varIndex[lhs.variable];
+        if (_variableCells[varIndex] == null) {
+          trueState[varIndex] = _nullType;
+          falseState[varIndex] = _makeNarrow(_visit(lhs), const AnyType());
+        }
+        _variableValues = null;
+        return;
+      } else if ((rhs is IntLiteral &&
+              _isSubtype(lhs.variable.type,
+                  _environment.coreTypes.intLegacyRawType)) ||
+          (rhs is StringLiteral &&
+              _isSubtype(lhs.variable.type,
+                  _environment.coreTypes.stringLegacyRawType)) ||
+          (rhs is ConstantExpression &&
+              !_hasOverriddenEquals(lhs.variable.type))) {
+        // 'x == c', where x is a variable and c is a constant.
+        _addUse(_visit(node));
+        final int varIndex = _variablesInfo.varIndex[lhs.variable];
+        if (_variableCells[varIndex] == null) {
+          trueState[varIndex] = _visit(rhs);
+        }
+        _variableValues = null;
+        return;
+      }
+    } else if (node is IsExpression && node.operand is VariableGet) {
+      // Handle 'x is T', where x is a variable.
+      final operand = node.operand as VariableGet;
+      _addUse(_visit(operand));
+      final int varIndex = _variablesInfo.varIndex[operand.variable];
+      if (_variableCells[varIndex] == null) {
+        trueState[varIndex] = _makeNarrow(
+            _visit(operand), _typesBuilder.fromStaticType(node.type, false));
+      }
+      _variableValues = null;
+      return;
+    }
+    _addUse(_visit(node));
+    _copyVariableValues(trueState, _variableValues);
+    _copyVariableValues(falseState, _variableValues);
+    _variableValues = null;
+  }
+
   @override
   defaultTreeNode(TreeNode node) =>
       throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
@@ -1155,14 +1319,20 @@
 
   @override
   TypeExpr visitConditionalExpression(ConditionalExpression node) {
-    _addUse(_visit(node.condition));
-    final stateBefore = _cloneVariableValues(_variableValues);
-    Join v = new Join(null, _staticDartType(node));
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
+    _visitCondition(node.condition, trueState, falseState);
+
+    final Join v = new Join(null, _staticDartType(node));
     _summary.add(v);
+
+    _variableValues = trueState;
     v.values.add(_visit(node.then));
     final stateAfter = _variableValues;
-    _variableValues = stateBefore;
+
+    _variableValues = falseState;
     v.values.add(_visit(node.otherwise));
+
     _mergeVariableValues(stateAfter, _variableValues);
     _variableValues = stateAfter;
     return _makeNarrow(v, _staticType(node));
@@ -1279,10 +1449,11 @@
 
   @override
   TypeExpr visitLogicalExpression(LogicalExpression node) {
-    _addUse(_visit(node.left));
-    final stateAfterShortCircuit = _cloneVariableValues(_variableValues);
-    _addUse(_visit(node.right));
-    _mergeVariableValues(_variableValues, stateAfterShortCircuit);
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
+    _visitCondition(node, trueState, falseState);
+    _variableValues = trueState;
+    _mergeVariableValues(_variableValues, falseState);
     return _boolType;
   }
 
@@ -1639,8 +1810,15 @@
   TypeExpr visitDoStatement(DoStatement node) {
     final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
     _visit(node.body);
-    _visit(node.condition);
-    _mergeVariableValuesToJoins(_variableValues, joins);
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
+    _visitCondition(node.condition, trueState, falseState);
+    _mergeVariableValuesToJoins(trueState, joins);
+    // Kernel represents 'break;' as a BreakStatement referring to a
+    // LabeledStatement. We are therefore guaranteed to always have the
+    // condition be false after the 'do/while'.
+    // Any break would jump to the LabeledStatement outside the do/while.
+    _variableValues = falseState;
     return null;
   }
 
@@ -1671,14 +1849,20 @@
   TypeExpr visitForStatement(ForStatement node) {
     node.variables.forEach(visitVariableDeclaration);
     final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
     if (node.condition != null) {
-      _addUse(_visit(node.condition));
+      _visitCondition(node.condition, trueState, falseState);
     }
-    final stateAfterLoop = _cloneVariableValues(_variableValues);
+    _variableValues = trueState;
     _visit(node.body);
     node.updates.forEach(_visit);
     _mergeVariableValuesToJoins(_variableValues, joins);
-    _variableValues = stateAfterLoop;
+    // Kernel represents 'break;' as a BreakStatement referring to a
+    // LabeledStatement. We are therefore guaranteed to always have the
+    // condition be false after the 'for'.
+    // Any break would jump to the LabeledStatement outside the 'for'.
+    _variableValues = falseState;
     return null;
   }
 
@@ -1692,15 +1876,19 @@
 
   @override
   TypeExpr visitIfStatement(IfStatement node) {
-    _addUse(_visit(node.condition));
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
+    _visitCondition(node.condition, trueState, falseState);
 
-    final stateBefore = _cloneVariableValues(_variableValues);
+    _variableValues = trueState;
     _visit(node.then);
     final stateAfter = _variableValues;
-    _variableValues = stateBefore;
+
+    _variableValues = falseState;
     if (node.otherwise != null) {
       _visit(node.otherwise);
     }
+
     _mergeVariableValues(stateAfter, _variableValues);
     _variableValues = stateAfter;
     return null;
@@ -1802,11 +1990,17 @@
   @override
   TypeExpr visitWhileStatement(WhileStatement node) {
     final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
-    _addUse(_visit(node.condition));
-    final stateAfterLoop = _cloneVariableValues(_variableValues);
+    final trueState = _cloneVariableValues(_variableValues);
+    final falseState = _cloneVariableValues(_variableValues);
+    _visitCondition(node.condition, trueState, falseState);
+    _variableValues = trueState;
     _visit(node.body);
     _mergeVariableValuesToJoins(_variableValues, joins);
-    _variableValues = stateAfterLoop;
+    // Kernel represents 'break;' as a BreakStatement referring to a
+    // LabeledStatement. We are therefore guaranteed to always have the
+    // condition be false after the 'while'.
+    // Any break would jump to the LabeledStatement outside the while.
+    _variableValues = falseState;
     return null;
   }
 
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 13fb81f..d7cc554 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -61,7 +61,7 @@
   final StringBuffer _buf = new StringBuffer();
 
   PrintSummaries(Target target, TypeEnvironment environment,
-      CoreTypes coreTypes, ClassHierarchy hierarchy) {
+      CoreTypes coreTypes, ClosedWorldClassHierarchy hierarchy) {
     final typesBuilder = new FakeTypesBuilder(coreTypes);
     _summaryCollector = new SummaryCollector(
         target,
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart
index 8ee3002..6b1a2e9 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart
@@ -10,8 +10,11 @@
 
 class C4 {}
 
+enum TestEnum { v1, v2 }
+
 foo(x) {}
 bar(x) {}
+baz(x) {}
 
 sequence() {
   dynamic x = C1();
@@ -67,6 +70,45 @@
   foo(x);
 }
 
+if6a(bool x) {
+  if (x) {
+    foo(x);
+  } else {
+    bar(x);
+  }
+  baz(x);
+}
+
+if6b(x) {
+  if (x) {
+    foo(x);
+  } else {
+    bar(x);
+  }
+  baz(x);
+}
+
+if7(int x, String y, dynamic z) {
+  if ((x == 5) && (y == 'hi') && (z != null)) {
+    foo(x);
+    foo(y);
+    foo(z);
+  }
+}
+
+if8(x) {
+  if (x is String) {
+    foo(x);
+    x = 42;
+  }
+}
+
+if9(TestEnum x) {
+  if (x == TestEnum.v1) {
+    foo(x);
+  }
+}
+
 conditional1(bool cond1, bool cond2) {
   dynamic x = C1();
   dynamic y = foo(x = C2()) ? (x = C3()) : (x = C4());
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
index 028f10f..88b429a 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect
@@ -14,12 +14,36 @@
 %this = _Parameter #0 [_T (#lib::C4)+]
 t1 = _Call direct [dart.core::Object::] (%this)
 RESULT: _T {}?
+------------ #lib::TestEnum:: ------------
+%this = _Parameter #0 [_T (#lib::TestEnum)+]
+%index = _Parameter #1 [_T (dart.core::int)+?]
+%_name = _Parameter #2 [_T (dart.core::String)+?]
+t3 = _Call direct set [#lib::TestEnum::index] (%this, %index)
+t4 = _Call direct set [#lib::TestEnum::_name] (%this, %_name)
+t5 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::TestEnum::toString ------------
+%this = _Parameter #0 [_T (#lib::TestEnum)+]
+t1* = _Call direct get [#lib::TestEnum::_name] (%this)
+RESULT: t1
+------------ #lib::TestEnum::values ------------
+
+RESULT: _T (dart.core::_ImmutableList, ListConstant<#lib::TestEnum*>([#lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }, #lib::TestEnum {index: 1, #lib::_name: TestEnum.v2, }]))
+------------ #lib::TestEnum::v1 ------------
+
+RESULT: _T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, })
+------------ #lib::TestEnum::v2 ------------
+
+RESULT: _T (#lib::TestEnum, #lib::TestEnum {index: 1, #lib::_name: TestEnum.v2, })
 ------------ #lib::foo ------------
 %x = _Parameter #0 [_T ANY?]
 RESULT: _T {}?
 ------------ #lib::bar ------------
 %x = _Parameter #0 [_T ANY?]
 RESULT: _T {}?
+------------ #lib::baz ------------
+%x = _Parameter #0 [_T ANY?]
+RESULT: _T {}?
 ------------ #lib::sequence ------------
 t0 = _Call direct [#lib::C1::] (_T (#lib::C1))
 t1 = _Call direct [#lib::C2::] (_T (#lib::C2))
@@ -51,7 +75,7 @@
 t6 = _Call direct [#lib::C3::] (_T (#lib::C3))
 t7* = _Call direct [#lib::foo] (_T (#lib::C3))
 t8 = _TypeCheck (t7 against dart.core::bool) (for #lib::foo(x = new #lib::C3::•()) as{TypeError} dart.core::bool*)
-x_0 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
 t10 = _Call direct [#lib::bar] (x_0)
 RESULT: x_0
 ------------ #lib::if4 ------------
@@ -62,8 +86,8 @@
 t4 = _Call direct [#lib::C3::] (_T (#lib::C3))
 t5* = _Call direct [#lib::foo] (_T (#lib::C3))
 t6 = _TypeCheck (t5 against dart.core::bool) (for #lib::foo(x = new #lib::C3::•()) as{TypeError} dart.core::bool*)
-x_0 = _Join [dynamic] (_T (#lib::C3), _T (#lib::C2))
-t8 = _Call direct [#lib::bar] (x_0)
+t7 = _Call direct [#lib::bar] (_T (#lib::C3))
+x_0 = _Join [dynamic] (_T (#lib::C2), _T (#lib::C3))
 RESULT: x_0
 ------------ #lib::if5 ------------
 %cond = _Parameter #0 [_T (dart.core::bool)+?]
@@ -71,6 +95,43 @@
 t2 = _Call direct [#lib::C2::] (_T (#lib::C2))
 t3 = _Call direct [#lib::foo] (_T (#lib::C1))
 RESULT: _T {}?
+------------ #lib::if6a ------------
+%x = _Parameter #0 [_T (dart.core::bool)+?]
+t1 = _Call direct [#lib::foo] (_T (dart.core::bool, true))
+t2 = _Call direct [#lib::bar] (_T (dart.core::bool, false))
+x_0 = _Join [dart.core::bool*] (_T (dart.core::bool, true), _T (dart.core::bool, false))
+t4 = _Call direct [#lib::baz] (x_0)
+RESULT: _T {}?
+------------ #lib::if6b ------------
+%x = _Parameter #0 [_T ANY?]
+t1 = _TypeCheck (%x against dart.core::bool) (for x as{TypeError} dart.core::bool*)
+t2 = _Call direct [#lib::foo] (_T (dart.core::bool, true))
+t3 = _Call direct [#lib::bar] (_T (dart.core::bool, false))
+x_0 = _Join [dynamic] (_T (dart.core::bool, true), _T (dart.core::bool, false))
+t5 = _Call direct [#lib::baz] (x_0)
+RESULT: _T {}?
+------------ #lib::if7 ------------
+%x = _Parameter #0 [_T (dart.core::int)+?]
+%y = _Parameter #1 [_T (dart.core::String)+?]
+%z = _Parameter #2 [_T ANY?]
+t3* = _Call [dart.core::num::==] (%x, _T (dart.core::_Smi, 5))
+t4* = _Call [dart.core::String::==] (%y, _T (dart.core::_OneByteString, hi))
+t5* = _Call [dart.core::Object::==] (%z, _T {}?)
+t6 = _Call direct [#lib::foo] (_T (dart.core::_Smi, 5))
+t7 = _Call direct [#lib::foo] (_T (dart.core::_OneByteString, hi))
+t8 = _Narrow (%z to _T ANY)
+t9 = _Call direct [#lib::foo] (t8)
+RESULT: _T {}?
+------------ #lib::if8 ------------
+%x = _Parameter #0 [_T ANY?]
+t1 = _Narrow (%x to _T (dart.core::String)+)
+t2 = _Call direct [#lib::foo] (t1)
+RESULT: _T {}?
+------------ #lib::if9 ------------
+%x = _Parameter #0 [_T (#lib::TestEnum)+?]
+t1* = _Call [dart.core::Object::==] (%x, _T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
+t2 = _Call direct [#lib::foo] (_T (#lib::TestEnum, #lib::TestEnum {index: 0, #lib::_name: TestEnum.v1, }))
+RESULT: _T {}?
 ------------ #lib::conditional1 ------------
 %cond1 = _Parameter #0 [_T (dart.core::bool)+?]
 %cond2 = _Parameter #1 [_T (dart.core::bool)+?]
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
index aaced22..ec16190 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
@@ -92,7 +92,7 @@
 RESULT: _T {}?
 ------------ #lib::if5 ------------
 %c = _Parameter #0 [_T (dart.core::bool)+?]
-t1* = _Call direct [#lib::if5] (%c)
+t1* = _Call direct [#lib::if5] (_T (dart.core::bool, true))
 t2* = _Call direct [#lib::if5] (_T (dart.core::bool))
 %result = _Join [void] (t1, t2, _T {}?)
 RESULT: %result
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index be610de..2ea68d9 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -55,6 +55,16 @@
     name = Platform::GetExecutableName();
     target_size = strlen(name);
   }
+  Namespace* namespc = Namespace::Create(Namespace::Default());
+  if (File::GetType(namespc, name, false) == File::kIsLink) {
+    // Resolve the link without creating Dart scope String.
+    name = File::LinkTarget(namespc, name, target, kTargetSize);
+    if (name == NULL) {
+      return strdup("");
+    }
+    target_size = strlen(name);
+  }
+  namespc->Release();
   const char* sep = File::PathSeparator();
   const intptr_t sep_length = strlen(sep);
 
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 13e67e5..cc39f08 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -44,7 +44,7 @@
 // int.
 DART_EXPORT int32_t SumPlus42(int32_t a, int32_t b) {
   std::cout << "SumPlus42(" << a << ", " << b << ")\n";
-  int32_t retval = 42 + a + b;
+  const int32_t retval = 42 + a + b;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -173,7 +173,7 @@
 DART_EXPORT int64_t IntComputation(int8_t a, int16_t b, int32_t c, int64_t d) {
   std::cout << "IntComputation(" << static_cast<int>(a) << ", " << b << ", "
             << c << ", " << d << ")\n";
-  int64_t retval = d - c + b - a;
+  const int64_t retval = d - c + b - a;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -194,7 +194,7 @@
                                     uint64_t d) {
   std::cout << "UintComputation(" << static_cast<int>(a) << ", " << b << ", "
             << c << ", " << d << ")\n";
-  uint64_t retval = d - c + b - a;
+  const uint64_t retval = d - c + b - a;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -203,7 +203,7 @@
 // Used for testing pointer sized parameter and return value.
 DART_EXPORT intptr_t Times3(intptr_t a) {
   std::cout << "Times3(" << a << ")\n";
-  intptr_t retval = a * 3;
+  const intptr_t retval = a * 3;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -214,7 +214,7 @@
 // double.
 DART_EXPORT double Times1_337Double(double a) {
   std::cout << "Times1_337Double(" << a << ")\n";
-  double retval = a * 1.337;
+  const double retval = a * 1.337;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -223,7 +223,7 @@
 // Used for testing float parameter and return value.
 DART_EXPORT float Times1_337Float(float a) {
   std::cout << "Times1_337Float(" << a << ")\n";
-  float retval = a * 1.337f;
+  const float retval = a * 1.337f;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -244,7 +244,7 @@
   std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d
             << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
             << ", " << j << ")\n";
-  intptr_t retval = a + b + c + d + e + f + g + h + i + j;
+  const intptr_t retval = a + b + c + d + e + f + g + h + i + j;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -266,7 +266,146 @@
             << static_cast<int>(c) << ", " << d << ", " << static_cast<int>(e)
             << ", " << f << ", " << static_cast<int>(g) << ", " << h << ", "
             << static_cast<int>(i) << ", " << j << ")\n";
-  int16_t retval = a + b + c + d + e + f + g + h + i + j;
+  const int16_t retval = a + b + c + d + e + f + g + h + i + j;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Used for testing floating point argument backfilling on Arm32 in hardfp.
+DART_EXPORT double SumFloatsAndDoubles(float a, double b, float c) {
+  std::cout << "SumFloatsAndDoubles(" << a << ", " << b << ", " << c << ")\n";
+  const double retval = a + b + c;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Very many small integers, tests alignment on stack.
+DART_EXPORT int16_t SumVeryManySmallInts(int8_t a01,
+                                         int16_t a02,
+                                         int8_t a03,
+                                         int16_t a04,
+                                         int8_t a05,
+                                         int16_t a06,
+                                         int8_t a07,
+                                         int16_t a08,
+                                         int8_t a09,
+                                         int16_t a10,
+                                         int8_t a11,
+                                         int16_t a12,
+                                         int8_t a13,
+                                         int16_t a14,
+                                         int8_t a15,
+                                         int16_t a16,
+                                         int8_t a17,
+                                         int16_t a18,
+                                         int8_t a19,
+                                         int16_t a20,
+                                         int8_t a21,
+                                         int16_t a22,
+                                         int8_t a23,
+                                         int16_t a24,
+                                         int8_t a25,
+                                         int16_t a26,
+                                         int8_t a27,
+                                         int16_t a28,
+                                         int8_t a29,
+                                         int16_t a30,
+                                         int8_t a31,
+                                         int16_t a32,
+                                         int8_t a33,
+                                         int16_t a34,
+                                         int8_t a35,
+                                         int16_t a36,
+                                         int8_t a37,
+                                         int16_t a38,
+                                         int8_t a39,
+                                         int16_t a40) {
+  std::cout << "SumVeryManySmallInts(" << static_cast<int>(a01) << ", " << a02
+            << ", " << static_cast<int>(a03) << ", " << a04 << ", "
+            << static_cast<int>(a05) << ", " << a06 << ", "
+            << static_cast<int>(a07) << ", " << a08 << ", "
+            << static_cast<int>(a09) << ", " << a10 << ", "
+            << static_cast<int>(a11) << ", " << a12 << ", "
+            << static_cast<int>(a13) << ", " << a14 << ", "
+            << static_cast<int>(a15) << ", " << a16 << ", "
+            << static_cast<int>(a17) << ", " << a18 << ", "
+            << static_cast<int>(a19) << ", " << a20 << ", "
+            << static_cast<int>(a21) << ", " << a22 << ", "
+            << static_cast<int>(a23) << ", " << a24 << ", "
+            << static_cast<int>(a25) << ", " << a26 << ", "
+            << static_cast<int>(a27) << ", " << a28 << ", "
+            << static_cast<int>(a29) << ", " << a30 << ", "
+            << static_cast<int>(a31) << ", " << a32 << ", "
+            << static_cast<int>(a33) << ", " << a34 << ", "
+            << static_cast<int>(a35) << ", " << a36 << ", "
+            << static_cast<int>(a37) << ", " << a38 << ", "
+            << static_cast<int>(a39) << ", " << a40 << ")\n";
+  const int16_t retval = a01 + a02 + a03 + a04 + a05 + a06 + a07 + a08 + a09 +
+                         a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 +
+                         a19 + a20 + a21 + a22 + a23 + a24 + a25 + a26 + a27 +
+                         a28 + a29 + a30 + a31 + a32 + a33 + a34 + a35 + a36 +
+                         a37 + a38 + a39 + a40;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Very many floating points, tests alignment on stack, and packing in
+// floating point registers in hardfp.
+DART_EXPORT double SumVeryManyFloatsDoubles(float a01,
+                                            double a02,
+                                            float a03,
+                                            double a04,
+                                            float a05,
+                                            double a06,
+                                            float a07,
+                                            double a08,
+                                            float a09,
+                                            double a10,
+                                            float a11,
+                                            double a12,
+                                            float a13,
+                                            double a14,
+                                            float a15,
+                                            double a16,
+                                            float a17,
+                                            double a18,
+                                            float a19,
+                                            double a20,
+                                            float a21,
+                                            double a22,
+                                            float a23,
+                                            double a24,
+                                            float a25,
+                                            double a26,
+                                            float a27,
+                                            double a28,
+                                            float a29,
+                                            double a30,
+                                            float a31,
+                                            double a32,
+                                            float a33,
+                                            double a34,
+                                            float a35,
+                                            double a36,
+                                            float a37,
+                                            double a38,
+                                            float a39,
+                                            double a40) {
+  std::cout << "SumVeryManyFloatsDoubles(" << a01 << ", " << a02 << ", " << a03
+            << ", " << a04 << ", " << a05 << ", " << a06 << ", " << a07 << ", "
+            << a08 << ", " << a09 << ", " << a10 << ", " << a11 << ", " << a12
+            << ", " << a13 << ", " << a14 << ", " << a15 << ", " << a16 << ", "
+            << a17 << ", " << a18 << ", " << a19 << ", " << a20 << ", " << a21
+            << ", " << a22 << ", " << a23 << ", " << a24 << ", " << a25 << ", "
+            << a26 << ", " << a27 << ", " << a28 << ", " << a29 << ", " << a30
+            << ", " << a31 << ", " << a32 << ", " << a33 << ", " << a34 << ", "
+            << a35 << ", " << a36 << ", " << a37 << ", " << a38 << ", " << a39
+            << ", " << a40 << ")\n";
+  const double retval = a01 + a02 + a03 + a04 + a05 + a06 + a07 + a08 + a09 +
+                        a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 +
+                        a19 + a20 + a21 + a22 + a23 + a24 + a25 + a26 + a27 +
+                        a28 + a29 + a30 + a31 + a32 + a33 + a34 + a35 + a36 +
+                        a37 + a38 + a39 + a40;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -288,7 +427,7 @@
   std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d
             << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
             << ", " << j << ", " << k << ")\n";
-  intptr_t retval = a + b + c + d + e + f + g + h + i + j + k;
+  const intptr_t retval = a + b + c + d + e + f + g + h + i + j + k;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -309,7 +448,7 @@
   std::cout << "SumManyDoubles(" << a << ", " << b << ", " << c << ", " << d
             << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
             << ", " << j << ")\n";
-  double retval = a + b + c + d + e + f + g + h + i + j;
+  const double retval = a + b + c + d + e + f + g + h + i + j;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -342,8 +481,8 @@
             << ", " << j << ", " << k << ", " << l << ", " << m << ", " << n
             << ", " << o << ", " << p << ", " << q << ", " << r << ", " << s
             << ", " << t << ")\n";
-  double retval = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o +
-                  p + q + r + s + t;
+  const double retval = a + b + c + d + e + f + g + h + i + j + k + l + m + n +
+                        o + p + q + r + s + t;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -581,7 +720,7 @@
 // Used for testing functions that do not take any arguments.
 DART_EXPORT float InventFloatValue() {
   std::cout << "InventFloatValue()\n";
-  float retval = 1337.0f;
+  const float retval = 1337.0f;
   std::cout << "returning " << retval << "\n";
   return retval;
 }
@@ -678,6 +817,111 @@
   return 0;
 }
 
+// Used for testing floating point argument backfilling on Arm32 in hardfp.
+DART_EXPORT intptr_t TestSumFloatsAndDoubles(double (*fn)(float,
+                                                          double,
+                                                          float)) {
+  CHECK_EQ(6.0, fn(1.0, 2.0, 3.0));
+  return 0;
+}
+
+// Very many small integers, tests alignment on stack.
+DART_EXPORT intptr_t TestSumVeryManySmallInts(int16_t (*fn)(int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t,
+                                                            int8_t,
+                                                            int16_t)) {
+  CHECK_EQ(40 * 41 / 2, fn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+                           16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+                           29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40));
+  return 0;
+}
+
+// Very many floating points, tests alignment on stack, and packing in
+// floating point registers in hardfp.
+DART_EXPORT intptr_t TestSumVeryManyFloatsDoubles(double (*fn)(float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double,
+                                                               float,
+                                                               double)) {
+  CHECK_EQ(40 * 41 / 2,
+           fn(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
+              13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0,
+              24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0,
+              35.0, 36.0, 37.0, 38.0, 39.0, 40.0));
+  return 0;
+}
+
 DART_EXPORT intptr_t TestStore(int64_t* (*fn)(int64_t* a)) {
   int64_t p[2] = {42, 1000};
   int64_t* result = fn(p);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 9268cc9..c0ab0fb 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -253,7 +253,12 @@
   static StdioHandleType GetStdioHandleType(int fd);
 
   // LinkTarget, GetCanonicalPath, and ReadLink may call Dart_ScopeAllocate.
-  static const char* LinkTarget(Namespace* namespc, const char* pathname);
+  // If dest and its size are provided, Dart String will not be created.
+  // The result will be populated into dest.
+  static const char* LinkTarget(Namespace* namespc,
+                                const char* pathname,
+                                char* dest = NULL,
+                                int dest_size = 0);
   static const char* GetCanonicalPath(Namespace* namespc, const char* path);
   // Link LinkTarget, but pathname must be absolute.
   static const char* ReadLink(const char* pathname);
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index a3bb558..59abc84 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -552,7 +552,10 @@
   return syscall(__NR_readlinkat, dirfd, pathname, buf, bufsize);
 }
 
-const char* File::LinkTarget(Namespace* namespc, const char* name) {
+const char* File::LinkTarget(Namespace* namespc,
+                             const char* name,
+                             char* dest,
+                             int dest_size) {
   NamespaceScope ns(namespc, name);
   struct stat link_stats;
   const int status = TEMP_FAILURE_RETRY(
@@ -574,11 +577,17 @@
   if (target_size <= 0) {
     return NULL;
   }
-  char* target_name = DartUtils::ScopedCString(target_size + 1);
-  ASSERT(target_name != NULL);
-  memmove(target_name, target, target_size);
-  target_name[target_size] = '\0';
-  return target_name;
+  if (dest == NULL) {
+    dest = DartUtils::ScopedCString(target_size + 1);
+  } else {
+    ASSERT(dest_size > 0);
+    if (dest_size <= target_size) {
+      return NULL;
+    }
+  }
+  memmove(dest, target, target_size);
+  dest[target_size] = '\0';
+  return dest;
 }
 
 bool File::IsAbsolutePath(const char* pathname) {
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index 182b4a9..98b6537 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -540,7 +540,10 @@
   return utimensat(ns.fd(), ns.path(), times, 0) == 0;
 }
 
-const char* File::LinkTarget(Namespace* namespc, const char* name) {
+const char* File::LinkTarget(Namespace* namespc,
+                             const char* name,
+                             char* dest,
+                             int dest_size) {
   NamespaceScope ns(namespc, name);
   struct stat link_stats;
   const int status = TEMP_FAILURE_RETRY(
@@ -562,11 +565,17 @@
   if (target_size <= 0) {
     return NULL;
   }
-  char* target_name = DartUtils::ScopedCString(target_size + 1);
-  ASSERT(target_name != NULL);
-  memmove(target_name, target, target_size);
-  target_name[target_size] = '\0';
-  return target_name;
+  if (dest == NULL) {
+    dest = DartUtils::ScopedCString(target_size + 1);
+  } else {
+    ASSERT(dest_size > 0);
+    if (dest_size <= target_size) {
+      return NULL;
+    }
+  }
+  memmove(dest, target, target_size);
+  dest[target_size] = '\0';
+  return dest;
 }
 
 bool File::IsAbsolutePath(const char* pathname) {
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index bf51aba..c012f8a 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -549,7 +549,10 @@
   return utimensat(ns.fd(), ns.path(), times, 0) == 0;
 }
 
-const char* File::LinkTarget(Namespace* namespc, const char* name) {
+const char* File::LinkTarget(Namespace* namespc,
+                             const char* name,
+                             char* dest,
+                             int dest_size) {
   NamespaceScope ns(namespc, name);
   struct stat64 link_stats;
   const int status = TEMP_FAILURE_RETRY(
@@ -571,11 +574,17 @@
   if (target_size <= 0) {
     return NULL;
   }
-  char* target_name = DartUtils::ScopedCString(target_size + 1);
-  ASSERT(target_name != NULL);
-  memmove(target_name, target, target_size);
-  target_name[target_size] = '\0';
-  return target_name;
+  if (dest == NULL) {
+    dest = DartUtils::ScopedCString(target_size + 1);
+  } else {
+    ASSERT(dest_size > 0);
+    if (dest_size <= target_size) {
+      return NULL;
+    }
+  }
+  memmove(dest, target, target_size);
+  dest[target_size] = '\0';
+  return dest;
 }
 
 bool File::IsAbsolutePath(const char* pathname) {
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 2e13282..456023c 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -518,7 +518,10 @@
   return utime(name, &times) == 0;
 }
 
-const char* File::LinkTarget(Namespace* namespc, const char* pathname) {
+const char* File::LinkTarget(Namespace* namespc,
+                             const char* pathname,
+                             char* dest,
+                             int dest_size) {
   struct stat link_stats;
   if (lstat(pathname, &link_stats) != 0) {
     return NULL;
@@ -536,11 +539,17 @@
   if (target_size <= 0) {
     return NULL;
   }
-  char* target_name = DartUtils::ScopedCString(target_size + 1);
-  ASSERT(target_name != NULL);
-  memmove(target_name, target, target_size);
-  target_name[target_size] = '\0';
-  return target_name;
+  if (dest == NULL) {
+    dest = DartUtils::ScopedCString(target_size + 1);
+  } else {
+    ASSERT(dest_size > 0);
+    if ((size_t)dest_size <= target_size) {
+      return NULL;
+    }
+  }
+  memmove(dest, target, target_size);
+  dest[target_size] = '\0';
+  return dest;
 }
 
 bool File::IsAbsolutePath(const char* pathname) {
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index f5c6010..975bd12 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -517,7 +517,10 @@
   return st.st_size;
 }
 
-const char* File::LinkTarget(Namespace* namespc, const char* pathname) {
+const char* File::LinkTarget(Namespace* namespc,
+                             const char* pathname,
+                             char* dest,
+                             int dest_size) {
   const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname);
   HANDLE dir_handle = CreateFileW(
       name, GENERIC_READ,
@@ -571,13 +574,18 @@
   }
   int utf8_length = WideCharToMultiByte(CP_UTF8, 0, target, target_length, NULL,
                                         0, NULL, NULL);
-  char* utf8_target = DartUtils::ScopedCString(utf8_length + 1);
-  if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, utf8_target,
+  if (dest_size > 0 && dest_size <= utf8_length) {
+    return NULL;
+  }
+  if (dest == NULL) {
+    dest = DartUtils::ScopedCString(utf8_length + 1);
+  }
+  if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, dest,
                                utf8_length, NULL, NULL)) {
     return NULL;
   }
-  utf8_target[utf8_length] = '\0';
-  return utf8_target;
+  dest[utf8_length] = '\0';
+  return dest;
 }
 
 void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index bac0ef1..353f709 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -21,7 +21,7 @@
 // Native implementations for the dart:developer library.
 DEFINE_NATIVE_ENTRY(Developer_debugger, 0, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, when, arguments->NativeArgAt(0));
-#if !defined(PRODUCT)
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   GET_NATIVE_ARGUMENT(String, msg, arguments->NativeArgAt(1));
   Debugger* debugger = isolate->debugger();
   if (debugger == nullptr) {
@@ -140,6 +140,7 @@
   SendNull(port);
   return Object::null();
 #else
+  ServiceIsolate::WaitForServiceIsolateStartup();
   if (!ServiceIsolate::IsRunning()) {
     SendNull(port);
   } else {
@@ -156,6 +157,7 @@
   return Object::null();
 #else
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, enabled, arguments->NativeArgAt(1));
+  ServiceIsolate::WaitForServiceIsolateStartup();
   if (!ServiceIsolate::IsRunning()) {
     SendNull(port);
   } else {
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 118fd5c..df3fb7f 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -8,7 +8,9 @@
 #include "vm/class_finalizer.h"
 #include "vm/class_id.h"
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/call.h"
+#include "vm/compiler/ffi/callback.h"
+#include "vm/compiler/ffi/native_representation.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart
index 1b5cada..6f7cfe5 100644
--- a/runtime/observatory/lib/object_graph.dart
+++ b/runtime/observatory/lib/object_graph.dart
@@ -500,7 +500,7 @@
   Iterable<SnapshotObject> get instances sync* {
     final N = _graph._N;
     for (var id = 1; id <= N; id++) {
-      if (_graph._cids[id] == _cid) {
+      if (_graph._cids[id] == _cid && _graph._retainedSizes[id] > 0) {
         yield _SnapshotObject._new(id, _graph, "");
       }
     }
@@ -569,7 +569,9 @@
   Iterable<SnapshotObject> get objects sync* {
     final N = _N;
     for (var id = 1; id <= N; id++) {
-      yield _SnapshotObject._new(id, this, "");
+      if (_retainedSizes[id] > 0) {
+        yield _SnapshotObject._new(id, this, "");
+      }
     }
   }
 
@@ -1302,10 +1304,14 @@
       cls.liveInstanceCount++;
     }
 
-    // Start with retained size as shallow size + external size.
-    final retainedSizes = _newUint32Array(N + 1);
-    for (var i = 0; i < N + 1; i++) {
-      retainedSizes[i] = internalSizes[i] + externalSizes[i];
+    // Start with retained size as shallow size + external size. For reachable
+    // objects only; leave unreachable objects with a retained size of 0 so
+    // they can be filtered during graph iterations.
+    var retainedSizes = new Uint32List(N + 1);
+    assert(Nconnected <= N);
+    for (var i = 0; i <= Nconnected; i++) {
+      var v = vertex[i];
+      retainedSizes[v] = internalSizes[v] + externalSizes[v];
     }
 
     // In post order (bottom up), add retained size to dominator's retained
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 73d5b90..eea85a8 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1905,6 +1905,16 @@
     });
   }
 
+  Future<ServiceObject> invoke(ServiceObject target, String selector,
+      [List<ServiceObject> arguments = const <ServiceObject>[]]) {
+    Map params = {
+      'targetId': target.id,
+      'selector': selector,
+      'argumentIds': arguments.map((arg) => arg.id).toList(),
+    };
+    return invokeRpc('invoke', params);
+  }
+
   Future<ServiceObject> eval(ServiceObject target, String expression,
       {Map<String, ServiceObject> scope, bool disableBreakpoints: false}) {
     Map params = {
diff --git a/runtime/observatory/tests/service/causal_async_stack_contents_test.dart b/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
index a45ad7c..10a3669 100644
--- a/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
+++ b/runtime/observatory/tests/service/causal_async_stack_contents_test.dart
@@ -38,12 +38,7 @@
   (Isolate isolate) async {
     ServiceMap stack = await isolate.getStack();
     // No causal frames because we are in a completely synchronous stack.
-    if (useCausalAsyncStacks) {
-      expect(stack['asyncCausalFrames'], isNull);
-    } else {
-      // TODO(dartbug.com/37668): Implement suport for this in the debugger.
-      expect(stack['asyncCausalFrames'], isNotNull);
-    }
+    expect(stack['asyncCausalFrames'], isNull);
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
index c7cacdf..02d92ff 100644
--- a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
+++ b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
@@ -36,12 +36,7 @@
   (Isolate isolate) async {
     ServiceMap stack = await isolate.getStack();
     // No causal frames because we are in a completely synchronous stack.
-    if (useCausalAsyncStacks) {
-      expect(stack['asyncCausalFrames'], isNull);
-    } else {
-      // TODO(dartbug.com/37668): Implement suport for this in the debugger.
-      expect(stack['asyncCausalFrames'], isNotNull);
-    }
+    expect(stack['asyncCausalFrames'], isNull);
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart b/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
index 6b07a76..feb529e 100644
--- a/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
+++ b/runtime/observatory/tests/service/causal_async_star_stack_contents_test.dart
@@ -52,6 +52,7 @@
     } else {
       expect(asyncStack.length, greaterThanOrEqualTo(1));
       expect(asyncStack[0].toString(), contains('helper'));
+      // helper isn't awaited.
     }
   },
   resumeIsolate,
@@ -62,17 +63,14 @@
     // Has causal frames (we are inside an async function)
     expect(stack['asyncCausalFrames'], isNotNull);
     var asyncStack = stack['asyncCausalFrames'];
+    expect(asyncStack.length, greaterThanOrEqualTo(3));
+    expect(asyncStack[0].toString(), contains('foobar'));
+    expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
+    expect(asyncStack[2].toString(), contains('helper'));
+    expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
     if (useCausalAsyncStacks) {
-      expect(asyncStack.length, greaterThanOrEqualTo(3));
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('helper'));
-      expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
+      // helper isn't awaited.
       expect(asyncStack[4].toString(), contains('testMain'));
-    } else {
-      // TODO(dartbug.com/37668): Implement suport for this in the debugger.
-      expect(asyncStack.length, greaterThanOrEqualTo(1));
-      expect(asyncStack[0].toString(), contains('foobar'));
     }
   },
   resumeIsolate,
@@ -87,22 +85,19 @@
     await printFrames(asyncStack);
     print('sync:');
     await printFrames(stack['frames']);
+    expect(asyncStack.length, greaterThanOrEqualTo(4));
+    expect(asyncStack[0].toString(), contains('foobar'));
+    expect(
+        await asyncStack[0].location.toUserString(), contains('.dart:$LINE_C'));
+    expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
+    expect(asyncStack[2].toString(), contains('helper'));
+    expect(await asyncStack[2].location.toUserString(), contains('.dart:30'));
+    expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
     if (useCausalAsyncStacks) {
+      // helper isn't awaited.
       expect(asyncStack.length, greaterThanOrEqualTo(5));
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
-      expect(asyncStack[2].toString(), contains('helper'));
-      expect(asyncStack[3].kind, equals(M.FrameKind.asyncSuspensionMarker));
       expect(asyncStack[4].toString(), contains('testMain'));
-      expect(await asyncStack[0].location.toUserString(),
-          contains('.dart:$LINE_C'));
-      expect(await asyncStack[2].location.toUserString(), contains('.dart:30'));
       expect(await asyncStack[4].location.toUserString(), contains('.dart:36'));
-    } else {
-      // TODO(dartbug.com/37668): Implement suport for this in the debugger.
-      expect(asyncStack.length, greaterThanOrEqualTo(2));
-      expect(asyncStack[0].toString(), contains('foobar'));
-      expect(asyncStack[1].kind, equals(M.FrameKind.asyncSuspensionMarker));
     }
   },
 ];
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index 9b787ec..ad1a386 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -11,53 +11,43 @@
 import 'service_test_common.dart';
 import 'test_helper.dart';
 
-Future<ServiceExtensionResponse> Handler(String method,
-                                         Map paremeters) {
+Future<ServiceExtensionResponse> Handler(String method, Map paremeters) {
   print('Invoked extension: $method');
   switch (method) {
     case 'ext..delay':
-      Completer c = new Completer();
+      Completer c = new Completer<ServiceExtensionResponse>();
       new Timer(new Duration(seconds: 1), () {
         c.complete(new ServiceExtensionResponse.result(jsonEncode({
-            'type': '_delayedType',
-            'method': method,
-            'parameters': paremeters,
-          })));
+          'type': '_delayedType',
+          'method': method,
+          'parameters': paremeters,
+        })));
       });
       return c.future;
     case 'ext..error':
-      return new Future.value(
-              new ServiceExtensionResponse.error(
-                  ServiceExtensionResponse.extensionErrorMin,
-                  'My error detail.'));
+      return new Future<ServiceExtensionResponse>.value(
+          new ServiceExtensionResponse.error(
+              ServiceExtensionResponse.extensionErrorMin, 'My error detail.'));
     case 'ext..exception':
       throw "I always throw!";
     case 'ext..success':
-      return new Future.value(
+      return new Future<ServiceExtensionResponse>.value(
           new ServiceExtensionResponse.result(jsonEncode({
-              'type': '_extensionType',
-              'method': method,
-              'parameters': paremeters,
-          })));
+        'type': '_extensionType',
+        'method': method,
+        'parameters': paremeters,
+      })));
     case 'ext..null':
       return null;
     case 'ext..nullFuture':
-      return new Future.value(null);
+      return new Future<ServiceExtensionResponse>.value(null);
   }
 }
 
-Future<ServiceExtensionResponse> LanguageErrorHandler(String method,
-                                                      Map paremeters) {
-  // The following is an intentional syntax error.
-  klajsdlkjfad
-}
-
 void test() {
   registerExtension('ext..delay', Handler);
   debugger();
-  postEvent('ALPHA', {
-    'cat': 'dog'
-  });
+  postEvent('ALPHA', {'cat': 'dog'});
   debugger();
   registerExtension('ext..error', Handler);
   registerExtension('ext..exception', Handler);
@@ -71,15 +61,20 @@
     exceptionThrown = true;
   }
   expect(exceptionThrown, isTrue);
-  registerExtension('ext..languageError', LanguageErrorHandler);
 }
 
 var tests = <IsolateTest>[
   hasStoppedAtBreakpoint,
   (Isolate isolate) async {
     await isolate.load();
-    expect(isolate.extensionRPCs.length, 1);
-    expect(isolate.extensionRPCs[0], equals('ext..delay'));
+    // Note: extensions other than those is this test might already be
+    // registered by core libraries.
+    expect(isolate.extensionRPCs, contains('ext..delay'));
+    expect(isolate.extensionRPCs, isNot(contains('ext..error')));
+    expect(isolate.extensionRPCs, isNot(contains('ext..exception')));
+    expect(isolate.extensionRPCs, isNot(contains('ext..null')));
+    expect(isolate.extensionRPCs, isNot(contains('ext..nullFuture')));
+    expect(isolate.extensionRPCs, isNot(contains('ext..success')));
   },
   resumeIsolateAndAwaitEvent(Isolate.kExtensionStream, (ServiceEvent event) {
     expect(event.kind, equals(ServiceEvent.kExtension));
@@ -127,27 +122,19 @@
       await isolate.invokeRpcNoUpgrade('ext..nullFuture', {});
     } on ServerRpcException catch (e, st) {
       expect(e.code, equals(ServiceExtensionResponse.extensionError));
-      expect(e.message, equals('Extension handler must complete to a '
-                               'ServiceExtensionResponse'));
+      expect(
+          e.message,
+          equals('Extension handler must complete to a '
+              'ServiceExtensionResponse'));
     }
 
-    result = await isolate.invokeRpcNoUpgrade('ext..success',
-                                              {'apple': 'banana'});
+    result =
+        await isolate.invokeRpcNoUpgrade('ext..success', {'apple': 'banana'});
     expect(result['type'], equals('_extensionType'));
     expect(result['method'], equals('ext..success'));
     expect(result['parameters']['isolateId'], isNotNull);
     expect(result['parameters']['apple'], equals('banana'));
-
-
-    try {
-      result = await isolate.invokeRpcNoUpgrade('ext..languageError', {});
-    } on ServerRpcException catch (e, st) {
-      expect(e.code, equals(ServiceExtensionResponse.extensionError));
-      expect(e.message, stringContainsInOrder([
-          'developer_extension_test.dart',
-          'semicolon expected']));
-    }
   },
 ];
 
-main(args) async => runIsolateTests(args, tests, testeeConcurrent:test);
+main(args) async => runIsolateTests(args, tests, testeeConcurrent: test);
diff --git a/runtime/observatory/tests/service/developer_service_get_isolate_id_test.dart b/runtime/observatory/tests/service/developer_service_get_isolate_id_test.dart
index 5d7f393..4400e47 100644
--- a/runtime/observatory/tests/service/developer_service_get_isolate_id_test.dart
+++ b/runtime/observatory/tests/service/developer_service_get_isolate_id_test.dart
@@ -31,6 +31,12 @@
   dev.debugger();
 }
 
+@pragma("vm:entry-point")
+getSelfId() => selfId;
+
+@pragma("vm:entry-point")
+getChildId() => childId;
+
 // tester state:
 Service.Isolate initialIsolate;
 Service.Isolate localChildIsolate;
@@ -65,7 +71,7 @@
 
     // Grab self id.
     Service.Instance localSelfId =
-        await initialIsolate.eval(rootLbirary, 'selfId');
+        await initialIsolate.invoke(rootLbirary, 'getSelfId');
 
     // Check that the id reported from dart:developer matches the id reported
     // from the service protocol.
@@ -74,7 +80,7 @@
 
     // Grab the child isolate's id.
     Service.Instance localChildId =
-        await initialIsolate.eval(rootLbirary, 'childId');
+        await initialIsolate.invoke(rootLbirary, 'getChildId');
 
     // Check that the id reported from dart:developer matches the id reported
     // from the service protocol.
diff --git a/runtime/observatory/tests/service/get_instances_rpc_test.dart b/runtime/observatory/tests/service/get_instances_rpc_test.dart
index 814405c..8479483 100644
--- a/runtime/observatory/tests/service/get_instances_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_instances_rpc_test.dart
@@ -19,17 +19,21 @@
   global = new _TestClass(new _TestClass(1, 2), null);
 }
 
-eval(Isolate isolate, String expression) async {
+@pragma("vm:entry-point")
+getGlobal() => global;
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var tests = <IsolateTest>[
   (Isolate isolate) async {
-    var obj = await eval(isolate, 'global');
+    var obj = await invoke(isolate, 'getGlobal');
     var params = {
       'objectId': obj['class']['id'],
       'limit': 4,
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index ce8af6b..a19a869 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -25,12 +25,31 @@
   new _DummyClass().dummyFunction();
 }
 
-eval(Isolate isolate, String expression) async {
+@pragma("vm:entry-point")
+getChattanooga() => "Chattanooga";
+
+@pragma("vm:entry-point")
+getList() => [3, 2, 1];
+
+@pragma("vm:entry-point")
+getMap() => {"x": 3, "y": 4, "z": 5};
+
+@pragma("vm:entry-point")
+getUint8List() => uint8List;
+
+@pragma("vm:entry-point")
+getUint64List() => uint64List;
+
+@pragma("vm:entry-point")
+getDummyClass() => new _DummyClass();
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var uint8List = new Uint8List.fromList([3, 2, 1]);
@@ -88,7 +107,7 @@
   // A string
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '"Chattanooga"');
+    var evalResult = await invoke(isolate, 'getChattanooga');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -110,7 +129,7 @@
   // String prefix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '"Chattanooga"');
+    var evalResult = await invoke(isolate, 'getChattanooga');
     var params = {
       'objectId': evalResult['id'],
       'count': 4,
@@ -133,7 +152,7 @@
   // String subrange.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '"Chattanooga"');
+    var evalResult = await invoke(isolate, 'getChattanooga');
     var params = {
       'objectId': evalResult['id'],
       'offset': 4,
@@ -157,7 +176,7 @@
   // String with wacky offset.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '"Chattanooga"');
+    var evalResult = await invoke(isolate, 'getChattanooga');
     var params = {
       'objectId': evalResult['id'],
       'offset': 100,
@@ -181,7 +200,7 @@
   // A built-in List.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var evalResult = await invoke(isolate, 'getList');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -213,7 +232,7 @@
   // List prefix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var evalResult = await invoke(isolate, 'getList');
     var params = {
       'objectId': evalResult['id'],
       'count': 2,
@@ -243,7 +262,7 @@
   // List suffix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var evalResult = await invoke(isolate, 'getList');
     var params = {
       'objectId': evalResult['id'],
       'offset': 2,
@@ -271,7 +290,7 @@
   // List with wacky offset.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, '[3, 2, 1]');
+    var evalResult = await invoke(isolate, 'getList');
     var params = {
       'objectId': evalResult['id'],
       'offset': 100,
@@ -296,7 +315,7 @@
   // A built-in Map.
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var evalResult = await invoke(isolate, 'getMap');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -337,7 +356,7 @@
   // Map prefix.
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var evalResult = await invoke(isolate, 'getMap');
     var params = {
       'objectId': evalResult['id'],
       'count': 2,
@@ -373,7 +392,7 @@
   // Map suffix.
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var evalResult = await invoke(isolate, 'getMap');
     var params = {
       'objectId': evalResult['id'],
       'offset': 2,
@@ -404,7 +423,7 @@
   // Map with wacky offset
   (Isolate isolate) async {
     // Call eval to get a Dart map.
-    var evalResult = await eval(isolate, '{"x": 3, "y": 4, "z": 5}');
+    var evalResult = await invoke(isolate, 'getMap');
     var params = {
       'objectId': evalResult['id'],
       'offset': 100,
@@ -429,7 +448,7 @@
   // Uint8List.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint8List');
+    var evalResult = await invoke(isolate, 'getUint8List');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -454,7 +473,7 @@
   // Uint8List prefix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint8List');
+    var evalResult = await invoke(isolate, 'getUint8List');
     var params = {
       'objectId': evalResult['id'],
       'count': 2,
@@ -480,7 +499,7 @@
   // Uint8List suffix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint8List');
+    var evalResult = await invoke(isolate, 'getUint8List');
     var params = {
       'objectId': evalResult['id'],
       'offset': 2,
@@ -507,7 +526,7 @@
   // Uint8List with wacky offset.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint8List');
+    var evalResult = await invoke(isolate, 'getUint8List');
     var params = {
       'objectId': evalResult['id'],
       'offset': 100,
@@ -532,7 +551,7 @@
   // Uint64List.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint64List');
+    var evalResult = await invoke(isolate, 'getUint64List');
     var params = {
       'objectId': evalResult['id'],
     };
@@ -557,7 +576,7 @@
   // Uint64List prefix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint64List');
+    var evalResult = await invoke(isolate, 'getUint64List');
     var params = {
       'objectId': evalResult['id'],
       'count': 2,
@@ -583,7 +602,7 @@
   // Uint64List suffix.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint64List');
+    var evalResult = await invoke(isolate, 'getUint64List');
     var params = {
       'objectId': evalResult['id'],
       'offset': 2,
@@ -610,7 +629,7 @@
   // Uint64List with wacky offset.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'uint64List');
+    var evalResult = await invoke(isolate, 'getUint64List');
     var params = {
       'objectId': evalResult['id'],
       'offset': 100,
@@ -733,7 +752,7 @@
   // class
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var params = {
       'objectId': evalResult['class']['id'],
     };
@@ -780,7 +799,7 @@
   // type.
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/types/0";
     var params = {
       'objectId': id,
@@ -799,7 +818,7 @@
 
   // invalid type.
   (Isolate isolate) async {
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/types/9999999";
     var params = {
       'objectId': id,
@@ -820,7 +839,7 @@
   // function.
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/functions/dummyFunction";
     var params = {
       'objectId': id,
@@ -844,7 +863,7 @@
   // invalid function.
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/functions/invalid";
     var params = {
       'objectId': id,
@@ -865,7 +884,7 @@
   // field
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/fields/dummyVar";
     var params = {
       'objectId': id,
@@ -899,7 +918,7 @@
     }
 
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/fields/dummyList";
     var params = {
       'objectId': id,
@@ -920,7 +939,7 @@
   // invalid field.
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var id = "${evalResult['class']['id']}/fields/mythicalField";
     var params = {
       'objectId': id,
@@ -941,7 +960,7 @@
   // code.
   (Isolate isolate) async {
     // Call eval to get a class id.
-    var evalResult = await eval(isolate, 'new _DummyClass()');
+    var evalResult = await invoke(isolate, 'getDummyClass');
     var funcId = "${evalResult['class']['id']}/functions/dummyFunction";
     var params = {
       'objectId': funcId,
diff --git a/runtime/observatory/tests/service/get_object_store_rpc_test.dart b/runtime/observatory/tests/service/get_object_store_rpc_test.dart
index a6b665b..a98b595 100644
--- a/runtime/observatory/tests/service/get_object_store_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_store_rpc_test.dart
@@ -7,27 +7,14 @@
 import 'package:unittest/unittest.dart';
 import 'service_test_common.dart';
 import 'test_helper.dart';
-import 'dart:developer' as developer;
 
-void doDebugger() {
-  developer.debugger(message: "foo", when: true);
-}
+void testeeMain() {}
 
 bool isClosureFunctionsList(NamedField field) {
   return field.name == 'closure_functions_';
 }
 
 var tests = <IsolateTest>[
-// Initial data fetch and verify we've hit the breakpoint.
-  (Isolate isolate) async {
-    await isolate.rootLibrary.load();
-    var script = isolate.rootLibrary.scripts[0];
-    await script.load();
-    await hasStoppedAtBreakpoint(isolate);
-    // Sanity check.
-    expect(isolate.pauseEvent is M.PauseBreakpointEvent, isTrue);
-  },
-
 // Get object_store.
   (Isolate isolate) async {
     var object_store = await isolate.getObjectStore();
@@ -42,5 +29,4 @@
   }
 ];
 
-main(args) =>
-    runIsolateTestsSynchronous(args, tests, testeeConcurrent: doDebugger);
+main(args) => runIsolateTestsSynchronous(args, tests, testeeBefore: testeeMain);
diff --git a/runtime/observatory/tests/service/get_retained_size_rpc_test.dart b/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
index 68e5e56..318c511 100644
--- a/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retained_size_rpc_test.dart
@@ -15,20 +15,25 @@
 
 var myVar;
 
-eval(Isolate isolate, String expression) async {
-  // Silence analyzer.
-  new _TestClass(null, null);
+@pragma("vm:entry-point")
+invoke1() => myVar = new _TestClass(null, null);
+
+@pragma("vm:entry-point")
+invoke2() => myVar = new _TestClass(new _TestClass(null, null), null);
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var tests = <IsolateTest>[
   (Isolate isolate) async {
     // One instance of _TestClass retained.
-    var evalResult = await eval(isolate, 'myVar = new _TestClass(null, null)');
+    var evalResult = await invoke(isolate, 'invoke1');
     var params = {
       'targetId': evalResult['id'],
     };
@@ -39,8 +44,7 @@
     expect(value1, isPositive);
 
     // Two instances of _TestClass retained.
-    evalResult = await eval(
-        isolate, 'myVar = new _TestClass(new _TestClass(null, null), null)');
+    evalResult = await invoke(isolate, 'invoke2');
     params = {
       'targetId': evalResult['id'],
     };
diff --git a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
index fcb20a7..e9f6e55 100644
--- a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
@@ -31,18 +31,60 @@
   globalMap2[target5] = 'value';
 }
 
-eval(Isolate isolate, String expression) async {
+@pragma("vm:entry-point")
+getGlobalObject() => globalObject;
+
+@pragma("vm:entry-point")
+takeTarget1() {
+  var tmp = target1;
+  target1 = null;
+  return tmp;
+}
+
+@pragma("vm:entry-point")
+takeTarget2() {
+  var tmp = target2;
+  target2 = null;
+  return tmp;
+}
+
+@pragma("vm:entry-point")
+takeTarget3() {
+  var tmp = target3;
+  target3 = null;
+  return tmp;
+}
+
+@pragma("vm:entry-point")
+takeTarget4() {
+  var tmp = target4;
+  target4 = null;
+  return tmp;
+}
+
+@pragma("vm:entry-point")
+takeTarget5() {
+  var tmp = target5;
+  target5 = null;
+  return tmp;
+}
+
+@pragma("vm:entry-point")
+getTrue() => true;
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var tests = <IsolateTest>[
   // simple path
   (Isolate isolate) async {
-    var obj = await eval(isolate, 'globalObject');
+    var obj = await invoke(isolate, 'getGlobalObject');
     var params = {
       'targetId': obj['id'],
       'limit': 100,
@@ -55,7 +97,7 @@
 
   // missing limit.
   (Isolate isolate) async {
-    var obj = await eval(isolate, 'globalObject');
+    var obj = await invoke(isolate, 'getGlobalObject');
     var params = {
       'targetId': obj['id'],
     };
@@ -73,8 +115,7 @@
   },
 
   (Isolate isolate) async {
-    var target1 = await eval(
-        isolate, '() { var tmp = target1; target1 = null; return tmp;} ()');
+    var target1 = await invoke(isolate, 'takeTarget1');
     var params = {
       'targetId': target1['id'],
       'limit': 100,
@@ -88,8 +129,7 @@
   },
 
   (Isolate isolate) async {
-    var target2 = await eval(
-        isolate, '() { var tmp = target2; target2 = null; return tmp;} ()');
+    var target2 = await invoke(isolate, 'takeTarget2');
     var params = {
       'targetId': target2['id'],
       'limit': 100,
@@ -103,8 +143,7 @@
   },
 
   (Isolate isolate) async {
-    var target3 = await eval(
-        isolate, '() { var tmp = target3; target3 = null; return tmp;} ()');
+    var target3 = await invoke(isolate, 'takeTarget3');
     var params = {
       'targetId': target3['id'],
       'limit': 100,
@@ -118,8 +157,7 @@
   },
 
   (Isolate isolate) async {
-    var target4 = await eval(
-        isolate, '() { var tmp = target4; target4 = null; return tmp;} ()');
+    var target4 = await invoke(isolate, 'takeTarget4');
     var params = {
       'targetId': target4['id'],
       'limit': 100,
@@ -134,8 +172,7 @@
   },
 
   (Isolate isolate) async {
-    var target5 = await eval(
-        isolate, '() { var tmp = target5; target5 = null; return tmp;} ()');
+    var target5 = await invoke(isolate, 'takeTarget5');
     var params = {
       'targetId': target5['id'],
       'limit': 100,
@@ -150,7 +187,7 @@
 
   // object store
   (Isolate isolate) async {
-    var obj = await eval(isolate, 'true');
+    var obj = await invoke(isolate, 'getTrue');
     var params = {
       'targetId': obj['id'],
       'limit': 100,
diff --git a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
index 698ab56..e65dddf 100644
--- a/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_user_level_retaining_path_rpc_test.dart
@@ -27,19 +27,26 @@
   fn = _TopLevelClosure;
 }
 
-eval(Isolate isolate, String expression) async {
+@pragma("vm:entry-point")
+getX() => x;
+
+@pragma("vm:entry-point")
+getFn() => fn;
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var tests = <IsolateTest>[
   // Expect a simple path through variable x instead of long path filled
   // with VM objects
   (Isolate isolate) async {
-    var target1 = await eval(isolate, 'x');
+    var target1 = await invoke(isolate, 'getX');
     var params = {
       'targetId': target1['id'],
       'limit': 100,
@@ -54,7 +61,7 @@
   // Expect a simple path through variable fn instead of long path filled
   // with VM objects
   (Isolate isolate) async {
-    var target2 = await eval(isolate, 'fn');
+    var target2 = await invoke(isolate, 'getFn');
     var params = {
       'targetId': target2['id'],
       'limit': 100,
diff --git a/runtime/observatory/tests/service/instance_field_order_rpc_test.dart b/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
index e5d55c3..c531ad6 100644
--- a/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
+++ b/runtime/observatory/tests/service/instance_field_order_rpc_test.dart
@@ -18,18 +18,22 @@
   var x = 4;
 }
 
-eval(Isolate isolate, String expression) async {
+@pragma("vm:entry-point")
+getSub() => new Sub();
+
+invoke(Isolate isolate, String selector) async {
   Map params = {
     'targetId': isolate.rootLibrary.id,
-    'expression': expression,
+    'selector': selector,
+    'argumentIds': <String>[],
   };
-  return await isolate.invokeRpcNoUpgrade('evaluate', params);
+  return await isolate.invokeRpcNoUpgrade('invoke', params);
 }
 
 var tests = <IsolateTest>[
   (Isolate isolate) async {
     // Call eval to get a Dart list.
-    var evalResult = await eval(isolate, 'new Sub()');
+    var evalResult = await invoke(isolate, 'getSub');
     var params = {
       'objectId': evalResult['id'],
     };
diff --git a/runtime/observatory/tests/service/kill_running_test.dart b/runtime/observatory/tests/service/kill_running_test.dart
index 49ea835..5fe16b7 100644
--- a/runtime/observatory/tests/service/kill_running_test.dart
+++ b/runtime/observatory/tests/service/kill_running_test.dart
@@ -14,8 +14,6 @@
 }
 
 var tests = <IsolateTest>[
-  // Stopped at 'debugger' statement.
-  isolateIsRunning,
   // Kill the app
   (Isolate isolate) async {
     Map<String, dynamic> params = <String, dynamic>{};
diff --git a/runtime/observatory/tests/service/object_graph_vm_test.dart b/runtime/observatory/tests/service/object_graph_vm_test.dart
index 76a5895..669d096 100644
--- a/runtime/observatory/tests/service/object_graph_vm_test.dart
+++ b/runtime/observatory/tests/service/object_graph_vm_test.dart
@@ -78,6 +78,69 @@
     // Check that the short list retains more than the long list inside.
     // and specifically, that it retains exactly itself + the long one.
     expect(first.retainedSize, equals(first.shallowSize + second.shallowSize));
+
+    // Verify sizes of classes are the appropriates sums of their instances.
+    // This also verifies that the class instance iterators are visiting the
+    // correct set of objects (e.g., not including dead objects).
+    for (SnapshotClass klass in graph.classes) {
+      int shallowSum = 0;
+      int internalSum = 0;
+      int externalSum = 0;
+      for (SnapshotObject instance in klass.instances) {
+        if (instance == graph.root) {
+          // The root may have 0 self size.
+          expect(instance.internalSize, greaterThanOrEqualTo(0));
+          expect(instance.externalSize, greaterThanOrEqualTo(0));
+          expect(instance.shallowSize, greaterThanOrEqualTo(0));
+        } else {
+          // All other objects are heap objects with positive size.
+          expect(instance.internalSize, greaterThan(0));
+          expect(instance.externalSize, greaterThanOrEqualTo(0));
+          expect(instance.shallowSize, greaterThan(0));
+        }
+        expect(instance.retainedSize, greaterThan(0));
+        expect(instance.shallowSize,
+            equals(instance.internalSize + instance.externalSize));
+        shallowSum += instance.shallowSize;
+        internalSum += instance.internalSize;
+        externalSum += instance.externalSize;
+      }
+      expect(shallowSum, equals(klass.shallowSize));
+      expect(internalSum, equals(klass.internalSize));
+      expect(externalSum, equals(klass.externalSize));
+      expect(
+          klass.shallowSize, equals(klass.internalSize + klass.externalSize));
+    }
+
+    // Verify sizes of the overall graph are the appropriates sums of all
+    // instances. This also verifies that the all instances iterator is visiting
+    // the correct set of objects (e.g., not including dead objects).
+    int shallowSum = 0;
+    int internalSum = 0;
+    int externalSum = 0;
+    for (SnapshotObject instance in graph.objects) {
+      if (instance == graph.root) {
+        // The root may have 0 self size.
+        expect(instance.internalSize, greaterThanOrEqualTo(0));
+        expect(instance.externalSize, greaterThanOrEqualTo(0));
+        expect(instance.shallowSize, greaterThanOrEqualTo(0));
+      } else {
+        // All other objects are heap objects with positive size.
+        expect(instance.internalSize, greaterThan(0));
+        expect(instance.externalSize, greaterThanOrEqualTo(0));
+        expect(instance.shallowSize, greaterThan(0));
+      }
+      expect(instance.retainedSize, greaterThan(0));
+      expect(instance.shallowSize,
+          equals(instance.internalSize + instance.externalSize));
+      shallowSum += instance.shallowSize;
+      internalSum += instance.internalSize;
+      externalSum += instance.externalSize;
+    }
+    expect(shallowSum, equals(graph.size));
+    expect(internalSum, equals(graph.internalSize));
+    expect(externalSum, equals(graph.externalSize));
+    expect(graph.size, equals(graph.internalSize + graph.externalSize));
   },
 ];
 
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index a8f8dd4..f7857bc 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -5,7 +5,6 @@
 field_script_test: Pass, RuntimeError
 get_allocation_samples_test: Pass, RuntimeError # Inconsistent stack trace
 get_isolate_rpc_test: Pass, RuntimeError # Issue 29324
-get_retained_size_rpc_test: Pass, RuntimeError # Issue 28193
 isolate_lifecycle_test: Pass, RuntimeError # Issue 24174
 pause_on_exceptions_test: Pass, RuntimeError # Issue 33049
 pause_on_start_and_exit_with_child_test: Pass, RuntimeError # Issue 33049
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 0037e6e..05b6843 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -3,13 +3,13 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == app_jitk ]
+add_breakpoint_rpc_kernel_test: SkipByDesign # No incremental compiler available.
 async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
 bad_reload_test: RuntimeError
 break_on_activation_test: SkipByDesign # No incremental compiler available.
 complex_reload_test: RuntimeError
 debugger_inspect_test: SkipByDesign # No incremental compiler available.
 debugger_location_second_test: RuntimeError
-developer_service_get_isolate_id_test: SkipByDesign # No incremental compiler available.
 eval_internal_class_test: SkipByDesign # No incremental compiler available.
 eval_regression_flutter20255_test: SkipByDesign # No incremental compiler available.
 eval_test: SkipByDesign # No incremental compiler available.
@@ -17,29 +17,167 @@
 evaluate_activation_test: SkipByDesign # No incremental compiler available.
 evaluate_async_closure_test: SkipByDesign # No incremental compiler available.
 evaluate_class_type_parameters_test: SkipByDesign # No incremental compiler available.
+evaluate_function_type_parameters_test: SkipByDesign # No incremental compiler available.
 evaluate_in_async_activation_test: SkipByDesign # No incremental compiler available.
 evaluate_in_async_star_activation_test: SkipByDesign # No incremental compiler available.
 evaluate_in_frame_rpc_test: SkipByDesign # No incremental compiler available.
 evaluate_in_frame_with_scope_test: SkipByDesign # No incremental compiler available.
 evaluate_in_sync_star_activation_test: SkipByDesign # No incremental compiler available.
+evaluate_with_escaping_closure_test: SkipByDesign # No incremental compiler available.
 evaluate_with_scope_test: SkipByDesign # No incremental compiler available.
-get_instances_rpc_test: SkipByDesign # No incremental compiler available.
-get_object_rpc_test: SkipByDesign # No incremental compiler available.
-get_retained_size_rpc_test: SkipByDesign # No incremental compiler available.
-get_retaining_path_rpc_test: SkipByDesign # No incremental compiler available.
-get_user_level_retaining_path_rpc_test: SkipByDesign # No incremental compiler available.
-instance_field_order_rpc_test: SkipByDesign # No incremental compiler available.
 pause_on_exceptions_test: SkipByDesign # No incremental compiler available.
-regress_34841_test: RuntimeError # http://dartbug.com/34841
 rewind_optimized_out_test: SkipByDesign # No incremental compiler available.
 rewind_test: SkipByDesign # No incremental compiler available.
-simple_reload_test: RuntimeError, Timeout # Issue 35506
 
 [ $compiler == dartkp ]
-*: SkipByDesign # Non-kernel also skips precompiled mode.
+add_breakpoint_rpc_kernel_test: RuntimeError
+async_generator_breakpoint_test: RuntimeError
+async_next_regession_18877_test: Skip, Timeout
+async_next_test: Skip, Timeout
+async_scope_test: Skip, Timeout
+async_single_step_exception_test: Skip, Timeout
+async_single_step_into_test: Skip, Timeout
+async_single_step_out_test: Skip, Timeout
+async_star_single_step_into_test: Skip, Timeout
+async_star_step_out_test: Skip, Timeout
+async_step_out_test: Skip, Timeout
+awaiter_async_stack_contents_2_test: Skip, Timeout
+awaiter_async_stack_contents_test: Skip, Timeout
+bad_reload_test: RuntimeError
+break_on_activation_test: RuntimeError
+break_on_async_function_test: Skip, Timeout
+break_on_default_constructor_test: RuntimeError
+break_on_function_test: Skip, Timeout
+breakpoint_async_break_test: RuntimeError
+breakpoint_in_package_parts_class_file_uri_test: RuntimeError
+breakpoint_in_package_parts_class_test: RuntimeError
+breakpoint_in_parts_class_test: RuntimeError
+breakpoint_non_debuggable_library_test: RuntimeError
+breakpoint_on_if_null_1_test: RuntimeError
+breakpoint_on_if_null_2_test: RuntimeError
+breakpoint_on_if_null_3_test: RuntimeError
+breakpoint_on_if_null_4_test: RuntimeError
+breakpoint_partfile_test: RuntimeError
+breakpoint_two_args_checked_test: Skip, Timeout
+capture_stdio_test: Skip, Timeout
+causal_async_stack_contents_test: Skip, Timeout
+causal_async_stack_presence_test: Skip, Timeout
+causal_async_star_stack_contents_test: Skip, Timeout
+causal_async_star_stack_presence_test: Skip, Timeout
+code_test: RuntimeError
+column_breakpoint_test: RuntimeError
+complex_reload_test: RuntimeError
+coverage_const_field_async_closure_test: Skip, Timeout
+coverage_leaf_function_test: Skip, Timeout
+coverage_optimized_function_test: Skip, Timeout
+debugger_inspect_test: RuntimeError
+debugger_location_second_test: Skip, Timeout
+debugger_location_test: Skip, Timeout
+debugging_inlined_finally_test: Skip, Timeout
+debugging_test: RuntimeError
+dev_fs_spawn_test: RuntimeError
+developer_extension_test: Skip, Timeout
+developer_service_get_isolate_id_test: Skip, Timeout
+eval_internal_class_test: RuntimeError
+eval_regression_flutter20255_test: Skip, Timeout
+eval_test: Skip, Timeout
+evaluate_activation_in_method_class_test: Skip, Timeout
+evaluate_activation_test: RuntimeError
+evaluate_async_closure_test: RuntimeError
+evaluate_class_type_parameters_test: Skip, Timeout
+evaluate_function_type_parameters_test: Skip, Timeout
+evaluate_in_async_activation_test: Skip, Timeout
+evaluate_in_async_star_activation_test: Skip, Timeout
+evaluate_in_frame_rpc_test: Skip, Timeout
+evaluate_in_frame_with_scope_test: Skip, Timeout
+evaluate_in_sync_star_activation_test: Skip, Timeout
+evaluate_with_escaping_closure_test: RuntimeError
+evaluate_with_scope_test: RuntimeError
+field_script_test: RuntimeError
+get_allocation_samples_test: Skip, Timeout
+get_isolate_after_language_error_test: CompileTimeError
+get_object_rpc_test: RuntimeError
+get_source_report_test: Skip, Timeout
+get_source_report_with_mixin_test: Skip, Timeout
+get_stack_rpc_test: Skip, Timeout
+implicit_getter_setter_test: RuntimeError
+invoke_test: Skip, Timeout
+isolate_lifecycle_test: RuntimeError
+issue_25465_test: RuntimeError
+issue_27238_test: Skip, Timeout
+issue_27287_test: Skip, Timeout
+issue_30555_test: RuntimeError
+kill_paused_test: Skip, Timeout
+library_dependency_test: CompileTimeError
+local_variable_declaration_test: Skip, Timeout
+logging_test: Skip, Timeout
+mirror_references_test: CompileTimeError
+mixin_break_test: Skip, Timeout
+network_profiling_test: Skip, Timeout
+next_through_assign_call_test: RuntimeError
+next_through_assign_int_test: RuntimeError
+next_through_await_for_test: RuntimeError
+next_through_call_on_field_in_class_test: RuntimeError
+next_through_call_on_field_test: RuntimeError
+next_through_call_on_static_field_in_class_test: RuntimeError
+next_through_catch_test: RuntimeError
+next_through_closure_test: RuntimeError
+next_through_create_list_and_map_test: RuntimeError
+next_through_for_each_loop_test: RuntimeError
+next_through_for_loop_with_break_and_continue_test: RuntimeError
+next_through_function_expression_test: RuntimeError
+next_through_implicit_call_test: RuntimeError
+next_through_is_and_as_test: RuntimeError
+next_through_multi_catch_test: RuntimeError
+next_through_new_test: RuntimeError
+next_through_operator_bracket_on_super_test: RuntimeError
+next_through_operator_bracket_on_this_test: RuntimeError
+next_through_operator_bracket_test: RuntimeError
+next_through_simple_async_test: RuntimeError
+next_through_simple_async_with_returns_test: RuntimeError
+next_through_simple_linear_2_test: RuntimeError
+next_through_simple_linear_test: RuntimeError
+parameters_in_scope_at_entry_test: Skip, Timeout
+pause_idle_isolate_test: Skip, Timeout
+pause_on_exceptions_test: RuntimeError
+pause_on_start_then_step_test: RuntimeError
+pause_on_unhandled_async_exceptions2_test: RuntimeError
+pause_on_unhandled_async_exceptions3_test: RuntimeError
+pause_on_unhandled_async_exceptions_test: RuntimeError
+pause_on_unhandled_exceptions_test: RuntimeError
+positive_token_pos_test: Skip, Timeout
+regress_28443_test: RuntimeError
+regress_28980_test: RuntimeError
+regress_34841_test: Skip, Timeout
+reload_sources_test: Skip, Timeout
+rewind_optimized_out_test: Skip, Timeout
+rewind_test: Skip, Timeout
+set_library_debuggable_test: Skip, Timeout
+simple_reload_test: RuntimeError
+steal_breakpoint_test: RuntimeError
+step_into_async_no_await_test: Skip, Timeout
+step_over_await_test: Skip, Timeout
+step_test: RuntimeError
+step_through_arithmetic_test: RuntimeError
+step_through_constructor_calls_test: RuntimeError
+step_through_constructor_test: RuntimeError
+step_through_for_each_sync_star_2_test: RuntimeError
+step_through_for_each_sync_star_test: RuntimeError
+step_through_function_2_test: RuntimeError
+step_through_function_test: RuntimeError
+step_through_getter_test: RuntimeError
+step_through_mixin_from_sdk_test: RuntimeError
+step_through_property_get_test: RuntimeError
+step_through_property_set_test: RuntimeError
+step_through_setter_test: RuntimeError
+step_through_switch_test: RuntimeError
+step_through_switch_with_continue_test: RuntimeError
+valid_source_locations_test: Skip, Timeout
+vm_timeline_flags_test: Skip, Timeout
+weak_properties_test: CompileTimeError
+yield_positions_with_finally_test: RuntimeError
 
 [ $fasta ]
-developer_extension_test: CompileTimeError
 get_isolate_after_language_error_test: CompileTimeError
 
 [ $arch == arm64 && $compiler == dartk ]
@@ -123,7 +261,6 @@
 breakpoint_in_package_parts_class_file_uri_test: RuntimeError # Issue #34736
 complex_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 debugger_inspect_test: RuntimeError, Timeout # Issue #34736
-developer_service_get_isolate_id_test: RuntimeError # Issue #34736
 eval_internal_class_test: RuntimeError # Issue #34736
 eval_regression_flutter20255_test: SkipByDesign # No incremental compiler available.
 eval_test: RuntimeError # Issue #34736
@@ -137,11 +274,6 @@
 evaluate_in_frame_with_scope_test: RuntimeError # Issue #34736
 evaluate_in_sync_star_activation_test: SkipByDesign # No incremental compiler available.
 evaluate_with_scope_test: RuntimeError # Issue #34736
-get_instances_rpc_test: RuntimeError # Issue #34736
-get_object_rpc_test: RuntimeError # Please triage.
-get_retaining_path_rpc_test: RuntimeError # Issue #34736
-get_user_level_retaining_path_rpc_test: RuntimeError # Issue #34736
-instance_field_order_rpc_test: RuntimeError # Issue #34736
 pause_on_exceptions_test: RuntimeError, Timeout # Issue #34736
 reload_sources_test: Skip # Times out.
 rewind_optimized_out_test: RuntimeError # Issue #34736
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 43a000f..3fa25e4 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -127,6 +127,12 @@
   }
 }
 
+Future listenAsyncStarThrowAsync() async {
+  // Listening to an async* doesn't create the usual await-for StreamIterator.
+  StreamSubscription ss = asyncStarThrowAsync().listen((Future f) {});
+  await ss.asFuture();
+}
+
 // Helpers:
 
 void assertStack(List<String> expects, StackTrace stackTrace) {
@@ -472,6 +478,50 @@
             r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
             r'^$',
           ]);
+
+  final listenAsyncStartExpected = const <String>[
+    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+    r'^<asynchronous suspension>$',
+    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:11)?\)$',
+    r'^<asynchronous suspension>$',
+    r'^#2      listenAsyncStarThrowAsync \(.+/utils.dart:132(:27)?\)$',
+  ];
+  await doTestAwait(
+      listenAsyncStarThrowAsync,
+      listenAsyncStartExpected +
+          const <String>[
+            r'^#3      doTestAwait \(.+\)$',
+            r'^#4      doTestsCausal \(.+\)$',
+            r'^<asynchronous suspension>$',
+            r'^#5      main \(.+\)$',
+            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
+            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
+            r'^$',
+          ]);
+  await doTestAwaitThen(
+      listenAsyncStarThrowAsync,
+      listenAsyncStartExpected +
+          const <String>[
+            r'^#3      doTestAwaitThen \(.+\)$',
+            r'^#4      doTestsCausal \(.+\)$',
+            r'^<asynchronous suspension>$',
+            r'^#5      main \(.+\)$',
+            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
+            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
+            r'^$',
+          ]);
+  await doTestAwaitCatchError(
+      listenAsyncStarThrowAsync,
+      listenAsyncStartExpected +
+          const <String>[
+            r'^#3      doTestAwaitCatchError \(.+\)$',
+            r'^#4      doTestsCausal \(.+\)$',
+            r'^<asynchronous suspension>$',
+            r'^#5      main \(.+\)$',
+            r'^#6      _startIsolate.<anonymous closure> \(.+\)$',
+            r'^#7      _RawReceivePortImpl._handleMessage \(.+\)$',
+            r'^$',
+          ]);
 }
 
 // For: --no-causal-async-stacks
@@ -745,6 +795,25 @@
       awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
   await doTestAwaitCatchError(
       awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+
+  final listenAsyncStartExpected = const <String>[
+    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+    r'^#1      _RootZone.runUnary ',
+    r'^#2      _FutureListener.handleValue ',
+    r'^#3      Future._propagateToListeners.handleValueCallback ',
+    r'^#4      Future._propagateToListeners ',
+    // TODO(dart-vm): Figure out why this is inconsistent:
+    r'^#5      Future.(_addListener|_prependListeners).<anonymous closure> ',
+    r'^#6      _microtaskLoop ',
+    r'^#7      _startMicrotaskLoop ',
+    r'^#8      _runPendingImmediateCallback ',
+    r'^#9      _RawReceivePortImpl._handleMessage ',
+    r'^$',
+  ];
+  await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwaitCatchError(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected);
 }
 
 // For: --lazy-async-stacks
@@ -947,27 +1016,82 @@
     r'^#0      throwSync \(.+/utils.dart:16(:3)?\)$',
     r'^#1      asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$',
     r'^<asynchronous suspension>$',
-    // Non-visible _onData frame.
+    r'^#2      awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$',
     r'^<asynchronous suspension>$',
-    r'^$',
   ];
-  await doTestAwait(awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
+  await doTestAwait(
+      awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected +
+          const <String>[
+            r'^#3      doTestAwait ',
+            r'^<asynchronous suspension>$',
+            r'^#4      doTestsLazy ',
+            r'^<asynchronous suspension>$',
+            r'^#5      main ',
+            r'^<asynchronous suspension>$',
+            r'^$',
+          ]);
   await doTestAwaitThen(
-      awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
+      awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected +
+          const <String>[
+            r'^#3      doTestAwaitThen.<anonymous closure> ',
+            r'^<asynchronous suspension>$',
+            r'^$',
+          ]);
   await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowSync, asyncStarThrowSyncExpected);
+      awaitEveryAsyncStarThrowSync,
+      asyncStarThrowSyncExpected +
+          const <String>[
+            r'^$',
+          ]);
 
   final asyncStarThrowAsyncExpected = const <String>[
     r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
     r'^<asynchronous suspension>$',
     r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
     r'^<asynchronous suspension>$',
-    // Non-visible _onData frame.
+    r'^#2      awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$',
     r'^<asynchronous suspension>$',
   ];
-  await doTestAwait(awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+  await doTestAwait(
+      awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected +
+          const <String>[
+            r'^#3      doTestAwait ',
+            r'^<asynchronous suspension>$',
+            r'^#4      doTestsLazy ',
+            r'^<asynchronous suspension>$',
+            r'^#5      main ',
+            r'^<asynchronous suspension>$',
+            r'^$',
+          ]);
   await doTestAwaitThen(
-      awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+      awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected +
+          const <String>[
+            r'^#3      doTestAwaitThen.<anonymous closure> ',
+            r'^<asynchronous suspension>$',
+            r'^$',
+          ]);
   await doTestAwaitCatchError(
-      awaitEveryAsyncStarThrowAsync, asyncStarThrowAsyncExpected);
+      awaitEveryAsyncStarThrowAsync,
+      asyncStarThrowAsyncExpected +
+          const <String>[
+            r'^$',
+          ]);
+
+  final listenAsyncStartExpected = const <String>[
+    r'^#0      throwAsync \(.*/utils.dart:21(:3)?\)$',
+    r'^<asynchronous suspension>$',
+    r'^#1      asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$',
+    r'^<asynchronous suspension>$',
+    r'^#2      listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$',
+    r'^<asynchronous suspension>$',
+    r'^$',
+  ];
+  await doTestAwait(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwaitThen(listenAsyncStarThrowAsync, listenAsyncStartExpected);
+  await doTestAwaitCatchError(
+      listenAsyncStarThrowAsync, listenAsyncStartExpected);
 }
diff --git a/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
index 26b7a9c..0515cd8 100644
--- a/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
+++ b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
@@ -36,8 +36,8 @@
     }
 
     {
-      final result =
-          await generateAotSnapshot(genSnapshot, dillPath, aotPath, false);
+      final result = await generateAotSnapshot(
+          genSnapshot, dillPath, aotPath, null, false);
       Expect.equals(result.stderr, '');
       Expect.equals(result.exitCode, 0);
       Expect.equals(result.stdout, '');
diff --git a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
index c1c8462..6b115e1 100644
--- a/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
+++ b/runtime/tests/vm/dart/use_dwarf_stack_traces_flag_test.dart
@@ -12,8 +12,8 @@
 import "dart:io";
 
 import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.dart';
 import 'package:path/path.dart' as path;
-import 'package:vm/dwarf/convert.dart';
 
 import 'use_flag_test_helper.dart';
 
diff --git a/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart b/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
index 965ff50..b46d695 100644
--- a/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
+++ b/runtime/tests/vm/dart/use_save_debugging_info_flag_test.dart
@@ -13,9 +13,8 @@
 import "dart:typed_data";
 
 import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.dart';
 import 'package:path/path.dart' as path;
-import 'package:vm/dwarf/convert.dart';
-import 'package:vm/dwarf/dwarf.dart';
 
 import 'use_flag_test_helper.dart';
 
@@ -104,17 +103,6 @@
     ]);
     final strippedOffsets = collectPCOffsets(strippedTrace);
 
-    if (Platform.isWindows) {
-      // TODO(dartbug.com/35274): After this point, we make sure that we get
-      // the same offsets from the DWARF stack traces. On Windows, we currently
-      // aren't guaranteed to get the same offset in DWARF stack traces from
-      // different runs because we aren't using the native loader for dynamic
-      // libraries (as the Windows one does not understand ELF). Instead, we
-      // fall back onto our own ELF loader, and the DWARF stack trace output
-      // only prints relative PC addresses for dynamically loaded libraries.
-      return;
-    }
-
     // The retrieved offsets should be the same for all runs.
     Expect.deepEquals(wholeOffsets, strippedOffsets);
     Expect.deepEquals(strippedOnlyOffsets, strippedOffsets);
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index ddce93a..7f713cd 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -11,7 +11,6 @@
 cc/IsolateReload_PendingStaticCall_NSMToDefined: Fail, Crash # Issue 32981. Fails on non-Windows, crashes on Windows (because of test.py special handline)
 cc/IsolateReload_PendingUnqualifiedCall_InstanceToStatic: Fail # Issue 32981
 cc/IsolateReload_PendingUnqualifiedCall_StaticToInstance: Fail # Issue 32981
-cc/Profiler_StringInterpolation: Fail # Issue 37208
 dart/data_uri_import_test/none: SkipByDesign
 dart/emit_aot_size_info_flag_test: Pass, Slow # Spawns several subprocesses
 dart/slow_path_shared_stub_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
diff --git a/runtime/tools/dartfuzz/collect_data.py b/runtime/tools/dartfuzz/collect_data.py
index 03ca8c1..1683a83 100755
--- a/runtime/tools/dartfuzz/collect_data.py
+++ b/runtime/tools/dartfuzz/collect_data.py
@@ -46,10 +46,10 @@
     resp = requests.get(uri)
     soup = BeautifulSoup(resp.text, "html.parser")
     for a in soup.findAll("a"):
-        if a.text == "raw":
+        if "stdout" in a.text:
             href = a["href"]
             if ("make_a_fuzz_shard" in href and "__trigger__" not in href):
-                links.append(href)
+                links.append(href + "?format=raw")
     return links
 
 
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 3807646..6770834 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -14,7 +14,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.85';
+const String version = '1.86';
 
 // Restriction on statements and expressions.
 const int stmtDepth = 1;
@@ -372,7 +372,7 @@
           DartLib('times1_337Float', [DartType.VOID, DartType.DOUBLE], true),
           DartLib(
               'sumManyDoubles',
-              [DartType.VOID, ...List<DartType>.filled(10, DartType.INT)],
+              [DartType.VOID, ...List<DartType>.filled(10, DartType.DOUBLE)],
               true),
           DartLib('times1_337Double', [DartType.VOID, DartType.DOUBLE], true),
           DartLib(
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index f0c8324..d0bcee0 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -189,6 +189,21 @@
   configs += [
     "..:dart_arch_config",
     "..:dart_config",
+    "..:dart_maybe_product_config",
+    ":libdart_vm_config",
+  ]
+  sources = [
+    "compiler/offsets_extractor.cc",
+  ]
+  include_dirs = [ ".." ]
+}
+
+executable("offsets_extractor_precompiled_runtime") {
+  configs += [
+    "..:dart_arch_config",
+    "..:dart_config",
+    "..:dart_precompiled_runtime_config",
+    "..:dart_maybe_product_config",
     ":libdart_vm_config",
   ]
   sources = [
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 2af21cc..19ea921 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -1561,6 +1561,12 @@
           initializer_function = field.InitializerFunction();
           initializer_function.ClearBytecode();
         }
+#if !defined(PRODUCT)
+        if (field.is_instance() && cls.is_allocated()) {
+          // Keep instance fields so their names are available to graph tools.
+          retain = true;
+        }
+#endif
         if (retain) {
           retained_fields.Add(field);
           type = field.type();
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 993e0f8..2e3ddcf 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -16,7 +16,8 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/loops.h"
 #include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/compiler/method_recognizer.h"
@@ -4088,8 +4089,9 @@
   // the top of stack from above the entry frame, we add a constant to account
   // for the the two frame pointers and two return addresses of the entry frame.
   constexpr intptr_t kEntryFramePadding = 4;
-  FrameRebase rebase(/*old_base=*/SPREG, /*new_base=*/FPREG,
-                     -kExitLinkSlotFromEntryFp + kEntryFramePadding);
+  compiler::ffi::FrameRebase rebase(
+      /*old_base=*/SPREG, /*new_base=*/FPREG,
+      -kExitLinkSlotFromEntryFp + kEntryFramePadding);
   const Location dst = locs()->out(0);
   const Location src = rebase.Rebase(loc_);
   NoTemporaryAllocator no_temp;
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 3d81bab..377874f 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -13,7 +13,6 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/slot.h"
 #include "vm/compiler/compiler_state.h"
-#include "vm/compiler/ffi.h"
 #include "vm/compiler/method_recognizer.h"
 #include "vm/flags.h"
 #include "vm/growable_array.h"
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 055963c..6c43554 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -13,6 +13,8 @@
 #include "vm/compiler/backend/locations_helpers.h"
 #include "vm/compiler/backend/range_analysis.h"
 #include "vm/compiler/compiler_state.h"
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
@@ -1123,8 +1125,8 @@
   __ ReserveAlignedFrameSpace(compiler::ffi::NumStackSlots(arg_locations_) *
                               compiler::target::kWordSize);
 
-  FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
-                     /*stack_delta=*/0);
+  compiler::ffi::FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
+                                    /*stack_delta=*/0);
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 7a56b46..405bc32 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -12,6 +12,8 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/locations_helpers.h"
 #include "vm/compiler/backend/range_analysis.h"
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/instructions.h"
@@ -988,8 +990,8 @@
   __ ReserveAlignedFrameSpace(compiler::ffi::NumStackSlots(arg_locations_) *
                               kWordSize);
 
-  FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
-                     /*stack_delta=*/0);
+  compiler::ffi::FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
+                                    /*stack_delta=*/0);
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 10f1149..c02b5e7 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -13,7 +13,8 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/locations_helpers.h"
 #include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
@@ -944,8 +945,8 @@
     __ andl(SPREG, compiler::Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
 
-  FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
-                     /*stack_delta=*/0);
+  compiler::ffi::FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
+                                    /*stack_delta=*/0);
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index dd48008..4b9cfcd 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -13,7 +13,8 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/backend/locations_helpers.h"
 #include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/instructions.h"
@@ -956,8 +957,8 @@
     __ andq(SPREG, compiler::Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
 
-  FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
-                     /*stack_delta=*/0);
+  compiler::ffi::FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
+                                    /*stack_delta=*/0);
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index e0731f4..c5c7174 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -62,8 +62,6 @@
 static constexpr Representation kUnboxedIntPtr =
     compiler::target::kWordSize == 4 ? kUnboxedInt32 : kUnboxedInt64;
 
-class FrameRebase;
-
 // Location objects are used to connect register allocator and code generator.
 // Instruction templates used by code generator have a corresponding
 // LocationSummary object which specifies expected location for every input
@@ -394,8 +392,6 @@
 
   uword payload() const { return PayloadField::decode(value_); }
 
-  friend class FrameRebase;
-
   class KindField : public BitField<uword, Kind, kKindBitsPos, kKindBitsSize> {
   };
   class PayloadField
@@ -804,36 +800,6 @@
 #endif
 };
 
-// Describes a change of stack frame where the stack or base register or stack
-// offset may change. This class allows easily rebasing stack locations across
-// frame manipulations.
-//
-// If the stack offset register matches 'old_base', it is changed to 'new_base'
-// and 'stack_delta' (# of slots) is applied.
-class FrameRebase : public ValueObject {
- public:
-  FrameRebase(Register old_base, Register new_base, intptr_t stack_delta)
-      : old_base_(old_base), new_base_(new_base), stack_delta_(stack_delta) {}
-
-  Location Rebase(Location loc) const {
-    if (loc.IsPairLocation()) {
-      return Location::Pair(Rebase(loc.Component(0)), Rebase(loc.Component(1)));
-    }
-    if (!loc.HasStackIndex() || loc.base_reg() != old_base_) {
-      return loc;
-    }
-
-    loc.set_base_reg(new_base_);
-    loc.set_stack_index(loc.stack_index() + stack_delta_);
-    return loc;
-  }
-
- private:
-  Register old_base_;
-  Register new_base_;
-  intptr_t stack_delta_;
-};
-
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_H_
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index 6f92238..961e877 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -95,8 +95,22 @@
   "compiler_pass.h",
   "compiler_state.cc",
   "compiler_state.h",
-  "ffi.cc",
-  "ffi.h",
+  "ffi/abi.cc",
+  "ffi/abi.h",
+  "ffi/frame_rebase.cc",
+  "ffi/frame_rebase.h",
+  "ffi/marshaller.cc",
+  "ffi/marshaller.h",
+  "ffi/call.cc",
+  "ffi/call.h",
+  "ffi/callback.cc",
+  "ffi/callback.h",
+  "ffi/native_calling_convention.cc",
+  "ffi/native_calling_convention.h",
+  "ffi/native_representation.cc",
+  "ffi/native_representation.h",
+  "ffi/recognized_method.cc",
+  "ffi/recognized_method.h",
   "frontend/base_flow_graph_builder.cc",
   "frontend/base_flow_graph_builder.h",
   "frontend/bytecode_fingerprints.cc",
diff --git a/runtime/vm/compiler/ffi.cc b/runtime/vm/compiler/ffi.cc
deleted file mode 100644
index 82e95df..0000000
--- a/runtime/vm/compiler/ffi.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-// 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.
-
-#include "vm/compiler/ffi.h"
-
-#include <algorithm>
-
-#include "platform/globals.h"
-#include "vm/compiler/backend/locations.h"
-#include "vm/compiler/method_recognizer.h"
-#include "vm/compiler/runtime_api.h"
-#include "vm/compiler/stub_code_compiler.h"
-#include "vm/growable_array.h"
-#include "vm/object_store.h"
-#include "vm/stack_frame.h"
-#include "vm/symbols.h"
-
-namespace dart {
-
-namespace compiler {
-
-namespace ffi {
-
-static const size_t kSizeUnknown = 0;
-
-static const intptr_t kNumElementSizes = kFfiVoidCid - kFfiPointerCid + 1;
-
-static const size_t element_size_table[kNumElementSizes] = {
-    target::kWordSize,  // kFfiPointerCid
-    kSizeUnknown,       // kFfiNativeFunctionCid
-    1,                  // kFfiInt8Cid
-    2,                  // kFfiInt16Cid
-    4,                  // kFfiInt32Cid
-    8,                  // kFfiInt64Cid
-    1,                  // kFfiUint8Cid
-    2,                  // kFfiUint16Cid
-    4,                  // kFfiUint32Cid
-    8,                  // kFfiUint64Cid
-    target::kWordSize,  // kFfiIntPtrCid
-    4,                  // kFfiFloatCid
-    8,                  // kFfiDoubleCid
-    kSizeUnknown,       // kFfiVoidCid
-};
-
-size_t ElementSizeInBytes(intptr_t class_id) {
-  ASSERT(class_id != kFfiNativeFunctionCid);
-  ASSERT(class_id != kFfiVoidCid);
-  if (!RawObject::IsFfiTypeClassId(class_id)) {
-    // subtype of Pointer
-    class_id = kFfiPointerCid;
-  }
-  intptr_t index = class_id - kFfiPointerCid;
-  return element_size_table[index];
-}
-
-classid_t ElementTypedDataCid(classid_t class_id) {
-  ASSERT(class_id >= kFfiPointerCid);
-  ASSERT(class_id < kFfiVoidCid);
-  ASSERT(class_id != kFfiNativeFunctionCid);
-  switch (class_id) {
-    case kFfiInt8Cid:
-      return kTypedDataInt8ArrayCid;
-    case kFfiUint8Cid:
-      return kTypedDataUint8ArrayCid;
-    case kFfiInt16Cid:
-      return kTypedDataInt16ArrayCid;
-    case kFfiUint16Cid:
-      return kTypedDataUint16ArrayCid;
-    case kFfiInt32Cid:
-      return kTypedDataInt32ArrayCid;
-    case kFfiUint32Cid:
-      return kTypedDataUint32ArrayCid;
-    case kFfiInt64Cid:
-      return kTypedDataInt64ArrayCid;
-    case kFfiUint64Cid:
-      return kTypedDataUint64ArrayCid;
-    case kFfiIntPtrCid:
-      return target::kWordSize == 4 ? kTypedDataInt32ArrayCid
-                                    : kTypedDataInt64ArrayCid;
-    case kFfiPointerCid:
-      return target::kWordSize == 4 ? kTypedDataUint32ArrayCid
-                                    : kTypedDataUint64ArrayCid;
-    case kFfiFloatCid:
-      return kTypedDataFloat32ArrayCid;
-    case kFfiDoubleCid:
-      return kTypedDataFloat64ArrayCid;
-    default:
-      UNREACHABLE();
-  }
-}
-
-classid_t RecognizedMethodTypeArgCid(MethodRecognizer::Kind kind) {
-  switch (kind) {
-#define LOAD_STORE(type)                                                       \
-  case MethodRecognizer::kFfiLoad##type:                                       \
-  case MethodRecognizer::kFfiStore##type:                                      \
-    return kFfi##type##Cid;
-    CLASS_LIST_FFI_NUMERIC(LOAD_STORE)
-    LOAD_STORE(Pointer)
-#undef LOAD_STORE
-    default:
-      UNREACHABLE();
-  }
-}
-
-// See pkg/vm/lib/transformations/ffi.dart, which makes these assumptions.
-struct AbiAlignmentDouble {
-  int8_t use_one_byte;
-  double d;
-};
-struct AbiAlignmentUint64 {
-  int8_t use_one_byte;
-  uint64_t i;
-};
-
-#if defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64)
-static_assert(offsetof(AbiAlignmentDouble, d) == 8,
-              "FFI transformation alignment");
-static_assert(offsetof(AbiAlignmentUint64, i) == 8,
-              "FFI transformation alignment");
-#elif (defined(HOST_ARCH_IA32) && /* NOLINT(whitespace/parens) */              \
-       (defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                    \
-        defined(HOST_OS_ANDROID))) ||                                          \
-    (defined(HOST_ARCH_ARM) && defined(HOST_OS_IOS))
-static_assert(offsetof(AbiAlignmentDouble, d) == 4,
-              "FFI transformation alignment");
-static_assert(offsetof(AbiAlignmentUint64, i) == 4,
-              "FFI transformation alignment");
-#elif defined(HOST_ARCH_IA32) && defined(HOST_OS_WINDOWS) ||                   \
-    defined(HOST_ARCH_ARM)
-static_assert(offsetof(AbiAlignmentDouble, d) == 8,
-              "FFI transformation alignment");
-static_assert(offsetof(AbiAlignmentUint64, i) == 8,
-              "FFI transformation alignment");
-#else
-#error "Unknown platform. Please add alignment requirements for ABI."
-#endif
-
-Abi TargetAbi() {
-#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
-  return Abi::kWordSize64;
-#elif (defined(TARGET_ARCH_IA32) && /* NOLINT(whitespace/parens) */            \
-       (defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) ||                \
-        defined(TARGET_OS_ANDROID))) ||                                        \
-    (defined(TARGET_ARCH_ARM) && defined(TARGET_OS_IOS))
-  return Abi::kWordSize32Align32;
-#elif defined(TARGET_ARCH_IA32) && defined(TARGET_OS_WINDOWS) ||               \
-    defined(TARGET_ARCH_ARM)
-  return Abi::kWordSize32Align64;
-#else
-#error "Unknown platform. Please add alignment requirements for ABI."
-#endif
-}
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-
-Representation TypeRepresentation(classid_t class_id) {
-  switch (class_id) {
-    case kFfiFloatCid:
-      return kUnboxedFloat;
-    case kFfiDoubleCid:
-      return kUnboxedDouble;
-    case kFfiInt8Cid:
-    case kFfiInt16Cid:
-    case kFfiInt32Cid:
-      return kUnboxedInt32;
-    case kFfiUint8Cid:
-    case kFfiUint16Cid:
-    case kFfiUint32Cid:
-      return kUnboxedUint32;
-    case kFfiInt64Cid:
-    case kFfiUint64Cid:
-      return kUnboxedInt64;
-    case kFfiIntPtrCid:
-      return kUnboxedIntPtr;
-    case kFfiPointerCid:
-    case kFfiVoidCid:
-      return kUnboxedFfiIntPtr;
-    default:
-      UNREACHABLE();
-  }
-}
-
-SmallRepresentation TypeSmallRepresentation(const AbstractType& ffi_type) {
-  switch (ffi_type.type_class_id()) {
-    case kFfiInt8Cid:
-      return kSmallUnboxedInt8;
-    case kFfiInt16Cid:
-      return kSmallUnboxedInt16;
-    case kFfiUint8Cid:
-      return kSmallUnboxedUint8;
-    case kFfiUint16Cid:
-      return kSmallUnboxedUint16;
-    default:
-      return kNoSmallRepresentation;
-  }
-}
-
-bool NativeTypeIsVoid(const AbstractType& result_type) {
-  return result_type.type_class_id() == kFfiVoidCid;
-}
-
-bool NativeTypeIsPointer(const AbstractType& result_type) {
-  return result_type.type_class_id() == kFfiPointerCid;
-}
-
-// Converts a Ffi [signature] to a list of Representations.
-// Note that this ignores first argument (receiver) which is dynamic.
-ZoneGrowableArray<Representation>* ArgumentRepresentations(
-    const Function& signature) {
-  intptr_t num_arguments = signature.num_fixed_parameters() - 1;
-  auto result = new ZoneGrowableArray<Representation>(num_arguments);
-  for (intptr_t i = 0; i < num_arguments; i++) {
-    AbstractType& arg_type =
-        AbstractType::Handle(signature.ParameterTypeAt(i + 1));
-    Representation rep = TypeRepresentation(arg_type.type_class_id());
-    // In non simulator mode host::CallingConventions == CallingConventions.
-    // In simulator mode convert arguments to host representation.
-    if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
-      rep = kUnboxedInt32;
-    } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
-      rep = kUnboxedInt64;
-    }
-    result->Add(rep);
-  }
-  return result;
-}
-
-Representation ResultRepresentation(const Function& signature) {
-  AbstractType& arg_type = AbstractType::Handle(signature.result_type());
-  Representation rep = TypeRepresentation(arg_type.type_class_id());
-  if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
-    rep = kUnboxedInt32;
-  } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
-    rep = kUnboxedInt64;
-  }
-  return rep;
-}
-
-RawFunction* NativeCallbackFunction(const Function& c_signature,
-                                    const Function& dart_target,
-                                    const Instance& exceptional_return) {
-  Thread* const thread = Thread::Current();
-  const int32_t callback_id = thread->AllocateFfiCallbackId();
-
-  // Create a new Function named '<target>_FfiCallback' and stick it in the
-  // 'dart:ffi' library. Note that these functions will never be invoked by
-  // Dart, so they have may have duplicate names.
-  Zone* const zone = thread->zone();
-  const auto& name = String::Handle(
-      zone, Symbols::FromConcat(thread, Symbols::FfiCallback(),
-                                String::Handle(zone, dart_target.name())));
-  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
-  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
-  const Function& function =
-      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
-                                           /*is_static=*/true,
-                                           /*is_const=*/false,
-                                           /*is_abstract=*/false,
-                                           /*is_external=*/false,
-                                           /*is_native=*/false, owner_class,
-                                           TokenPosition::kNoSource));
-  function.set_is_debuggable(false);
-
-  // Set callback-specific fields which the flow-graph builder needs to generate
-  // the body.
-  function.SetFfiCSignature(c_signature);
-  function.SetFfiCallbackId(callback_id);
-  function.SetFfiCallbackTarget(dart_target);
-
-  // We need to load the exceptional return value as a constant in the generated
-  // function. Even though the FE ensures that it is a constant, it could still
-  // be a literal allocated in new space. We need to copy it into old space in
-  // that case.
-  //
-  // Exceptional return values currently cannot be pointers because we don't
-  // have constant pointers.
-  //
-  // TODO(36730): We'll need to extend this when we support passing/returning
-  // structs by value.
-  ASSERT(exceptional_return.IsNull() || exceptional_return.IsNumber());
-  if (!exceptional_return.IsSmi() && exceptional_return.IsNew()) {
-    function.SetFfiCallbackExceptionalReturn(Instance::Handle(
-        zone, exceptional_return.CopyShallowToOldSpace(thread)));
-  } else {
-    function.SetFfiCallbackExceptionalReturn(exceptional_return);
-  }
-
-  return function.raw();
-}
-
-// Represents the state of a stack frame going into a call, between allocations
-// of argument locations. Acts like a register allocator but for arguments in
-// the native ABI.
-class ArgumentAllocator : public ValueObject {
- public:
-  Location AllocateArgument(Representation rep) {
-    switch (rep) {
-      case kUnboxedFloat:
-      case kUnboxedDouble: {
-        Location result = AllocateFpuRegister();
-        if (!result.IsUnallocated()) return result;
-        break;
-      }
-      case kUnboxedInt64:
-      case kUnboxedUint32:
-      case kUnboxedInt32: {
-        Location result = rep == kUnboxedInt64 && target::kWordSize == 4
-                              ? AllocateAlignedRegisterPair()
-                              : AllocateCpuRegister();
-        if (!result.IsUnallocated()) return result;
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-
-    // Argument must be spilled.
-    if (rep == kUnboxedInt64 && target::kWordSize == 4) {
-      return AllocateAlignedStackSlots(rep);
-    } else if (rep == kUnboxedDouble) {
-      // By convention, we always use DoubleStackSlot for doubles, even on
-      // 64-bit systems.
-      ASSERT(!CallingConventions::kAlignArguments);
-      return AllocateDoubleStackSlot();
-    } else {
-      return AllocateStackSlot();
-    }
-  }
-
- private:
-  Location AllocateStackSlot() {
-    return Location::StackSlot(stack_height_in_slots++,
-                               CallingConventions::kStackPointerRegister);
-  }
-
-  Location AllocateDoubleStackSlot() {
-    const Location result = Location::DoubleStackSlot(
-        stack_height_in_slots, CallingConventions::kStackPointerRegister);
-    stack_height_in_slots += 8 / target::kWordSize;
-    return result;
-  }
-
-  // Allocates a pair of stack slots where the first stack slot is aligned to an
-  // 8-byte boundary, if necessary.
-  Location AllocateAlignedStackSlots(Representation rep) {
-    if (CallingConventions::kAlignArguments && target::kWordSize == 4) {
-      stack_height_in_slots += stack_height_in_slots % 2;
-    }
-
-    Location result;
-    if (rep == kUnboxedDouble) {
-      result = Location::DoubleStackSlot(
-          stack_height_in_slots, CallingConventions::kStackPointerRegister);
-      stack_height_in_slots += 2;
-    } else {
-      const Location low = AllocateStackSlot();
-      const Location high = AllocateStackSlot();
-      result = Location::Pair(low, high);
-    }
-    return result;
-  }
-
-  Location AllocateFpuRegister() {
-    if (fpu_regs_used == CallingConventions::kNumFpuArgRegs) {
-      return Location::RequiresFpuRegister();
-    }
-
-    const Location result = Location::FpuRegisterLocation(
-        CallingConventions::FpuArgumentRegisters[fpu_regs_used]);
-    fpu_regs_used++;
-    if (CallingConventions::kArgumentIntRegXorFpuReg) {
-      cpu_regs_used++;
-    }
-    return result;
-  }
-
-  Location AllocateCpuRegister() {
-    if (cpu_regs_used == CallingConventions::kNumArgRegs) {
-      return Location::RequiresRegister();
-    }
-
-    const Location result = Location::RegisterLocation(
-        CallingConventions::ArgumentRegisters[cpu_regs_used]);
-    cpu_regs_used++;
-    if (CallingConventions::kArgumentIntRegXorFpuReg) {
-      fpu_regs_used++;
-    }
-    return result;
-  }
-
-  // Allocates a pair of registers where the first register index is even, if
-  // necessary.
-  Location AllocateAlignedRegisterPair() {
-    if (CallingConventions::kAlignArguments) {
-      cpu_regs_used += cpu_regs_used % 2;
-    }
-    if (cpu_regs_used > CallingConventions::kNumArgRegs - 2) {
-      return Location::Any();
-    }
-    return Location::Pair(AllocateCpuRegister(), AllocateCpuRegister());
-  }
-
-  intptr_t cpu_regs_used = 0;
-  intptr_t fpu_regs_used = 0;
-  intptr_t stack_height_in_slots = 0;
-};
-
-ZoneGrowableArray<Location>*
-CallbackArgumentTranslator::TranslateArgumentLocations(
-    const ZoneGrowableArray<Location>& arg_locs) {
-  auto& pushed_locs = *(new ZoneGrowableArray<Location>(arg_locs.length()));
-
-  CallbackArgumentTranslator translator;
-  for (intptr_t i = 0, n = arg_locs.length(); i < n; i++) {
-    translator.AllocateArgument(arg_locs[i]);
-  }
-  for (intptr_t i = 0, n = arg_locs.length(); i < n; ++i) {
-    pushed_locs.Add(translator.TranslateArgument(arg_locs[i]));
-  }
-
-  return &pushed_locs;
-}
-
-void CallbackArgumentTranslator::AllocateArgument(Location arg) {
-  if (arg.IsPairLocation()) {
-    AllocateArgument(arg.Component(0));
-    AllocateArgument(arg.Component(1));
-    return;
-  }
-  if (arg.HasStackIndex()) return;
-  ASSERT(arg.IsRegister() || arg.IsFpuRegister());
-  if (arg.IsRegister()) {
-    argument_slots_required_++;
-  } else {
-    argument_slots_required_ += 8 / target::kWordSize;
-  }
-}
-
-Location CallbackArgumentTranslator::TranslateArgument(Location arg) {
-  if (arg.IsPairLocation()) {
-    const Location low = TranslateArgument(arg.Component(0));
-    const Location high = TranslateArgument(arg.Component(1));
-    return Location::Pair(low, high);
-  }
-
-  if (arg.HasStackIndex()) {
-    // Add extra slots after the saved arguments for the return address and
-    // frame pointer of the dummy arguments frame, which will be between the
-    // saved argument registers and stack arguments. Also add slots for the
-    // shadow space if present (factored into
-    // kCallbackSlotsBeforeSavedArguments).
-    //
-    // Finally, if we are using NativeCallbackTrampolines, factor in the extra
-    // stack space corresponding to those trampolines' frames (above the entry
-    // frame).
-    intptr_t stack_delta = kCallbackSlotsBeforeSavedArguments;
-    if (NativeCallbackTrampolines::Enabled()) {
-      stack_delta += StubCodeCompiler::kNativeCallbackTrampolineStackDelta;
-    }
-    FrameRebase rebase(
-        /*old_base=*/SPREG, /*new_base=*/SPREG,
-        /*stack_delta=*/argument_slots_required_ + stack_delta);
-    return rebase.Rebase(arg);
-  }
-
-  if (arg.IsRegister()) {
-    return Location::StackSlot(argument_slots_used_++, SPREG);
-  }
-
-  ASSERT(arg.IsFpuRegister());
-  const Location result =
-      Location::DoubleStackSlot(argument_slots_used_, SPREG);
-  argument_slots_used_ += 8 / target::kWordSize;
-  return result;
-}
-
-// Takes a list of argument representations, and converts it to a list of
-// argument locations based on calling convention.
-
-ZoneGrowableArray<Location>* ArgumentLocations(
-    const ZoneGrowableArray<Representation>& arg_reps) {
-  intptr_t num_arguments = arg_reps.length();
-  auto result = new ZoneGrowableArray<Location>(num_arguments);
-
-  // Loop through all arguments and assign a register or a stack location.
-  ArgumentAllocator frame_state;
-  for (intptr_t i = 0; i < num_arguments; i++) {
-    Representation rep = arg_reps[i];
-    result->Add(frame_state.AllocateArgument(rep));
-  }
-  return result;
-}
-
-Location ResultLocation(Representation result_rep) {
-  switch (result_rep) {
-    case kUnboxedFloat:
-    case kUnboxedDouble:
-#if defined(TARGET_ARCH_IA32)
-      // The result is returned in ST0, but we don't allocate ST registers, so
-      // the FFI trampoline will move it to XMM0.
-      return Location::FpuRegisterLocation(XMM0);
-#else
-      return Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg);
-#endif
-    case kUnboxedInt32:
-    case kUnboxedUint32:
-      return Location::RegisterLocation(CallingConventions::kReturnReg);
-    case kUnboxedInt64:
-      if (target::kWordSize == 4) {
-        return Location::Pair(
-            Location::RegisterLocation(CallingConventions::kReturnReg),
-            Location::RegisterLocation(CallingConventions::kSecondReturnReg));
-      } else {
-        return Location::RegisterLocation(CallingConventions::kReturnReg);
-      }
-    default:
-      UNREACHABLE();
-  }
-}
-
-// TODO(36607): Cache the trampolines.
-RawFunction* TrampolineFunction(const Function& dart_signature,
-                                const Function& c_signature) {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
-  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
-  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
-  Function& function =
-      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
-                                           /*is_static=*/true,
-                                           /*is_const=*/false,
-                                           /*is_abstract=*/false,
-                                           /*is_external=*/false,
-                                           /*is_native=*/false, owner_class,
-                                           TokenPosition::kMinSource));
-  function.set_is_debuggable(false);
-  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
-  function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
-  function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
-
-  // The signature function won't have any names for the parameters. We need to
-  // assign unique names for scope building and error messages.
-  const intptr_t num_params = dart_signature.num_fixed_parameters();
-  const Array& parameter_names = Array::Handle(Array::New(num_params));
-  for (intptr_t i = 0; i < num_params; ++i) {
-    if (i == 0) {
-      name = Symbols::ClosureParameter().raw();
-    } else {
-      name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i);
-    }
-    parameter_names.SetAt(i, name);
-  }
-  function.set_parameter_names(parameter_names);
-  function.SetFfiCSignature(c_signature);
-
-  return function.raw();
-}
-
-// Accounts for alignment, where some stack slots are used as padding.
-intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
-  intptr_t num_arguments = locations.length();
-  intptr_t max_height_in_slots = 0;
-  for (intptr_t i = 0; i < num_arguments; i++) {
-    intptr_t height = 0;
-    if (locations.At(i).IsStackSlot()) {
-      height = locations.At(i).stack_index() + 1;
-    } else if (locations.At(i).IsDoubleStackSlot()) {
-      height = locations.At(i).stack_index() + 8 / target::kWordSize;
-    } else if (locations.At(i).IsPairLocation()) {
-      const Location first = locations.At(i).AsPairLocation()->At(0);
-      const Location second = locations.At(i).AsPairLocation()->At(1);
-      height = std::max(first.IsStackSlot() ? first.stack_index() + 1 : 0,
-                        second.IsStackSlot() ? second.stack_index() + 1 : 0);
-    }
-    max_height_in_slots = std::max(height, max_height_in_slots);
-  }
-  return max_height_in_slots;
-}
-
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
-}  // namespace ffi
-
-}  // namespace compiler
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/ffi.h b/runtime/vm/compiler/ffi.h
deleted file mode 100644
index a1b50b1..0000000
--- a/runtime/vm/compiler/ffi.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-#ifndef RUNTIME_VM_COMPILER_FFI_H_
-#define RUNTIME_VM_COMPILER_FFI_H_
-
-#include <platform/globals.h>
-
-#include "../class_id.h"
-#include "../object.h"
-#include "../raw_object.h"
-#include "backend/locations.h"
-
-namespace dart {
-
-namespace compiler {
-
-namespace ffi {
-
-// On all supported platforms, the minimum width an argument must be sign- or
-// zero-extended to is 4 bytes.
-constexpr intptr_t kMinimumArgumentWidth = 4;
-
-// Storage size for an FFI type (extends 'ffi.NativeType').
-size_t ElementSizeInBytes(intptr_t class_id);
-
-// TypedData class id for a NativeType type, except for Void and NativeFunction.
-classid_t ElementTypedDataCid(classid_t class_id);
-
-// Returns the kFFi<type>Cid for the recognized load/store method [kind].
-classid_t RecognizedMethodTypeArgCid(MethodRecognizer::Kind kind);
-
-// These ABIs should be kept in sync with pkg/vm/lib/transformations/ffi.dart.
-enum class Abi {
-  kWordSize64 = 0,
-  kWordSize32Align32 = 1,
-  kWordSize32Align64 = 2
-};
-
-// The target ABI. Defines sizes and alignment of native types.
-Abi TargetAbi();
-
-// Unboxed representation of an FFI type (extends 'ffi.NativeType').
-Representation TypeRepresentation(classid_t class_id);
-
-// Unboxed representation of an FFI type (extends 'ffi.NativeType') for 8 and 16
-// bit integers.
-SmallRepresentation TypeSmallRepresentation(const AbstractType& result_type);
-
-// Whether a type which extends 'ffi.NativeType' also extends 'ffi.Pointer'.
-bool NativeTypeIsPointer(const AbstractType& result_type);
-
-// Whether a type is 'ffi.Void'.
-bool NativeTypeIsVoid(const AbstractType& result_type);
-
-// Location for the result of a C signature function.
-Location ResultLocation(Representation result_rep);
-
-RawFunction* TrampolineFunction(const Function& dart_signature,
-                                const Function& c_signature);
-
-RawFunction* NativeCallbackFunction(const Function& c_signature,
-                                    const Function& dart_target,
-                                    const Instance& exceptional_return);
-
-// Unboxed representations of the arguments to a C signature function.
-ZoneGrowableArray<Representation>* ArgumentRepresentations(
-    const Function& signature);
-
-// Unboxed representation of the result of a C signature function.
-Representation ResultRepresentation(const Function& signature);
-
-// Location for the arguments of a C signature function.
-ZoneGrowableArray<Location>* ArgumentLocations(
-    const ZoneGrowableArray<Representation>& arg_reps);
-
-// Number of stack slots used in 'locations'.
-intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations);
-
-// This classes translates the ABI location of arguments into the locations they
-// will inhabit after entry-frame setup in the invocation of a native callback.
-//
-// Native -> Dart callbacks must push all the arguments before executing any
-// Dart code because the reading the Thread from TLS requires calling a native
-// stub, and the argument registers are volatile on all ABIs we support.
-//
-// To avoid complicating initial definitions, all callback arguments are read
-// off the stack from their pushed locations, so this class updates the argument
-// positions to account for this.
-//
-// See 'NativeEntryInstr::EmitNativeCode' for details.
-class CallbackArgumentTranslator : public ValueObject {
- public:
-  static ZoneGrowableArray<Location>* TranslateArgumentLocations(
-      const ZoneGrowableArray<Location>& arg_locs);
-
- private:
-  void AllocateArgument(Location arg);
-  Location TranslateArgument(Location arg);
-
-  intptr_t argument_slots_used_ = 0;
-  intptr_t argument_slots_required_ = 0;
-};
-
-}  // namespace ffi
-
-}  // namespace compiler
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_FFI_H_
diff --git a/runtime/vm/compiler/ffi/abi.cc b/runtime/vm/compiler/ffi/abi.cc
new file mode 100644
index 0000000..f3ea956
--- /dev/null
+++ b/runtime/vm/compiler/ffi/abi.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/abi.h"
+
+#include "vm/constants.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// See pkg/vm/lib/transformations/ffi.dart, which makes these assumptions.
+struct AbiAlignmentDouble {
+  int8_t use_one_byte;
+  double d;
+};
+struct AbiAlignmentUint64 {
+  int8_t use_one_byte;
+  uint64_t i;
+};
+
+#if defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64)
+static_assert(offsetof(AbiAlignmentDouble, d) == 8,
+              "FFI transformation alignment");
+static_assert(offsetof(AbiAlignmentUint64, i) == 8,
+              "FFI transformation alignment");
+#elif (defined(HOST_ARCH_IA32) && /* NOLINT(whitespace/parens) */              \
+       (defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                    \
+        defined(HOST_OS_ANDROID))) ||                                          \
+    (defined(HOST_ARCH_ARM) && defined(HOST_OS_IOS))
+static_assert(offsetof(AbiAlignmentDouble, d) == 4,
+              "FFI transformation alignment");
+static_assert(offsetof(AbiAlignmentUint64, i) == 4,
+              "FFI transformation alignment");
+#elif defined(HOST_ARCH_IA32) && defined(HOST_OS_WINDOWS) ||                   \
+    defined(HOST_ARCH_ARM)
+static_assert(offsetof(AbiAlignmentDouble, d) == 8,
+              "FFI transformation alignment");
+static_assert(offsetof(AbiAlignmentUint64, i) == 8,
+              "FFI transformation alignment");
+#else
+#error "Unknown platform. Please add alignment requirements for ABI."
+#endif
+
+Abi TargetAbi() {
+#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
+  return Abi::kWordSize64;
+#elif (defined(TARGET_ARCH_IA32) && /* NOLINT(whitespace/parens) */            \
+       (defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) ||                \
+        defined(TARGET_OS_ANDROID))) ||                                        \
+    (defined(TARGET_ARCH_ARM) && defined(TARGET_OS_IOS))
+  return Abi::kWordSize32Align32;
+#elif defined(TARGET_ARCH_IA32) && defined(TARGET_OS_WINDOWS) ||               \
+    defined(TARGET_ARCH_ARM)
+  return Abi::kWordSize32Align64;
+#else
+#error "Unknown platform. Please add alignment requirements for ABI."
+#endif
+}
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/abi.h b/runtime/vm/compiler/ffi/abi.h
new file mode 100644
index 0000000..623374f
--- /dev/null
+++ b/runtime/vm/compiler/ffi/abi.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_ABI_H_
+#define RUNTIME_VM_COMPILER_FFI_ABI_H_
+
+#include <platform/globals.h>
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// These ABIs should be kept in sync with pkg/vm/lib/transformations/ffi.dart.
+enum class Abi {
+  kWordSize64 = 0,
+  kWordSize32Align32 = 1,
+  kWordSize32Align64 = 2
+};
+
+// The target ABI. Defines sizes and alignment of native types.
+Abi TargetAbi();
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_ABI_H_
diff --git a/runtime/vm/compiler/ffi/call.cc b/runtime/vm/compiler/ffi/call.cc
new file mode 100644
index 0000000..b13af64
--- /dev/null
+++ b/runtime/vm/compiler/ffi/call.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/call.h"
+
+#include "vm/symbols.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+// TODO(dartbug.com/36607): Cache the trampolines.
+RawFunction* TrampolineFunction(const Function& dart_signature,
+                                const Function& c_signature) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
+  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
+  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
+  Function& function =
+      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+                                           /*is_static=*/true,
+                                           /*is_const=*/false,
+                                           /*is_abstract=*/false,
+                                           /*is_external=*/false,
+                                           /*is_native=*/false, owner_class,
+                                           TokenPosition::kMinSource));
+  function.set_is_debuggable(false);
+  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
+  function.set_result_type(
+      AbstractType::Handle(zone, dart_signature.result_type()));
+  function.set_parameter_types(
+      Array::Handle(zone, dart_signature.parameter_types()));
+
+  // The signature function won't have any names for the parameters. We need to
+  // assign unique names for scope building and error messages.
+  const intptr_t num_params = dart_signature.num_fixed_parameters();
+  const Array& parameter_names = Array::Handle(zone, Array::New(num_params));
+  for (intptr_t i = 0; i < num_params; ++i) {
+    if (i == 0) {
+      name = Symbols::ClosureParameter().raw();
+    } else {
+      name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i);
+    }
+    parameter_names.SetAt(i, name);
+  }
+  function.set_parameter_names(parameter_names);
+  function.SetFfiCSignature(c_signature);
+
+  return function.raw();
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/call.h b/runtime/vm/compiler/ffi/call.h
new file mode 100644
index 0000000..3680481
--- /dev/null
+++ b/runtime/vm/compiler/ffi/call.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_CALL_H_
+#define RUNTIME_VM_COMPILER_FFI_CALL_H_
+
+#include <platform/globals.h>
+
+#include "vm/raw_object.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+RawFunction* TrampolineFunction(const Function& dart_signature,
+                                const Function& c_signature);
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_CALL_H_
diff --git a/runtime/vm/compiler/ffi/callback.cc b/runtime/vm/compiler/ffi/callback.cc
new file mode 100644
index 0000000..94abfb8
--- /dev/null
+++ b/runtime/vm/compiler/ffi/callback.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/callback.h"
+
+#include "vm/symbols.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+RawFunction* NativeCallbackFunction(const Function& c_signature,
+                                    const Function& dart_target,
+                                    const Instance& exceptional_return) {
+  Thread* const thread = Thread::Current();
+  const int32_t callback_id = thread->AllocateFfiCallbackId();
+
+  // Create a new Function named '<target>_FfiCallback' and stick it in the
+  // 'dart:ffi' library. Note that these functions will never be invoked by
+  // Dart, so they have may have duplicate names.
+  Zone* const zone = thread->zone();
+  const auto& name = String::Handle(
+      zone, Symbols::FromConcat(thread, Symbols::FfiCallback(),
+                                String::Handle(zone, dart_target.name())));
+  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
+  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
+  const Function& function =
+      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+                                           /*is_static=*/true,
+                                           /*is_const=*/false,
+                                           /*is_abstract=*/false,
+                                           /*is_external=*/false,
+                                           /*is_native=*/false, owner_class,
+                                           TokenPosition::kNoSource));
+  function.set_is_debuggable(false);
+
+  // Set callback-specific fields which the flow-graph builder needs to generate
+  // the body.
+  function.SetFfiCSignature(c_signature);
+  function.SetFfiCallbackId(callback_id);
+  function.SetFfiCallbackTarget(dart_target);
+
+  // We need to load the exceptional return value as a constant in the generated
+  // function. Even though the FE ensures that it is a constant, it could still
+  // be a literal allocated in new space. We need to copy it into old space in
+  // that case.
+  //
+  // Exceptional return values currently cannot be pointers because we don't
+  // have constant pointers.
+  //
+  // TODO(36730): We'll need to extend this when we support passing/returning
+  // structs by value.
+  ASSERT(exceptional_return.IsNull() || exceptional_return.IsNumber());
+  if (!exceptional_return.IsSmi() && exceptional_return.IsNew()) {
+    function.SetFfiCallbackExceptionalReturn(Instance::Handle(
+        zone, exceptional_return.CopyShallowToOldSpace(thread)));
+  } else {
+    function.SetFfiCallbackExceptionalReturn(exceptional_return);
+  }
+
+  return function.raw();
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/callback.h b/runtime/vm/compiler/ffi/callback.h
new file mode 100644
index 0000000..ff432e6
--- /dev/null
+++ b/runtime/vm/compiler/ffi/callback.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_CALLBACK_H_
+#define RUNTIME_VM_COMPILER_FFI_CALLBACK_H_
+
+#include <platform/globals.h>
+
+#include "vm/raw_object.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+RawFunction* NativeCallbackFunction(const Function& c_signature,
+                                    const Function& dart_target,
+                                    const Instance& exceptional_return);
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_CALLBACK_H_
diff --git a/runtime/vm/compiler/ffi/frame_rebase.cc b/runtime/vm/compiler/ffi/frame_rebase.cc
new file mode 100644
index 0000000..deef5ee
--- /dev/null
+++ b/runtime/vm/compiler/ffi/frame_rebase.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, 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 !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/ffi/frame_rebase.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+Location FrameRebase::Rebase(const Location loc) const {
+  if (loc.IsPairLocation()) {
+    return Location::Pair(Rebase(loc.Component(0)), Rebase(loc.Component(1)));
+  }
+  if (!loc.HasStackIndex() || loc.base_reg() != old_base_) {
+    return loc;
+  }
+
+  const intptr_t new_stack_index = loc.stack_index() + stack_delta_;
+  if (loc.IsStackSlot()) {
+    return Location::StackSlot(new_stack_index, new_base_);
+  }
+  if (loc.IsDoubleStackSlot()) {
+    return Location::DoubleStackSlot(new_stack_index, new_base_);
+  }
+  ASSERT(loc.IsQuadStackSlot());
+  return Location::QuadStackSlot(new_stack_index, new_base_);
+}
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/ffi/frame_rebase.h b/runtime/vm/compiler/ffi/frame_rebase.h
new file mode 100644
index 0000000..be10aa7
--- /dev/null
+++ b/runtime/vm/compiler/ffi/frame_rebase.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_FRAME_REBASE_H_
+#define RUNTIME_VM_COMPILER_FFI_FRAME_REBASE_H_
+
+#include "vm/compiler/backend/locations.h"
+#include "vm/compiler/runtime_api.h"
+#include "vm/thread.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// Describes a change of stack frame where the stack or base register or stack
+// offset may change. This class allows easily rebasing stack locations across
+// frame manipulations.
+//
+// If the stack offset register matches 'old_base', it is changed to 'new_base'
+// and 'stack_delta' (# of slots) is applied.
+class FrameRebase : public ValueObject {
+ public:
+  FrameRebase(const Register old_base,
+              const Register new_base,
+              intptr_t stack_delta)
+      : old_base_(old_base), new_base_(new_base), stack_delta_(stack_delta) {}
+
+  Location Rebase(const Location loc) const;
+
+ private:
+  const Register old_base_;
+  const Register new_base_;
+  const intptr_t stack_delta_;
+};
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_FRAME_REBASE_H_
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
new file mode 100644
index 0000000..758d1ad
--- /dev/null
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/marshaller.h"
+
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/raw_object.h"
+#include "vm/stack_frame.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+ZoneGrowableArray<Location>*
+CallbackArgumentTranslator::TranslateArgumentLocations(
+    const ZoneGrowableArray<Location>& arg_locs) {
+  auto& pushed_locs = *(new ZoneGrowableArray<Location>(arg_locs.length()));
+
+  CallbackArgumentTranslator translator;
+  for (intptr_t i = 0, n = arg_locs.length(); i < n; i++) {
+    translator.AllocateArgument(arg_locs[i]);
+  }
+  for (intptr_t i = 0, n = arg_locs.length(); i < n; ++i) {
+    pushed_locs.Add(translator.TranslateArgument(arg_locs[i]));
+  }
+
+  return &pushed_locs;
+}
+
+void CallbackArgumentTranslator::AllocateArgument(Location arg) {
+  if (arg.IsPairLocation()) {
+    AllocateArgument(arg.Component(0));
+    AllocateArgument(arg.Component(1));
+    return;
+  }
+  if (arg.HasStackIndex()) return;
+  ASSERT(arg.IsRegister() || arg.IsFpuRegister());
+  if (arg.IsRegister()) {
+    argument_slots_required_++;
+  } else {
+    argument_slots_required_ += 8 / target::kWordSize;
+  }
+}
+
+Location CallbackArgumentTranslator::TranslateArgument(Location arg) {
+  if (arg.IsPairLocation()) {
+    const Location low = TranslateArgument(arg.Component(0));
+    const Location high = TranslateArgument(arg.Component(1));
+    return Location::Pair(low, high);
+  }
+
+  if (arg.HasStackIndex()) {
+    // Add extra slots after the saved arguments for the return address and
+    // frame pointer of the dummy arguments frame, which will be between the
+    // saved argument registers and stack arguments. Also add slots for the
+    // shadow space if present (factored into
+    // kCallbackSlotsBeforeSavedArguments).
+    //
+    // Finally, if we are using NativeCallbackTrampolines, factor in the extra
+    // stack space corresponding to those trampolines' frames (above the entry
+    // frame).
+    intptr_t stack_delta = kCallbackSlotsBeforeSavedArguments;
+    if (NativeCallbackTrampolines::Enabled()) {
+      stack_delta += StubCodeCompiler::kNativeCallbackTrampolineStackDelta;
+    }
+    FrameRebase rebase(
+        /*old_base=*/SPREG, /*new_base=*/SPREG,
+        /*stack_delta=*/argument_slots_required_ + stack_delta);
+    return rebase.Rebase(arg);
+  }
+
+  if (arg.IsRegister()) {
+    return Location::StackSlot(argument_slots_used_++, SPREG);
+  }
+
+  ASSERT(arg.IsFpuRegister());
+  const Location result =
+      Location::DoubleStackSlot(argument_slots_used_, SPREG);
+  argument_slots_used_ += 8 / target::kWordSize;
+  return result;
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
new file mode 100644
index 0000000..de85c2c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
+#define RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
+
+#include <platform/globals.h>
+
+#include "vm/compiler/backend/locations.h"
+#include "vm/compiler/ffi/callback.h"
+#include "vm/compiler/ffi/native_calling_convention.h"
+#include "vm/object.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// This classes translates the ABI location of arguments into the locations they
+// will inhabit after entry-frame setup in the invocation of a native callback.
+//
+// Native -> Dart callbacks must push all the arguments before executing any
+// Dart code because the reading the Thread from TLS requires calling a native
+// stub, and the argument registers are volatile on all ABIs we support.
+//
+// To avoid complicating initial definitions, all callback arguments are read
+// off the stack from their pushed locations, so this class updates the argument
+// positions to account for this.
+//
+// See 'NativeEntryInstr::EmitNativeCode' for details.
+class CallbackArgumentTranslator : public ValueObject {
+ public:
+  static ZoneGrowableArray<Location>* TranslateArgumentLocations(
+      const ZoneGrowableArray<Location>& arg_locs);
+
+ private:
+  void AllocateArgument(Location arg);
+  Location TranslateArgument(Location arg);
+
+  intptr_t argument_slots_used_ = 0;
+  intptr_t argument_slots_required_ = 0;
+};
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
new file mode 100644
index 0000000..17aed54
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -0,0 +1,292 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/native_calling_convention.h"
+
+#include "vm/compiler/ffi/frame_rebase.h"
+#include "vm/log.h"
+#include "vm/stack_frame.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+Representation TypeRepresentation(classid_t class_id) {
+  switch (class_id) {
+    case kFfiFloatCid:
+      return kUnboxedFloat;
+    case kFfiDoubleCid:
+      return kUnboxedDouble;
+    case kFfiInt8Cid:
+    case kFfiInt16Cid:
+    case kFfiInt32Cid:
+      return kUnboxedInt32;
+    case kFfiUint8Cid:
+    case kFfiUint16Cid:
+    case kFfiUint32Cid:
+      return kUnboxedUint32;
+    case kFfiInt64Cid:
+    case kFfiUint64Cid:
+      return kUnboxedInt64;
+    case kFfiIntPtrCid:
+      return kUnboxedIntPtr;
+    case kFfiPointerCid:
+    case kFfiVoidCid:
+      return kUnboxedFfiIntPtr;
+    default:
+      UNREACHABLE();
+  }
+}
+
+SmallRepresentation TypeSmallRepresentation(const AbstractType& ffi_type) {
+  switch (ffi_type.type_class_id()) {
+    case kFfiInt8Cid:
+      return kSmallUnboxedInt8;
+    case kFfiInt16Cid:
+      return kSmallUnboxedInt16;
+    case kFfiUint8Cid:
+      return kSmallUnboxedUint8;
+    case kFfiUint16Cid:
+      return kSmallUnboxedUint16;
+    default:
+      return kNoSmallRepresentation;
+  }
+}
+
+bool NativeTypeIsVoid(const AbstractType& result_type) {
+  return result_type.type_class_id() == kFfiVoidCid;
+}
+
+bool NativeTypeIsPointer(const AbstractType& result_type) {
+  return result_type.type_class_id() == kFfiPointerCid;
+}
+
+// Converts a Ffi [signature] to a list of Representations.
+// Note that this ignores first argument (receiver) which is dynamic.
+ZoneGrowableArray<Representation>* ArgumentRepresentations(
+    const Function& signature) {
+  intptr_t num_arguments = signature.num_fixed_parameters() - 1;
+  auto result = new ZoneGrowableArray<Representation>(num_arguments);
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    AbstractType& arg_type =
+        AbstractType::Handle(signature.ParameterTypeAt(i + 1));
+    Representation rep = TypeRepresentation(arg_type.type_class_id());
+    // In non simulator mode host::CallingConventions == CallingConventions.
+    // In simulator mode convert arguments to host representation.
+    if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
+      rep = kUnboxedInt32;
+    } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
+      rep = kUnboxedInt64;
+    }
+    result->Add(rep);
+  }
+  return result;
+}
+
+Representation ResultRepresentation(const Function& signature) {
+  AbstractType& arg_type = AbstractType::Handle(signature.result_type());
+  Representation rep = TypeRepresentation(arg_type.type_class_id());
+  if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
+    rep = kUnboxedInt32;
+  } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
+    rep = kUnboxedInt64;
+  }
+  return rep;
+}
+
+// Represents the state of a stack frame going into a call, between allocations
+// of argument locations. Acts like a register allocator but for arguments in
+// the native ABI.
+class ArgumentAllocator : public ValueObject {
+ public:
+  Location AllocateArgument(Representation rep) {
+    switch (rep) {
+      case kUnboxedFloat:
+      case kUnboxedDouble: {
+        Location result = AllocateFpuRegister();
+        if (!result.IsUnallocated()) return result;
+        break;
+      }
+      case kUnboxedInt64:
+      case kUnboxedUint32:
+      case kUnboxedInt32: {
+        Location result = rep == kUnboxedInt64 && target::kWordSize == 4
+                              ? AllocateAlignedRegisterPair()
+                              : AllocateCpuRegister();
+        if (!result.IsUnallocated()) return result;
+        break;
+      }
+      default:
+        UNREACHABLE();
+    }
+
+    // Argument must be spilled.
+    if (rep == kUnboxedInt64 && target::kWordSize == 4) {
+      return AllocateAlignedStackSlots(rep);
+    } else if (rep == kUnboxedDouble) {
+      // By convention, we always use DoubleStackSlot for doubles, even on
+      // 64-bit systems.
+      ASSERT(!CallingConventions::kAlignArguments);
+      return AllocateDoubleStackSlot();
+    } else {
+      return AllocateStackSlot();
+    }
+  }
+
+ private:
+  Location AllocateStackSlot() {
+    return Location::StackSlot(stack_height_in_slots++,
+                               CallingConventions::kStackPointerRegister);
+  }
+
+  Location AllocateDoubleStackSlot() {
+    const Location result = Location::DoubleStackSlot(
+        stack_height_in_slots, CallingConventions::kStackPointerRegister);
+    stack_height_in_slots += 8 / target::kWordSize;
+    return result;
+  }
+
+  // Allocates a pair of stack slots where the first stack slot is aligned to an
+  // 8-byte boundary, if necessary.
+  Location AllocateAlignedStackSlots(Representation rep) {
+    if (CallingConventions::kAlignArguments && target::kWordSize == 4) {
+      stack_height_in_slots += stack_height_in_slots % 2;
+    }
+
+    Location result;
+    if (rep == kUnboxedDouble) {
+      result = Location::DoubleStackSlot(
+          stack_height_in_slots, CallingConventions::kStackPointerRegister);
+      stack_height_in_slots += 2;
+    } else {
+      const Location low = AllocateStackSlot();
+      const Location high = AllocateStackSlot();
+      result = Location::Pair(low, high);
+    }
+    return result;
+  }
+
+  Location AllocateFpuRegister() {
+    if (fpu_regs_used == CallingConventions::kNumFpuArgRegs) {
+      return Location::RequiresFpuRegister();
+    }
+
+    const Location result = Location::FpuRegisterLocation(
+        CallingConventions::FpuArgumentRegisters[fpu_regs_used]);
+    fpu_regs_used++;
+    if (CallingConventions::kArgumentIntRegXorFpuReg) {
+      cpu_regs_used++;
+    }
+    return result;
+  }
+
+  Location AllocateCpuRegister() {
+    if (cpu_regs_used == CallingConventions::kNumArgRegs) {
+      return Location::RequiresRegister();
+    }
+
+    const Location result = Location::RegisterLocation(
+        CallingConventions::ArgumentRegisters[cpu_regs_used]);
+    cpu_regs_used++;
+    if (CallingConventions::kArgumentIntRegXorFpuReg) {
+      fpu_regs_used++;
+    }
+    return result;
+  }
+
+  // Allocates a pair of registers where the first register index is even, if
+  // necessary.
+  Location AllocateAlignedRegisterPair() {
+    if (CallingConventions::kAlignArguments) {
+      cpu_regs_used += cpu_regs_used % 2;
+    }
+    if (cpu_regs_used > CallingConventions::kNumArgRegs - 2) {
+      return Location::Any();
+    }
+    return Location::Pair(AllocateCpuRegister(), AllocateCpuRegister());
+  }
+
+  intptr_t cpu_regs_used = 0;
+  intptr_t fpu_regs_used = 0;
+  intptr_t stack_height_in_slots = 0;
+};
+
+// Takes a list of argument representations, and converts it to a list of
+// argument locations based on calling convention.
+
+ZoneGrowableArray<Location>* ArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_reps) {
+  intptr_t num_arguments = arg_reps.length();
+  auto result = new ZoneGrowableArray<Location>(num_arguments);
+
+  // Loop through all arguments and assign a register or a stack location.
+  ArgumentAllocator frame_state;
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    Representation rep = arg_reps[i];
+    result->Add(frame_state.AllocateArgument(rep));
+  }
+  return result;
+}
+
+Location ResultLocation(Representation result_rep) {
+  switch (result_rep) {
+    case kUnboxedFloat:
+    case kUnboxedDouble:
+#if defined(TARGET_ARCH_IA32)
+      // The result is returned in ST0, but we don't allocate ST registers, so
+      // the FFI trampoline will move it to XMM0.
+      return Location::FpuRegisterLocation(XMM0);
+#else
+      return Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg);
+#endif
+    case kUnboxedInt32:
+    case kUnboxedUint32:
+      return Location::RegisterLocation(CallingConventions::kReturnReg);
+    case kUnboxedInt64:
+      if (target::kWordSize == 4) {
+        return Location::Pair(
+            Location::RegisterLocation(CallingConventions::kReturnReg),
+            Location::RegisterLocation(CallingConventions::kSecondReturnReg));
+      } else {
+        return Location::RegisterLocation(CallingConventions::kReturnReg);
+      }
+    default:
+      UNREACHABLE();
+  }
+}
+
+// Accounts for alignment, where some stack slots are used as padding.
+intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
+  intptr_t num_arguments = locations.length();
+  intptr_t max_height_in_slots = 0;
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    intptr_t height = 0;
+    if (locations.At(i).IsStackSlot()) {
+      height = locations.At(i).stack_index() + 1;
+    } else if (locations.At(i).IsDoubleStackSlot()) {
+      height = locations.At(i).stack_index() + 8 / target::kWordSize;
+    } else if (locations.At(i).IsPairLocation()) {
+      const Location first = locations.At(i).AsPairLocation()->At(0);
+      const Location second = locations.At(i).AsPairLocation()->At(1);
+      height =
+          Utils::Maximum(first.IsStackSlot() ? first.stack_index() + 1 : 0,
+                         second.IsStackSlot() ? second.stack_index() + 1 : 0);
+    }
+    max_height_in_slots = Utils::Maximum(height, max_height_in_slots);
+  }
+  return max_height_in_slots;
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.h b/runtime/vm/compiler/ffi/native_calling_convention.h
new file mode 100644
index 0000000..8336f1c
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_calling_convention.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_CALLING_CONVENTION_H_
+#define RUNTIME_VM_COMPILER_FFI_NATIVE_CALLING_CONVENTION_H_
+
+#include <platform/globals.h>
+
+#include "vm/compiler/backend/locations.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// Unboxed representation of an FFI type (extends 'ffi.NativeType').
+Representation TypeRepresentation(classid_t class_id);
+
+// Unboxed representation of an FFI type (extends 'ffi.NativeType') for 8 and 16
+// bit integers.
+SmallRepresentation TypeSmallRepresentation(const AbstractType& result_type);
+
+// Whether a type which extends 'ffi.NativeType' also extends 'ffi.Pointer'.
+bool NativeTypeIsPointer(const AbstractType& result_type);
+
+// Whether a type is 'ffi.Void'.
+bool NativeTypeIsVoid(const AbstractType& result_type);
+
+// Location for the result of a C signature function.
+Location ResultLocation(Representation result_rep);
+
+RawFunction* TrampolineFunction(const Function& dart_signature,
+                                const Function& c_signature);
+
+RawFunction* NativeCallbackFunction(const Function& c_signature,
+                                    const Function& dart_target,
+                                    const Instance& exceptional_return);
+
+// Unboxed representations of the arguments to a C signature function.
+ZoneGrowableArray<Representation>* ArgumentRepresentations(
+    const Function& signature);
+
+// Unboxed representation of the result of a C signature function.
+Representation ResultRepresentation(const Function& signature);
+
+// Location for the arguments of a C signature function.
+ZoneGrowableArray<Location>* ArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_reps);
+
+// Number of stack slots used in 'locations'.
+intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations);
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_NATIVE_CALLING_CONVENTION_H_
diff --git a/runtime/vm/compiler/ffi/native_representation.cc b/runtime/vm/compiler/ffi/native_representation.cc
new file mode 100644
index 0000000..1ccd606
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_representation.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/native_representation.h"
+
+#include "platform/assert.h"
+#include "platform/globals.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/compiler/runtime_api.h"
+#include "vm/object.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+static const size_t kSizeUnknown = 0;
+
+static const intptr_t kNumElementSizes = kFfiVoidCid - kFfiPointerCid + 1;
+
+static const size_t element_size_table[kNumElementSizes] = {
+    target::kWordSize,  // kFfiPointerCid
+    kSizeUnknown,       // kFfiNativeFunctionCid
+    1,                  // kFfiInt8Cid
+    2,                  // kFfiInt16Cid
+    4,                  // kFfiInt32Cid
+    8,                  // kFfiInt64Cid
+    1,                  // kFfiUint8Cid
+    2,                  // kFfiUint16Cid
+    4,                  // kFfiUint32Cid
+    8,                  // kFfiUint64Cid
+    target::kWordSize,  // kFfiIntPtrCid
+    4,                  // kFfiFloatCid
+    8,                  // kFfiDoubleCid
+    kSizeUnknown,       // kFfiVoidCid
+};
+
+size_t ElementSizeInBytes(intptr_t class_id) {
+  ASSERT(class_id != kFfiNativeFunctionCid);
+  ASSERT(class_id != kFfiVoidCid);
+  if (!RawObject::IsFfiTypeClassId(class_id)) {
+    // subtype of Pointer
+    class_id = kFfiPointerCid;
+  }
+  intptr_t index = class_id - kFfiPointerCid;
+  return element_size_table[index];
+}
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/native_representation.h b/runtime/vm/compiler/ffi/native_representation.h
new file mode 100644
index 0000000..48bcd1a
--- /dev/null
+++ b/runtime/vm/compiler/ffi/native_representation.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_REPRESENTATION_H_
+#define RUNTIME_VM_COMPILER_FFI_NATIVE_REPRESENTATION_H_
+
+#include <platform/globals.h>
+
+#include "platform/assert.h"
+#include "vm/allocation.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/compiler/runtime_api.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// Storage size for an FFI type (extends 'ffi.NativeType').
+size_t ElementSizeInBytes(intptr_t class_id);
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_NATIVE_REPRESENTATION_H_
diff --git a/runtime/vm/compiler/ffi/recognized_method.cc b/runtime/vm/compiler/ffi/recognized_method.cc
new file mode 100644
index 0000000..f13f041
--- /dev/null
+++ b/runtime/vm/compiler/ffi/recognized_method.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2020, 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.
+
+#include "vm/compiler/ffi/recognized_method.h"
+
+#include "vm/symbols.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+classid_t ElementTypedDataCid(classid_t class_id) {
+  ASSERT(class_id >= kFfiPointerCid);
+  ASSERT(class_id < kFfiVoidCid);
+  ASSERT(class_id != kFfiNativeFunctionCid);
+  switch (class_id) {
+    case kFfiInt8Cid:
+      return kTypedDataInt8ArrayCid;
+    case kFfiUint8Cid:
+      return kTypedDataUint8ArrayCid;
+    case kFfiInt16Cid:
+      return kTypedDataInt16ArrayCid;
+    case kFfiUint16Cid:
+      return kTypedDataUint16ArrayCid;
+    case kFfiInt32Cid:
+      return kTypedDataInt32ArrayCid;
+    case kFfiUint32Cid:
+      return kTypedDataUint32ArrayCid;
+    case kFfiInt64Cid:
+      return kTypedDataInt64ArrayCid;
+    case kFfiUint64Cid:
+      return kTypedDataUint64ArrayCid;
+    case kFfiIntPtrCid:
+      return target::kWordSize == 4 ? kTypedDataInt32ArrayCid
+                                    : kTypedDataInt64ArrayCid;
+    case kFfiPointerCid:
+      return target::kWordSize == 4 ? kTypedDataUint32ArrayCid
+                                    : kTypedDataUint64ArrayCid;
+    case kFfiFloatCid:
+      return kTypedDataFloat32ArrayCid;
+    case kFfiDoubleCid:
+      return kTypedDataFloat64ArrayCid;
+    default:
+      UNREACHABLE();
+  }
+}
+
+classid_t RecognizedMethodTypeArgCid(MethodRecognizer::Kind kind) {
+  switch (kind) {
+#define LOAD_STORE(type)                                                       \
+  case MethodRecognizer::kFfiLoad##type:                                       \
+  case MethodRecognizer::kFfiStore##type:                                      \
+    return kFfi##type##Cid;
+    CLASS_LIST_FFI_NUMERIC(LOAD_STORE)
+    LOAD_STORE(Pointer)
+#undef LOAD_STORE
+    default:
+      UNREACHABLE();
+  }
+}
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/ffi/recognized_method.h b/runtime/vm/compiler/ffi/recognized_method.h
new file mode 100644
index 0000000..0bd7dab
--- /dev/null
+++ b/runtime/vm/compiler/ffi/recognized_method.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, 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.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_RECOGNIZED_METHOD_H_
+#define RUNTIME_VM_COMPILER_FFI_RECOGNIZED_METHOD_H_
+
+#include <platform/globals.h>
+
+#include "vm/compiler/method_recognizer.h"
+
+namespace dart {
+
+namespace compiler {
+
+namespace ffi {
+
+// TypedData class id for a NativeType type, except for Void and NativeFunction.
+classid_t ElementTypedDataCid(classid_t class_id);
+
+// Returns the kFFi<type>Cid for the recognized load/store method [kind].
+classid_t RecognizedMethodTypeArgCid(MethodRecognizer::Kind kind);
+
+}  // namespace ffi
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_RECOGNIZED_METHOD_H_
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index dd86588..958e626 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -4,6 +4,7 @@
 
 #include "vm/compiler/frontend/base_flow_graph_builder.h"
 
+#include "vm/compiler/ffi/call.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"  // For InlineExitCollector.
 #include "vm/compiler/jit/compiler.h"  // For Compiler::IsBackgroundCompilation().
 #include "vm/compiler/runtime_api.h"
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 98a38ef..42006a5 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -5,7 +5,7 @@
 #include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
 
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/callback.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/prologue_builder.h"
 #include "vm/compiler/jit/compiler.h"
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 765baf3..6441249 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4,7 +4,7 @@
 
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/callback.h"
 #include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"  // For dart::FlowGraphBuilder::SimpleInstanceOfType.
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index d5e7a59..c857a50 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -9,7 +9,10 @@
 #include "vm/compiler/backend/il.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/locations.h"
-#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi/abi.h"
+#include "vm/compiler/ffi/marshaller.h"
+#include "vm/compiler/ffi/native_representation.h"
+#include "vm/compiler/ffi/recognized_method.h"
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/compiler/frontend/prologue_builder.h"
diff --git a/runtime/vm/compiler/offsets_extractor.cc b/runtime/vm/compiler/offsets_extractor.cc
index 293ff55..5e82260 100644
--- a/runtime/vm/compiler/offsets_extractor.cc
+++ b/runtime/vm/compiler/offsets_extractor.cc
@@ -37,6 +37,53 @@
 class OffsetsExtractor : public AllStatic {
  public:
   static void DumpOffsets() {
+#if defined(DART_PRECOMPILED_RUNTIME)
+
+#define PRINT_FIELD_OFFSET(Class, Name)                                        \
+  std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
+               "_" #Name " = "                                                 \
+            << Class::Name() << ";\n";
+
+#define PRINT_ARRAY_LAYOUT(Class, Name)                                        \
+  std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
+               "_elements_start_offset = "                                     \
+            << Class::ArrayLayout::elements_start_offset() << ";\n";           \
+  std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
+               "_element_size = "                                              \
+            << Class::ArrayLayout::kElementSize << ";\n";
+
+#define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName,         \
+                                       FieldOffset)
+
+#define PRINT_SIZEOF(Class, Name, What)                                        \
+  std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
+               "_" #Name " = "                                                 \
+            << sizeof(What) << ";\n";
+
+#define PRINT_RANGE(Class, Name, Type, First, Last, Filter)                    \
+  {                                                                            \
+    auto filter = Filter;                                                      \
+    bool comma = false;                                                        \
+    std::cout << "static constexpr dart::compiler::target::word AOT_" #Class   \
+                 "_" #Name "[] = {";                                           \
+    for (intptr_t i = static_cast<intptr_t>(First);                            \
+         i <= static_cast<intptr_t>(Last); i++) {                              \
+      auto v = static_cast<Type>(i);                                           \
+      std::cout << (comma ? ", " : "") << (filter(v) ? Class::Name(v) : -1);   \
+      comma = true;                                                            \
+    }                                                                          \
+    std::cout << "};\n";                                                       \
+  }
+
+#define PRINT_CONSTANT(Class, Name)                                            \
+  std::cout << "static constexpr dart::compiler::target::word AOT_" #Class     \
+               "_" #Name " = "                                                 \
+            << Class::Name << ";\n";
+
+#define PRECOMP_NO_CHECK(Code)
+
+#else  // defined(DART_PRECOMPILED_RUNTIME)
+
 #define PRINT_FIELD_OFFSET(Class, Name)                                        \
   std::cout << "static constexpr dart::compiler::target::word " #Class         \
                "_" #Name " = "                                                 \
@@ -80,6 +127,8 @@
 
 #define PRECOMP_NO_CHECK(Code) Code
 
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+
     OFFSETS_LIST(PRINT_FIELD_OFFSET, PRINT_ARRAY_LAYOUT,
                  PRINT_ARRAY_STRUCTFIELD_OFFSET, PRINT_SIZEOF, PRINT_RANGE,
                  PRINT_CONSTANT, PRECOMP_NO_CHECK)
@@ -98,7 +147,9 @@
 
 int main(int argc, char* argv[]) {
   std::cout << "#if " << ARCH_DEF << std::endl;
+#if !defined(TARGET_ARCH_IA32) || !defined(DART_PRECOMPILED_RUNTIME)
   dart::OffsetsExtractor::DumpOffsets();
+#endif
   std::cout << "#endif  // " << ARCH_DEF << std::endl;
   return 0;
 }
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 63299ee..d628ac8 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -469,9 +469,20 @@
     return element_offset(index) + field_offset;                               \
   }
 
+#if defined(TARGET_ARCH_IA32)
+
 #define DEFINE_SIZEOF(clazz, name, what)                                       \
   word clazz::name() { return clazz##_##name; }
 
+#else
+
+#define DEFINE_SIZEOF(clazz, name, what)                                       \
+  word clazz::name() {                                                         \
+    return FLAG_precompiled_mode ? AOT_##clazz##_##name : clazz##_##name;      \
+  }
+
+#endif  //  defined(TARGET_ARCH_IA32)
+
 #define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter)                 \
   word Class::Getter(Type index) {                                             \
     return Class##_##Getter[static_cast<intptr_t>(index) -                     \
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index a16384f..5617457 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -15,6 +15,8 @@
 // when the offsets change, which is usually detected by CheckOffsets() in
 // dart.cc.
 
+#if !defined(PRODUCT)
+
 #if defined(TARGET_ARCH_ARM)
 static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
     8;
@@ -162,10 +164,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    64;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 32;
+    112;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 56;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    80;
+    136;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
     8;
@@ -539,10 +541,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    128;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 64;
+    224;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 112;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    160;
+    272;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
     16;
@@ -916,10 +918,10 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    64;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 32;
+    112;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 56;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    80;
+    136;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
     8;
@@ -1289,10 +1291,10 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    128;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 64;
+    224;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 112;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    160;
+    272;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
     16;
@@ -1520,4 +1522,3898 @@
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 #endif  // defined(TARGET_ARCH_ARM64)
 
+#else  // !defined(PRODUCT)
+
+#if defined(TARGET_ARCH_ARM)
+static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
+    8;
+static constexpr dart::compiler::target::word ObjectPool_element_size = 4;
+static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
+static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
+    65533;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetJIT = 0;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetAOT = 0;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetAOT = 12;
+static constexpr dart::compiler::target::word HeapPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word
+    NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
+static constexpr dart::compiler::target::word
+    AbstractType_type_test_stub_entry_point_offset = 4;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
+    16;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_first_named_entry_offset = 24;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_named_entry_size = 8;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
+    0;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_position_offset = 4;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_positional_count_offset = 20;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_type_args_len_offset = 12;
+static constexpr dart::compiler::target::word Array_data_offset = 12;
+static constexpr dart::compiler::target::word Array_length_offset = 8;
+static constexpr dart::compiler::target::word Array_tags_offset = 0;
+static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word Class_declaration_type_offset =
+    56;
+static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
+    102;
+static constexpr dart::compiler::target::word Class_super_type_offset = 44;
+static constexpr dart::compiler::target::word
+    Class_type_arguments_field_offset_in_words_offset = 92;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 16;
+static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word Closure_context_offset = 20;
+static constexpr dart::compiler::target::word
+    Closure_delayed_type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Closure_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Closure_function_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Closure_hash_offset = 24;
+static constexpr dart::compiler::target::word
+    Closure_instantiator_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
+static constexpr dart::compiler::target::word Code_saved_instructions_offset =
+    24;
+static constexpr dart::compiler::target::word Code_owner_offset = 28;
+static constexpr dart::compiler::target::word Context_num_variables_offset = 4;
+static constexpr dart::compiler::target::word Context_parent_offset = 8;
+static constexpr dart::compiler::target::word Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    ExternalOneByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word
+    ExternalTwoByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 52;
+static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 60;
+static constexpr dart::compiler::target::word Function_code_offset = 44;
+static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
+    4, 8};
+static constexpr dart::compiler::target::word Function_usage_counter_offset =
+    76;
+static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_length_offset = 8;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    ICData_arguments_descriptor_offset = 12;
+static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_owner_offset = 20;
+static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
+static constexpr dart::compiler::target::word
+    ICData_receivers_static_type_offset = 16;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 40;
+static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
+static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
+static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 36;
+static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
+static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
+static constexpr dart::compiler::target::word
+    LinkedHashMap_deleted_keys_offset = 24;
+static constexpr dart::compiler::target::word LinkedHashMap_hash_mask_offset =
+    12;
+static constexpr dart::compiler::target::word LinkedHashMap_index_offset = 8;
+static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
+    20;
+static constexpr dart::compiler::target::word
+    MarkingStackBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
+static constexpr dart::compiler::target::word
+    MegamorphicCache_arguments_descriptor_offset = 16;
+static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
+    4;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+static constexpr dart::compiler::target::word Mint_value_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
+    4;
+static constexpr dart::compiler::target::word NativeArguments_argv_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_retval_offset =
+    12;
+static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
+    112;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 56;
+static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
+    136;
+static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
+static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+    8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_lower_limit_offset = 12;
+static constexpr dart::compiler::target::word SingleTargetCache_target_offset =
+    4;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_upper_limit_offset = 14;
+static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset =
+    8;
+static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4;
+static constexpr dart::compiler::target::word String_hash_offset = 8;
+static constexpr dart::compiler::target::word String_length_offset = 4;
+static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
+static constexpr dart::compiler::target::word
+    Thread_AllocateArray_entry_point_offset = 328;
+static constexpr dart::compiler::target::word Thread_active_exception_offset =
+    664;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    668;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 220;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 244;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 248;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 164;
+static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
+    92;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 288;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 700;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    268;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 180;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    272;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    184;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    308;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 304;
+static constexpr dart::compiler::target::word Thread_end_offset = 68;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 204;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    684;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 208;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 212;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 320;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 316;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    312;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 324;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
+    672;
+static constexpr dart::compiler::target::word
+    Thread_interpret_call_entry_point_offset = 292;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_from_bytecode_stub_offset = 136;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 52;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    56;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_return_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_throw_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_lazy_specialize_type_test_stub_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_marking_stack_block_offset = 80;
+static constexpr dart::compiler::target::word
+    Thread_megamorphic_call_checked_entry_offset = 260;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_entry_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_stub_offset = 176;
+static constexpr dart::compiler::target::word
+    Thread_no_scope_native_wrapper_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 148;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 156;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 228;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 144;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 152;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 296;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 676;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 680;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
+    688;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
+    40;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_flags_offset = 44;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 168;
+static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
+    76;
+static constexpr dart::compiler::target::word
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 64;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+static constexpr dart::compiler::target::word
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
+static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
+    116;
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_entry_point_offset = 216;
+static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
+    48;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 692;
+static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
+static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
+static constexpr dart::compiler::target::word Type_signature_offset = 24;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word
+    TypeArguments_instantiations_offset = 4;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
+    4;
+static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
+static constexpr dart::compiler::target::word
+    TypedDataView_offset_in_bytes_offset = 16;
+static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_expected_cid_offset = 8;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_entrypoint_offset = 12;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Array_element_size = 4;
+static constexpr dart::compiler::target::word
+    TypeArguments_elements_start_offset = 16;
+static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
+static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
+    4, 12, 8, 16};
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_wrappers_thread_offset[] = {
+        628, 632, 636, 640, 644, -1, 648, 652,
+        656, 660, -1,  -1,  -1,  -1, -1,  -1};
+static constexpr dart::compiler::target::word Array_header_size = 12;
+static constexpr dart::compiler::target::word Context_header_size = 12;
+static constexpr dart::compiler::target::word Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
+    8;
+static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
+static constexpr dart::compiler::target::word String_InstanceSize = 12;
+static constexpr dart::compiler::target::word TypedData_InstanceSize = 12;
+static constexpr dart::compiler::target::word Object_InstanceSize = 4;
+static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
+static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
+static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
+    16;
+static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
+static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
+#endif  // defined(TARGET_ARCH_ARM)
+
+#if defined(TARGET_ARCH_X64)
+static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetAOT = 22;
+static constexpr dart::compiler::target::word HeapPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word
+    NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
+static constexpr dart::compiler::target::word
+    AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
+    32;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
+    0;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word Array_data_offset = 24;
+static constexpr dart::compiler::target::word Array_length_offset = 16;
+static constexpr dart::compiler::target::word Array_tags_offset = 0;
+static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Class_declaration_type_offset =
+    112;
+static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
+    182;
+static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word Code_saved_instructions_offset =
+    48;
+static constexpr dart::compiler::target::word Code_owner_offset = 56;
+static constexpr dart::compiler::target::word Context_num_variables_offset = 8;
+static constexpr dart::compiler::target::word Context_parent_offset = 16;
+static constexpr dart::compiler::target::word Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 104;
+static constexpr dart::compiler::target::word Function_code_offset = 88;
+static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
+    8, 16};
+static constexpr dart::compiler::target::word Function_usage_counter_offset =
+    132;
+static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_owner_offset = 40;
+static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
+static constexpr dart::compiler::target::word
+    ICData_receivers_static_type_offset = 32;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 80;
+static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
+static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
+static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 72;
+static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
+static constexpr dart::compiler::target::word
+    LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word LinkedHashMap_hash_mask_offset =
+    24;
+static constexpr dart::compiler::target::word LinkedHashMap_index_offset = 16;
+static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
+    40;
+static constexpr dart::compiler::target::word
+    MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
+static constexpr dart::compiler::target::word
+    MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
+    8;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+static constexpr dart::compiler::target::word Mint_value_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
+    8;
+static constexpr dart::compiler::target::word NativeArguments_argv_offset = 16;
+static constexpr dart::compiler::target::word NativeArguments_retval_offset =
+    24;
+static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
+    224;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 112;
+static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
+    272;
+static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
+static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+    16;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word SingleTargetCache_target_offset =
+    8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset =
+    16;
+static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8;
+static constexpr dart::compiler::target::word String_hash_offset = 4;
+static constexpr dart::compiler::target::word String_length_offset = 8;
+static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_active_exception_offset =
+    1336;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1344;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
+    184;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1408;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 352;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    536;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    360;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    608;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1376;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    616;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
+    1352;
+static constexpr dart::compiler::target::word
+    Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    112;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1360;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1368;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
+    1384;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
+    80;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
+    152;
+static constexpr dart::compiler::target::word
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 128;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
+    224;
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
+    96;
+static constexpr dart::compiler::target::word Thread_callback_code_offset =
+    1392;
+static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
+    16;
+static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
+static constexpr dart::compiler::target::word Type_signature_offset = 48;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
+static constexpr dart::compiler::target::word Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
+    8;
+static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word
+    TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
+static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, -1,   -1,   1280, 1288,
+        1296, 1304, 1312, -1,   1320, 1328, -1,   -1};
+static constexpr dart::compiler::target::word Array_header_size = 24;
+static constexpr dart::compiler::target::word Context_header_size = 24;
+static constexpr dart::compiler::target::word Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
+    12;
+static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
+static constexpr dart::compiler::target::word String_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
+static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
+    32;
+static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
+#endif  // defined(TARGET_ARCH_X64)
+
+#if defined(TARGET_ARCH_IA32)
+static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
+    8;
+static constexpr dart::compiler::target::word ObjectPool_element_size = 4;
+static constexpr dart::compiler::target::word Array_kMaxElements = 268435455;
+static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
+    65533;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetJIT = 6;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetJIT = 34;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetAOT = 0;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetAOT = 0;
+static constexpr dart::compiler::target::word HeapPage_kBytesPerCardLog2 = 9;
+static constexpr dart::compiler::target::word
+    NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word String_kMaxElements = 536870911;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
+static constexpr dart::compiler::target::word
+    AbstractType_type_test_stub_entry_point_offset = 4;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
+    16;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_first_named_entry_offset = 24;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_named_entry_size = 8;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
+    0;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_position_offset = 4;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_positional_count_offset = 20;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_type_args_len_offset = 12;
+static constexpr dart::compiler::target::word Array_data_offset = 12;
+static constexpr dart::compiler::target::word Array_length_offset = 8;
+static constexpr dart::compiler::target::word Array_tags_offset = 0;
+static constexpr dart::compiler::target::word Array_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word Class_declaration_type_offset =
+    56;
+static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
+    102;
+static constexpr dart::compiler::target::word Class_super_type_offset = 44;
+static constexpr dart::compiler::target::word
+    Class_type_arguments_field_offset_in_words_offset = 92;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 16;
+static constexpr dart::compiler::target::word ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word Closure_context_offset = 20;
+static constexpr dart::compiler::target::word
+    Closure_delayed_type_arguments_offset = 12;
+static constexpr dart::compiler::target::word Closure_function_offset = 16;
+static constexpr dart::compiler::target::word
+    Closure_function_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Closure_hash_offset = 24;
+static constexpr dart::compiler::target::word
+    Closure_instantiator_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word Code_object_pool_offset = 20;
+static constexpr dart::compiler::target::word Code_saved_instructions_offset =
+    24;
+static constexpr dart::compiler::target::word Code_owner_offset = 28;
+static constexpr dart::compiler::target::word Context_num_variables_offset = 4;
+static constexpr dart::compiler::target::word Context_parent_offset = 8;
+static constexpr dart::compiler::target::word Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    ExternalOneByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word
+    ExternalTwoByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 52;
+static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
+    24;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 60;
+static constexpr dart::compiler::target::word Function_code_offset = 44;
+static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
+    4, 8};
+static constexpr dart::compiler::target::word Function_usage_counter_offset =
+    76;
+static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_length_offset = 8;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word HeapPage_card_table_offset = 20;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    ICData_arguments_descriptor_offset = 12;
+static constexpr dart::compiler::target::word ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word ICData_owner_offset = 20;
+static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
+static constexpr dart::compiler::target::word
+    ICData_receivers_static_type_offset = 16;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 40;
+static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
+static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
+static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 36;
+static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
+static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
+static constexpr dart::compiler::target::word
+    LinkedHashMap_deleted_keys_offset = 24;
+static constexpr dart::compiler::target::word LinkedHashMap_hash_mask_offset =
+    12;
+static constexpr dart::compiler::target::word LinkedHashMap_index_offset = 8;
+static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
+    20;
+static constexpr dart::compiler::target::word
+    MarkingStackBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
+static constexpr dart::compiler::target::word
+    MegamorphicCache_arguments_descriptor_offset = 16;
+static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
+    4;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 8;
+static constexpr dart::compiler::target::word Mint_value_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
+    4;
+static constexpr dart::compiler::target::word NativeArguments_argv_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_retval_offset =
+    12;
+static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
+    112;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 56;
+static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
+    136;
+static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
+static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+    8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_lower_limit_offset = 12;
+static constexpr dart::compiler::target::word SingleTargetCache_target_offset =
+    4;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_upper_limit_offset = 14;
+static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset =
+    8;
+static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4;
+static constexpr dart::compiler::target::word String_hash_offset = 8;
+static constexpr dart::compiler::target::word String_length_offset = 4;
+static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4;
+static constexpr dart::compiler::target::word
+    Thread_AllocateArray_entry_point_offset = 328;
+static constexpr dart::compiler::target::word Thread_active_exception_offset =
+    628;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    632;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 220;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 244;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 248;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 164;
+static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
+    92;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 288;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 112;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 224;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 664;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    268;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 180;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    272;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    184;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    308;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 304;
+static constexpr dart::compiler::target::word Thread_end_offset = 68;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 204;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    648;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 208;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 212;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 320;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 316;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    312;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 324;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
+    636;
+static constexpr dart::compiler::target::word
+    Thread_interpret_call_entry_point_offset = 292;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_from_bytecode_stub_offset = 136;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 52;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    56;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_return_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_throw_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    Thread_lazy_specialize_type_test_stub_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_marking_stack_block_offset = 80;
+static constexpr dart::compiler::target::word
+    Thread_megamorphic_call_checked_entry_offset = 260;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_entry_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_stub_offset = 176;
+static constexpr dart::compiler::target::word
+    Thread_no_scope_native_wrapper_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 148;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 156;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 228;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 144;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 236;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 152;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 104;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 296;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 640;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 644;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
+    652;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_stub_offset = 196;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
+static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
+    40;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_flags_offset = 44;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 256;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 252;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 168;
+static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
+    76;
+static constexpr dart::compiler::target::word
+    Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word Thread_top_offset = 64;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 24;
+static constexpr dart::compiler::target::word
+    Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 88;
+static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
+    116;
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_entry_point_offset = 216;
+static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
+    48;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 656;
+static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
+static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
+static constexpr dart::compiler::target::word Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Type_hash_offset = 20;
+static constexpr dart::compiler::target::word Type_signature_offset = 24;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 12;
+static constexpr dart::compiler::target::word Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word
+    TypeArguments_instantiations_offset = 4;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
+    4;
+static constexpr dart::compiler::target::word TypedDataBase_length_offset = 8;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 12;
+static constexpr dart::compiler::target::word
+    TypedDataView_offset_in_bytes_offset = 16;
+static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_expected_cid_offset = 8;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_entrypoint_offset = 12;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word Array_elements_start_offset = 12;
+static constexpr dart::compiler::target::word Array_element_size = 4;
+static constexpr dart::compiler::target::word
+    TypeArguments_elements_start_offset = 16;
+static constexpr dart::compiler::target::word TypeArguments_element_size = 4;
+static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
+    4, 12, 8, 16};
+static constexpr dart::compiler::target::word Array_header_size = 12;
+static constexpr dart::compiler::target::word Context_header_size = 12;
+static constexpr dart::compiler::target::word Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
+    8;
+static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
+static constexpr dart::compiler::target::word String_InstanceSize = 12;
+static constexpr dart::compiler::target::word TypedData_InstanceSize = 12;
+static constexpr dart::compiler::target::word Object_InstanceSize = 4;
+static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 12;
+static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
+static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
+    16;
+static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
+static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
+#endif  // defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_ARM64)
+static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
+    16;
+static constexpr dart::compiler::target::word ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetJIT = 48;
+static constexpr dart::compiler::target::word
+    Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    Instructions_kPolymorphicEntryOffsetAOT = 20;
+static constexpr dart::compiler::target::word HeapPage_kBytesPerCardLog2 = 10;
+static constexpr dart::compiler::target::word
+    NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word SubtypeTestCache_kTestResult = 0;
+static constexpr dart::compiler::target::word
+    AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_count_offset =
+    32;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word ArgumentsDescriptor_name_offset =
+    0;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word Array_data_offset = 24;
+static constexpr dart::compiler::target::word Array_length_offset = 16;
+static constexpr dart::compiler::target::word Array_tags_offset = 0;
+static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Class_declaration_type_offset =
+    112;
+static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
+    182;
+static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word Code_saved_instructions_offset =
+    48;
+static constexpr dart::compiler::target::word Code_owner_offset = 56;
+static constexpr dart::compiler::target::word Context_num_variables_offset = 8;
+static constexpr dart::compiler::target::word Context_parent_offset = 16;
+static constexpr dart::compiler::target::word Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+static constexpr dart::compiler::target::word
+    Field_guarded_list_length_in_object_offset_offset = 88;
+static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
+    48;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 104;
+static constexpr dart::compiler::target::word Function_code_offset = 88;
+static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
+    8, 16};
+static constexpr dart::compiler::target::word Function_usage_counter_offset =
+    132;
+static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word HeapPage_card_table_offset = 40;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word ICData_owner_offset = 40;
+static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
+static constexpr dart::compiler::target::word
+    ICData_receivers_static_type_offset = 32;
+static constexpr dart::compiler::target::word Isolate_class_table_offset = 80;
+static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
+static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
+static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
+static constexpr dart::compiler::target::word Isolate_object_store_offset = 72;
+static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
+static constexpr dart::compiler::target::word
+    LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word LinkedHashMap_hash_mask_offset =
+    24;
+static constexpr dart::compiler::target::word LinkedHashMap_index_offset = 16;
+static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
+    40;
+static constexpr dart::compiler::target::word
+    MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
+static constexpr dart::compiler::target::word
+    MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word MegamorphicCache_buckets_offset =
+    8;
+static constexpr dart::compiler::target::word MegamorphicCache_mask_offset = 16;
+static constexpr dart::compiler::target::word Mint_value_offset = 8;
+static constexpr dart::compiler::target::word NativeArguments_argc_tag_offset =
+    8;
+static constexpr dart::compiler::target::word NativeArguments_argv_offset = 16;
+static constexpr dart::compiler::target::word NativeArguments_retval_offset =
+    24;
+static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
+    224;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 112;
+static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
+    272;
+static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
+static constexpr dart::compiler::target::word Pointer_c_memory_address_offset =
+    16;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word SingleTargetCache_target_offset =
+    8;
+static constexpr dart::compiler::target::word
+    SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset =
+    16;
+static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8;
+static constexpr dart::compiler::target::word String_hash_offset = 4;
+static constexpr dart::compiler::target::word String_length_offset = 8;
+static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word Thread_active_exception_offset =
+    1416;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+    1424;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
+    184;
+static constexpr dart::compiler::target::word
+    Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word Thread_bool_false_offset = 216;
+static constexpr dart::compiler::target::word Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488;
+static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 352;
+static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset =
+    536;
+static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset =
+    360;
+static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
+    608;
+static constexpr dart::compiler::target::word
+    Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word Thread_execution_state_offset =
+    1456;
+static constexpr dart::compiler::target::word
+    Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word Thread_float_not_address_offset =
+    616;
+static constexpr dart::compiler::target::word
+    Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
+    1432;
+static constexpr dart::compiler::target::word
+    Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word Thread_field_table_values_offset =
+    112;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word Thread_object_null_offset = 200;
+static constexpr dart::compiler::target::word
+    Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1440;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1448;
+static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
+    1464;
+static constexpr dart::compiler::target::word
+    Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
+static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset =
+    80;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word Thread_store_buffer_block_offset =
+    152;
+static constexpr dart::compiler::target::word
+    Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word Thread_top_offset = 128;
+static constexpr dart::compiler::target::word Thread_top_resource_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word Thread_write_barrier_code_offset =
+    224;
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
+    96;
+static constexpr dart::compiler::target::word Thread_callback_code_offset =
+    1472;
+static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
+    16;
+static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
+static constexpr dart::compiler::target::word Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word Type_hash_offset = 40;
+static constexpr dart::compiler::target::word Type_signature_offset = 48;
+static constexpr dart::compiler::target::word Type_type_class_id_offset = 24;
+static constexpr dart::compiler::target::word Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word TypedDataBase_data_field_offset =
+    8;
+static constexpr dart::compiler::target::word TypedDataBase_length_offset = 16;
+static constexpr dart::compiler::target::word TypedDataView_data_offset = 24;
+static constexpr dart::compiler::target::word
+    TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word Array_elements_start_offset = 24;
+static constexpr dart::compiler::target::word Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word TypeArguments_element_size = 8;
+static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328,
+        1336, 1344, 1352, 1360, -1,   -1,   -1,   -1,   1368, 1376, 1384,
+        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+static constexpr dart::compiler::target::word Array_header_size = 24;
+static constexpr dart::compiler::target::word Context_header_size = 24;
+static constexpr dart::compiler::target::word Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
+    12;
+static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
+static constexpr dart::compiler::target::word String_InstanceSize = 16;
+static constexpr dart::compiler::target::word TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
+static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
+    32;
+static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
+#endif  // defined(TARGET_ARCH_ARM64)
+
+#endif  // !defined(PRODUCT)
+
+#if !defined(PRODUCT)
+
+#if defined(TARGET_ARCH_ARM)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 8;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 4;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    268435455;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    65533;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 0;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 0;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 12;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    9;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    536870911;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 12;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    4;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 56;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 102;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 92;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 16;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 24;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 28;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    4;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 8;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {4, 8};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    20;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 12;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    20;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    28;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    36;
+static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
+    64;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 12;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    4;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 4;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 4;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 112;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    56;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 136;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 14;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    4;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 8;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 664;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 668;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 220;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 244;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 164;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 92;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 288;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    112;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 140;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    700;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    268;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    180;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 272;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 308;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 304;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 68;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 204;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 684;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 212;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 316;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 324;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 672;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 292;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 52;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 56;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 260;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 148;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 156;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 228;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 144;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 236;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 152;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 676;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 680;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 688;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 196;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    36;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 256;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 252;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 168;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 76;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 64;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 116;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 216;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 48;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    692;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 8;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 4;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    4;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_elements_start_offset = 0;
+static constexpr dart::compiler::target::word AOT_ClassTable_element_size = 1;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    4, 12, 8, 16};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        628, 632, 636, 640, 644, -1, 648, 652,
+        656, 660, -1,  -1,  -1,  -1, -1,  -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 12;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 8;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    16;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 4;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    12;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 4;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    28;
+#endif  // defined(TARGET_ARCH_ARM)
+
+#if defined(TARGET_ARCH_X64)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 22;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    10;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 16;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 182;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 48;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 56;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 16;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {8, 16};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    80;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    56;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    72;
+static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
+    128;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    32;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 24;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 8;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 8;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 224;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    112;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 272;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 4;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 1336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 1344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    216;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    1408;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 1376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 616;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 1352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
+    1360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 1368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 1384;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    72;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 152;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 128;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    1392;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 16;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 48;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_elements_start_offset = 0;
+static constexpr dart::compiler::target::word AOT_ClassTable_element_size = 1;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, -1,   -1,   1280, 1288,
+        1296, 1304, 1312, -1,   1320, 1328, -1,   -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 12;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    32;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    24;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    56;
+#endif  // defined(TARGET_ARCH_X64)
+
+#if defined(TARGET_ARCH_IA32)
+#endif  // defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_ARM64)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 48;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 20;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    10;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 16;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 182;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SharedClassTable_class_heap_stats_table_offset = 0;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 48;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 56;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 16;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {8, 16};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    80;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    56;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    72;
+static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
+    128;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    32;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 24;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 8;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 8;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 224;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    112;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 272;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 4;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 1416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 1424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    216;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    1488;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 1456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 616;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 1432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
+    1440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 1448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 1464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    72;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 152;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 128;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    1472;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 16;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 48;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_elements_start_offset = 0;
+static constexpr dart::compiler::target::word AOT_ClassTable_element_size = 1;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328,
+        1336, 1344, 1352, 1360, -1,   -1,   -1,   -1,   1368, 1376, 1384,
+        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 12;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    32;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    24;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    56;
+#endif  // defined(TARGET_ARCH_ARM64)
+
+#else  // !defined(PRODUCT)
+
+#if defined(TARGET_ARCH_ARM)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 8;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 4;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    268435455;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    65533;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 0;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 0;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 12;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    9;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    536870911;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 12;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    4;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 56;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 102;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 92;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 16;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 8;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 12;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 24;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 28;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    4;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 8;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {4, 8};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 4;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    20;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 12;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 4;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    20;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    28;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    36;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 12;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 20;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    4;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 4;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 4;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 112;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    56;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 136;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 14;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 8;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    4;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 8;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 664;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 668;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 120;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 220;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 244;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 164;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 92;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 288;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    112;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 108;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 140;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    700;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    268;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    180;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 272;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 308;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 304;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 68;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 204;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 684;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 212;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 276;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 128;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 124;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 316;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 324;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 672;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 292;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 132;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 52;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 56;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 188;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 192;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 260;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 284;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 148;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 156;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 228;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 144;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 236;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 152;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 676;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 680;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 688;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 196;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    36;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 44;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 256;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 252;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 168;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 76;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 72;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 64;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 116;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 216;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 48;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    692;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 8;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 20;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 24;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 33;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 4;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 4;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    12;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 4;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    12;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 4;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    4;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    4, 12, 8, 16};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        628, 632, 636, 640, 644, -1, 648, 652,
+        656, 660, -1,  -1,  -1,  -1, -1,  -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 12;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 8;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    16;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 12;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 4;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    12;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 4;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    28;
+#endif  // defined(TARGET_ARCH_ARM)
+
+#if defined(TARGET_ARCH_X64)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 40;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 22;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    10;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 16;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 182;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 48;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 56;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 16;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {8, 16};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    80;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    56;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    72;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    32;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 24;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 8;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 8;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 224;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    112;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 272;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 4;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 1336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 1344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    216;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    1408;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 1376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 616;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 1352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
+    1360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 1368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 1384;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    72;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 152;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 128;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    1392;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 16;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 48;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    8;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, -1,   -1,   1280, 1288,
+        1296, 1304, 1312, -1,   1320, 1328, -1,   -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 12;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    32;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    24;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    56;
+#endif  // defined(TARGET_ARCH_X64)
+
+#if defined(TARGET_ARCH_IA32)
+#endif  // defined(TARGET_ARCH_IA32)
+
+#if defined(TARGET_ARCH_ARM64)
+static constexpr dart::compiler::target::word
+    AOT_ObjectPool_elements_start_offset = 16;
+static constexpr dart::compiler::target::word AOT_ObjectPool_element_size = 8;
+static constexpr dart::compiler::target::word AOT_Array_kMaxElements =
+    576460752303423487;
+static constexpr dart::compiler::target::word AOT_Array_kMaxNewSpaceElements =
+    32765;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetJIT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetJIT = 48;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kMonomorphicEntryOffsetAOT = 8;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_kPolymorphicEntryOffsetAOT = 20;
+static constexpr dart::compiler::target::word AOT_HeapPage_kBytesPerCardLog2 =
+    10;
+static constexpr dart::compiler::target::word
+    AOT_NativeEntry_kNumCallWrapperArguments = 2;
+static constexpr dart::compiler::target::word AOT_String_kMaxElements =
+    2305843009213693951;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kFunctionTypeArguments = 4;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceClassIdOrFunction = 1;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceDelayedFunctionTypeArguments = 6;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceParentFunctionTypeArguments = 5;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstanceTypeArguments = 2;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kInstantiatorTypeArguments = 3;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_kTestEntryLength = 7;
+static constexpr dart::compiler::target::word AOT_SubtypeTestCache_kTestResult =
+    0;
+static constexpr dart::compiler::target::word
+    AOT_AbstractType_type_test_stub_entry_point_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_count_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_first_named_entry_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_named_entry_size = 16;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_name_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_position_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_positional_count_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_ArgumentsDescriptor_type_args_len_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_Array_length_offset = 16;
+static constexpr dart::compiler::target::word AOT_Array_tags_offset = 0;
+static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_Class_declaration_type_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Class_num_type_arguments_offset = 182;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Class_type_arguments_field_offset_in_words_offset = 172;
+static constexpr dart::compiler::target::word
+    AOT_ClassTable_shared_class_table_offset = 32;
+static constexpr dart::compiler::target::word AOT_ClassTable_table_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Closure_delayed_type_arguments_offset = 24;
+static constexpr dart::compiler::target::word AOT_Closure_function_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_Closure_function_type_arguments_offset = 16;
+static constexpr dart::compiler::target::word AOT_Closure_hash_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Closure_instantiator_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_Code_saved_instructions_offset = 48;
+static constexpr dart::compiler::target::word AOT_Code_owner_offset = 56;
+static constexpr dart::compiler::target::word AOT_Context_num_variables_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_Context_parent_offset = 16;
+static constexpr dart::compiler::target::word AOT_Double_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_ExternalOneByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_ExternalTwoByteString_external_data_offset = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Function_entry_point_offset[] = {8, 16};
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_length_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_type_arguments_offset = 8;
+static constexpr dart::compiler::target::word AOT_HeapPage_card_table_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedMask = 3;
+static constexpr dart::compiler::target::word AOT_ICData_NumArgsTestedShift = 0;
+static constexpr dart::compiler::target::word
+    AOT_ICData_arguments_descriptor_offset = 24;
+static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 8;
+static constexpr dart::compiler::target::word AOT_Isolate_class_table_offset =
+    80;
+static constexpr dart::compiler::target::word AOT_Isolate_current_tag_offset =
+    40;
+static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset =
+    48;
+static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
+    56;
+static constexpr dart::compiler::target::word AOT_Isolate_object_store_offset =
+    72;
+static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
+    32;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_deleted_keys_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_hash_mask_offset = 24;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_index_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word
+    AOT_MarkingStackBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_arguments_descriptor_offset = 32;
+static constexpr dart::compiler::target::word
+    AOT_MegamorphicCache_buckets_offset = 8;
+static constexpr dart::compiler::target::word AOT_MegamorphicCache_mask_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Mint_value_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_argc_tag_offset = 8;
+static constexpr dart::compiler::target::word AOT_NativeArguments_argv_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_retval_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_NativeArguments_thread_offset = 0;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_double_type_offset = 224;
+static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
+    112;
+static constexpr dart::compiler::target::word
+    AOT_ObjectStore_string_type_offset = 272;
+static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word
+    AOT_Pointer_c_memory_address_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_entry_point_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_lower_limit_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_target_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SingleTargetCache_upper_limit_offset = 26;
+static constexpr dart::compiler::target::word
+    AOT_StoreBufferBlock_pointers_offset = 16;
+static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset =
+    8;
+static constexpr dart::compiler::target::word AOT_String_hash_offset = 4;
+static constexpr dart::compiler::target::word AOT_String_length_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_SubtypeTestCache_cache_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_Thread_AllocateArray_entry_point_offset = 648;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_exception_offset = 1416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_active_stacktrace_offset = 1424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_code_offset = 232;
+static constexpr dart::compiler::target::word
+    AOT_Thread_array_write_barrier_entry_point_offset = 432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 480;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 312;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 488;
+static constexpr dart::compiler::target::word
+    AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 320;
+static constexpr dart::compiler::target::word
+    AOT_Thread_async_stack_trace_offset = 184;
+static constexpr dart::compiler::target::word
+    AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 568;
+static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset =
+    216;
+static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 208;
+static constexpr dart::compiler::target::word
+    AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 552;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_entry_point_offset = 440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_to_runtime_stub_offset = 272;
+static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
+    1488;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
+    528;
+static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
+    352;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_entry_offset = 536;
+static constexpr dart::compiler::target::word
+    AOT_Thread_deoptimize_stub_offset = 360;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_abs_address_offset = 608;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_negate_address_offset = 600;
+static constexpr dart::compiler::target::word AOT_Thread_end_offset = 136;
+static constexpr dart::compiler::target::word
+    AOT_Thread_enter_safepoint_stub_offset = 400;
+static constexpr dart::compiler::target::word
+    AOT_Thread_execution_state_offset = 1456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_safepoint_stub_offset = 408;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_stub_offset = 416;
+static constexpr dart::compiler::target::word
+    AOT_Thread_call_native_through_safepoint_entry_point_offset = 544;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_allocation_stub_code_offset = 248;
+static constexpr dart::compiler::target::word
+    AOT_Thread_fix_callers_target_code_offset = 240;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_absolute_address_offset = 632;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_negate_address_offset = 624;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_not_address_offset = 616;
+static constexpr dart::compiler::target::word
+    AOT_Thread_float_zerow_address_offset = 640;
+static constexpr dart::compiler::target::word
+    AOT_Thread_global_object_pool_offset = 1432;
+static constexpr dart::compiler::target::word
+    AOT_Thread_interpret_call_entry_point_offset = 576;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_invoke_dart_code_stub_offset = 256;
+static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 104;
+static constexpr dart::compiler::target::word
+    AOT_Thread_field_table_values_offset = 112;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_return_stub_offset = 368;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_deopt_from_throw_stub_offset = 376;
+static constexpr dart::compiler::target::word
+    AOT_Thread_lazy_specialize_type_test_stub_offset = 392;
+static constexpr dart::compiler::target::word
+    AOT_Thread_marking_stack_block_offset = 160;
+static constexpr dart::compiler::target::word
+    AOT_Thread_megamorphic_call_checked_entry_offset = 512;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_entry_offset = 520;
+static constexpr dart::compiler::target::word
+    AOT_Thread_monomorphic_miss_stub_offset = 344;
+static constexpr dart::compiler::target::word
+    AOT_Thread_no_scope_native_wrapper_entry_point_offset = 560;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_entry_point_offset = 456;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 288;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_entry_point_offset = 472;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 304;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_entry_point_offset = 448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 280;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_entry_point_offset = 464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 296;
+static constexpr dart::compiler::target::word AOT_Thread_object_null_offset =
+    200;
+static constexpr dart::compiler::target::word
+    AOT_Thread_predefined_symbols_address_offset = 584;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
+    1440;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_shadow_call_stack_offset = 1448;
+static constexpr dart::compiler::target::word
+    AOT_Thread_safepoint_state_offset = 1464;
+static constexpr dart::compiler::target::word
+    AOT_Thread_slow_type_test_stub_offset = 384;
+static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset =
+    72;
+static constexpr dart::compiler::target::word
+    AOT_Thread_saved_stack_limit_offset = 80;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_flags_offset = 88;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 504;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 336;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 496;
+static constexpr dart::compiler::target::word
+    AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 328;
+static constexpr dart::compiler::target::word
+    AOT_Thread_store_buffer_block_offset = 152;
+static constexpr dart::compiler::target::word
+    AOT_Thread_top_exit_frame_info_offset = 144;
+static constexpr dart::compiler::target::word AOT_Thread_top_offset = 128;
+static constexpr dart::compiler::target::word AOT_Thread_top_resource_offset =
+    48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_unboxed_int64_runtime_arg_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 176;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_code_offset = 224;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_entry_point_offset = 424;
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_mask_offset = 96;
+static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
+    1472;
+static constexpr dart::compiler::target::word
+    AOT_TimelineStream_enabled_offset = 16;
+static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_Type_arguments_offset = 32;
+static constexpr dart::compiler::target::word AOT_Type_hash_offset = 40;
+static constexpr dart::compiler::target::word AOT_Type_signature_offset = 48;
+static constexpr dart::compiler::target::word AOT_Type_type_class_id_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Type_type_state_offset = 60;
+static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 61;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_instantiations_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypeRef_type_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataBase_data_field_offset = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_length_offset =
+    16;
+static constexpr dart::compiler::target::word AOT_TypedDataView_data_offset =
+    24;
+static constexpr dart::compiler::target::word
+    AOT_TypedDataView_offset_in_bytes_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_entrypoint_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_MonomorphicSmiableCall_target_offset = 8;
+static constexpr dart::compiler::target::word AOT_Array_elements_start_offset =
+    24;
+static constexpr dart::compiler::target::word AOT_Array_element_size = 8;
+static constexpr dart::compiler::target::word
+    AOT_TypeArguments_elements_start_offset = 32;
+static constexpr dart::compiler::target::word AOT_TypeArguments_element_size =
+    8;
+static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
+    8, 24, 16, 32};
+static constexpr dart::compiler::target::word
+    AOT_Thread_write_barrier_wrappers_thread_offset[] = {
+        1248, 1256, 1264, 1272, 1280, 1288, 1296, 1304, 1312, 1320, 1328,
+        1336, 1344, 1352, 1360, -1,   -1,   -1,   -1,   1368, 1376, 1384,
+        -1,   1392, 1400, 1408, -1,   -1,   -1,   -1,   -1,   -1};
+static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Context_header_size = 24;
+static constexpr dart::compiler::target::word AOT_Double_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
+static constexpr dart::compiler::target::word
+    AOT_Instructions_UnalignedHeaderSize = 12;
+static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Mint_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
+    32;
+static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
+static constexpr dart::compiler::target::word AOT_TypedData_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_TypedDataBase_InstanceSize =
+    24;
+static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
+static constexpr dart::compiler::target::word
+    AOT_GrowableObjectArray_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 8;
+static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
+    56;
+#endif  // defined(TARGET_ARCH_ARM64)
+
+#endif  // !defined(PRODUCT)
+
 #endif  // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_EXTRACTED_H_
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 4078722..2ee57f4 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -172,7 +172,8 @@
     // Raspberry Pi, etc.
     arm_version_ = ARMv6;
   } else if (CpuInfo::FieldContains(kCpuInfoProcessor, "ARMv7") ||
-             CpuInfo::FieldContains(kCpuInfoModel, "ARMv7")) {
+             CpuInfo::FieldContains(kCpuInfoModel, "ARMv7") ||
+             CpuInfo::FieldContains(kCpuInfoArchitecture, "7")) {
     arm_version_ = ARMv7;
   } else {
 #if defined(DART_RUN_IN_QEMU_ARMv7)
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 6741b97..a3381d0 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -113,8 +113,15 @@
                Class##_elements_start_offset)                                  \
   CHECK_OFFSET(Class::ArrayLayout::kElementSize, Class##_element_size)
 #define CHECK_ARRAY_STRUCTFIELD(Class, Name, ElementOffsetName, FieldOffset)
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+#define CHECK_SIZEOF(Class, Name, What)                                        \
+  CHECK_OFFSET(sizeof(What), AOT_##Class##_##Name)
+#else
 #define CHECK_SIZEOF(Class, Name, What)                                        \
   CHECK_OFFSET(sizeof(What), Class##_##Name)
+#endif
+
 #define CHECK_RANGE(Class, Name, Type, First, Last, Filter)
 #define CHECK_CONSTANT(Class, Name) CHECK_OFFSET(Class::Name, Class##_##Name)
 
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index e598ded..6ac1947 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -694,16 +694,12 @@
 }
 
 Dart_CObject* ApiMessageReader::ReadIndexedObject(intptr_t object_id) {
-  if (object_id == kDynamicType || object_id == kDoubleType ||
-      object_id == kIntType || object_id == kBoolType ||
-      object_id == kStringType || object_id == kObjectType) {
+  if (object_id >= kFirstTypeSnapshotId && object_id <= kLastTypeSnapshotId) {
     // Always return dynamic type (this is only a marker).
     return &dynamic_type_marker;
   }
-  if (object_id == kIntTypeArguments || object_id == kDoubleTypeArguments ||
-      object_id == kStringTypeArguments ||
-      object_id == kStringDynamicTypeArguments ||
-      object_id == kStringStringTypeArguments) {
+  if (object_id >= kFirstTypeArgumentsSnapshotId &&
+      object_id <= kLastTypeArgumentsSnapshotId) {
     return &type_arguments_marker;
   }
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index bbff28b..f0b7a18 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1504,7 +1504,7 @@
     } else if (!name.Equals(Symbols::This()) &&
                !IsSyntheticVariableName(name)) {
       if (IsPrivateVariableName(name)) {
-        name = String::ScrubName(name);
+        name = Symbols::New(Thread::Current(), String::ScrubName(name));
       }
       bool conflict = false;
       for (intptr_t j = 0; j < param_names.Length(); j++) {
@@ -1639,8 +1639,8 @@
       if (!IsSyntheticVariableName(var_name)) {
         JSONObject jsvar(&jsvars);
         jsvar.AddProperty("type", "BoundVariable");
-        var_name = String::ScrubName(var_name);
-        jsvar.AddProperty("name", var_name.ToCString());
+        const char* scrubbed_var_name = String::ScrubName(var_name);
+        jsvar.AddProperty("name", scrubbed_var_name);
         jsvar.AddProperty("value", var_value);
         // Where was the variable declared?
         jsvar.AddProperty("declarationTokenPos", declaration_token_pos);
@@ -2348,8 +2348,14 @@
       zone, GrowableObjectArray::New(kDefaultStackAllocation));
   const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
       zone, GrowableObjectArray::New(kDefaultStackAllocation));
+  bool has_async = false;
   StackTraceUtils::CollectFramesLazy(thread, code_array, pc_offset_array,
-                                     /*skip_frames=*/0, &on_sync_frame);
+                                     /*skip_frames=*/0, &on_sync_frame,
+                                     &has_async);
+
+  if (!has_async) {
+    return nullptr;
+  }
 
   const intptr_t length = code_array.Length();
   for (intptr_t i = stack_trace->Length(); i < length; ++i) {
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index e2a2e1f..7f314f5 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -161,7 +161,7 @@
       return addr;
     }
     // Before throwing an out-of-memory error try a synchronous GC.
-    CollectAllGarbage();
+    CollectAllGarbage(kLowMemory);
     WaitForSweeperTasks(thread);
   }
   addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 6c5a066..0fc0a87 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -221,12 +221,6 @@
     : freelist_(),
       heap_(heap),
       pages_lock_(),
-      pages_(NULL),
-      pages_tail_(NULL),
-      exec_pages_(NULL),
-      exec_pages_tail_(NULL),
-      large_pages_(NULL),
-      image_pages_(NULL),
       bump_top_(0),
       bump_end_(0),
       max_capacity_in_words_(max_capacity_in_words),
@@ -273,49 +267,95 @@
   return page_size >> kWordSizeLog2;
 }
 
+void PageSpace::AddPageLocked(HeapPage* page) {
+  if (pages_ == nullptr) {
+    pages_ = page;
+  } else {
+    pages_tail_->set_next(page);
+  }
+  pages_tail_ = page;
+}
+
+void PageSpace::AddLargePageLocked(HeapPage* page) {
+  if (large_pages_ == nullptr) {
+    large_pages_ = page;
+  } else {
+    large_pages_tail_->set_next(page);
+  }
+  large_pages_tail_ = page;
+}
+
+void PageSpace::AddExecPageLocked(HeapPage* page) {
+  if (exec_pages_ == nullptr) {
+    exec_pages_ = page;
+  } else {
+    if (FLAG_write_protect_code) {
+      exec_pages_tail_->WriteProtect(false);
+    }
+    exec_pages_tail_->set_next(page);
+    if (FLAG_write_protect_code) {
+      exec_pages_tail_->WriteProtect(true);
+    }
+  }
+  exec_pages_tail_ = page;
+}
+
+void PageSpace::RemovePageLocked(HeapPage* page, HeapPage* previous_page) {
+  if (previous_page != NULL) {
+    previous_page->set_next(page->next());
+  } else {
+    pages_ = page->next();
+  }
+  if (page == pages_tail_) {
+    pages_tail_ = previous_page;
+  }
+}
+
+void PageSpace::RemoveLargePageLocked(HeapPage* page, HeapPage* previous_page) {
+  if (previous_page != NULL) {
+    previous_page->set_next(page->next());
+  } else {
+    large_pages_ = page->next();
+  }
+  if (page == large_pages_tail_) {
+    large_pages_tail_ = previous_page;
+  }
+}
+
+void PageSpace::RemoveExecPageLocked(HeapPage* page, HeapPage* previous_page) {
+  if (previous_page != NULL) {
+    previous_page->set_next(page->next());
+  } else {
+    exec_pages_ = page->next();
+  }
+  if (page == exec_pages_tail_) {
+    exec_pages_tail_ = previous_page;
+  }
+}
+
 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type, bool link) {
   {
     MutexLocker ml(&pages_lock_);
     if (!CanIncreaseCapacityInWordsLocked(kPageSizeInWords)) {
-      return NULL;
+      return nullptr;
     }
     IncreaseCapacityInWordsLocked(kPageSizeInWords);
   }
   const bool is_exec = (type == HeapPage::kExecutable);
   const char* name = Heap::RegionName(is_exec ? Heap::kCode : Heap::kOld);
   HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type, name);
-  if (page == NULL) {
+  if (page == nullptr) {
     RELEASE_ASSERT(!FLAG_abort_on_oom);
     IncreaseCapacityInWords(-kPageSizeInWords);
-    return NULL;
+    return nullptr;
   }
 
   MutexLocker ml(&pages_lock_);
   if (link) {
-    if (!is_exec) {
-      if (pages_ == NULL) {
-        pages_ = page;
-      } else {
-        pages_tail_->set_next(page);
-      }
-      pages_tail_ = page;
+    if (is_exec) {
+      AddExecPageLocked(page);
     } else {
-      // Should not allocate executable pages when running from a precompiled
-      // snapshot.
-      ASSERT(Dart::vm_snapshot_kind() != Snapshot::kFullAOT);
-
-      if (exec_pages_ == NULL) {
-        exec_pages_ = page;
-      } else {
-        if (FLAG_write_protect_code) {
-          exec_pages_tail_->WriteProtect(false);
-        }
-        exec_pages_tail_->set_next(page);
-        if (FLAG_write_protect_code) {
-          exec_pages_tail_->WriteProtect(true);
-        }
-      }
-      exec_pages_tail_ = page;
+      AddPageLocked(page);
     }
   }
 
@@ -332,26 +372,28 @@
   {
     MutexLocker ml(&pages_lock_);
     if (!CanIncreaseCapacityInWordsLocked(page_size_in_words)) {
-      return NULL;
+      return nullptr;
     }
     IncreaseCapacityInWordsLocked(page_size_in_words);
   }
   const bool is_exec = (type == HeapPage::kExecutable);
   const char* name = Heap::RegionName(is_exec ? Heap::kCode : Heap::kOld);
   HeapPage* page = HeapPage::Allocate(page_size_in_words, type, name);
-  {
-    MutexLocker ml(&pages_lock_);
-    if (page == nullptr) {
-      IncreaseCapacityInWordsLocked(-page_size_in_words);
-      return nullptr;
-    }
-    page->set_next(large_pages_);
-    large_pages_ = page;
 
-    // Only one object in this page (at least until Array::MakeFixedLength
-    // is called).
-    page->set_object_end(page->object_start() + size);
+  MutexLocker ml(&pages_lock_);
+  if (page == nullptr) {
+    IncreaseCapacityInWordsLocked(-page_size_in_words);
+    return nullptr;
   }
+  if (is_exec) {
+    AddExecPageLocked(page);
+  } else {
+    AddLargePageLocked(page);
+  }
+
+  // Only one object in this page (at least until Array::MakeFixedLength
+  // is called).
+  page->set_object_end(page->object_start() + size);
   return page;
 }
 
@@ -376,26 +418,10 @@
   {
     MutexLocker ml(&pages_lock_);
     IncreaseCapacityInWordsLocked(-(page->memory_->size() >> kWordSizeLog2));
-    if (!is_exec) {
-      // Remove the page from the list of data pages.
-      if (previous_page != NULL) {
-        previous_page->set_next(page->next());
-      } else {
-        pages_ = page->next();
-      }
-      if (page == pages_tail_) {
-        pages_tail_ = previous_page;
-      }
+    if (is_exec) {
+      RemoveExecPageLocked(page, previous_page);
     } else {
-      // Remove the page from the list of executable pages.
-      if (previous_page != NULL) {
-        previous_page->set_next(page->next());
-      } else {
-        exec_pages_ = page->next();
-      }
-      if (page == exec_pages_tail_) {
-        exec_pages_tail_ = previous_page;
-      }
+      RemovePageLocked(page, previous_page);
     }
   }
   // TODO(iposva): Consider adding to a pool of empty pages.
@@ -403,16 +429,10 @@
 }
 
 void PageSpace::FreeLargePage(HeapPage* page, HeapPage* previous_page) {
-  // Thread should be at a safepoint when this code is called and hence
-  // it is not necessary to lock large_pages_.
-  ASSERT(Thread::Current()->IsAtSafepoint());
-  IncreaseCapacityInWords(-(page->memory_->size() >> kWordSizeLog2));
-  // Remove the page from the list.
-  if (previous_page != NULL) {
-    previous_page->set_next(page->next());
-  } else {
-    large_pages_ = page->next();
-  }
+  ASSERT(page->type() != HeapPage::kExecutable);
+  MutexLocker ml(&pages_lock_);
+  IncreaseCapacityInWordsLocked(-(page->memory_->size() >> kWordSizeLog2));
+  RemoveLargePageLocked(page, previous_page);
   page->Deallocate();
 }
 
@@ -634,28 +654,6 @@
   HeapPage* page_;
 };
 
-// Provides exclusive access to large pages, and ensures they are walkable.
-class ExclusiveLargePageIterator : ValueObject {
- public:
-  explicit ExclusiveLargePageIterator(const PageSpace* space)
-      : space_(space), ml_(&space->pages_lock_) {
-    space_->MakeIterable();
-    page_ = space_->large_pages_;
-  }
-  HeapPage* page() const { return page_; }
-  bool Done() const { return page_ == NULL; }
-  void Advance() {
-    ASSERT(!Done());
-    page_ = page_->next();
-  }
-
- private:
-  const PageSpace* space_;
-  MutexLocker ml_;
-  NoSafepointScope no_safepoint;
-  HeapPage* page_;
-};
-
 void PageSpace::MakeIterable() const {
   // Assert not called from concurrent sweeper task.
   // TODO(koda): Use thread/task identity when implemented.
@@ -722,12 +720,6 @@
         return true;
       }
     }
-    // Large pages can be executable, walk them too.
-    for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) {
-      if ((it.page()->type() == type) && it.page()->Contains(addr)) {
-        return true;
-      }
-    }
     return false;
   }
   for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
@@ -785,7 +777,14 @@
 
 void PageSpace::VisitRememberedCards(ObjectPointerVisitor* visitor) const {
   ASSERT(Thread::Current()->IsAtSafepoint());
-  for (HeapPage* page = large_pages_; page != NULL; page = page->next()) {
+
+  // Wait for the sweeper to finish mutating the large page list.
+  MonitorLocker ml(tasks_lock());
+  while (phase() == kSweepingLarge) {
+    ml.Wait();  // No safepoint check.
+  }
+
+  for (HeapPage* page = large_pages_; page != nullptr; page = page->next()) {
     page->VisitRememberedCards(visitor);
   }
 }
@@ -800,15 +799,6 @@
         return obj;
       }
     }
-    // Large pages can be executable, walk them too.
-    for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) {
-      if (it.page()->type() == type) {
-        RawObject* obj = it.page()->FindObject(visitor);
-        if (obj != Object::null()) {
-          return obj;
-        }
-      }
-    }
     return Object::null();
   }
 
@@ -1132,36 +1122,18 @@
       OS::PrintErr(" done.\n");
     }
 
-    TIMELINE_FUNCTION_GC_DURATION(thread, "SweepLargeAndExecutablePages");
+    // Executable pages are always swept immediately to simplify
+    // code protection.
+
+    TIMELINE_FUNCTION_GC_DURATION(thread, "SweepExecutable");
     GCSweeper sweeper;
-
-    // During stop-the-world phases we should use bulk lock when adding
-    // elements to the free list.
-    MutexLocker mld(freelist_[HeapPage::kData].mutex());
-    MutexLocker mle(freelist_[HeapPage::kExecutable].mutex());
-
-    // Large and executable pages are always swept immediately.
     HeapPage* prev_page = NULL;
-    HeapPage* page = large_pages_;
-    while (page != NULL) {
-      HeapPage* next_page = page->next();
-      const intptr_t words_to_end = sweeper.SweepLargePage(page);
-      if (words_to_end == 0) {
-        FreeLargePage(page, prev_page);
-      } else {
-        TruncateLargePage(page, words_to_end << kWordSizeLog2);
-        prev_page = page;
-      }
-      // Advance to the next page.
-      page = next_page;
-    }
-
-    prev_page = NULL;
-    page = exec_pages_;
+    HeapPage* page = exec_pages_;
     FreeList* freelist = &freelist_[HeapPage::kExecutable];
+    MutexLocker ml(freelist->mutex());
     while (page != NULL) {
       HeapPage* next_page = page->next();
-      bool page_in_use = sweeper.SweepPage(page, freelist, true);
+      bool page_in_use = sweeper.SweepPage(page, freelist, true /*is_locked*/);
       if (page_in_use) {
         prev_page = page;
       } else {
@@ -1175,12 +1147,14 @@
   }
 
   if (compact) {
+    SweepLarge();
     Compact(thread);
     set_phase(kDone);
   } else if (FLAG_concurrent_sweep) {
     ConcurrentSweep(isolate);
   } else {
-    BlockingSweep();
+    SweepLarge();
+    Sweep();
     set_phase(kDone);
   }
 
@@ -1213,19 +1187,38 @@
   }
 }
 
-void PageSpace::BlockingSweep() {
+void PageSpace::SweepLarge() {
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "SweepLarge");
+
+  GCSweeper sweeper;
+  HeapPage* prev_page = nullptr;
+  HeapPage* page = large_pages_;
+  while (page != nullptr) {
+    HeapPage* next_page = page->next();
+    const intptr_t words_to_end = sweeper.SweepLargePage(page);
+    if (words_to_end == 0) {
+      FreeLargePage(page, prev_page);
+    } else {
+      TruncateLargePage(page, words_to_end << kWordSizeLog2);
+      prev_page = page;
+    }
+    // Advance to the next page.
+    page = next_page;
+  }
+}
+
+void PageSpace::Sweep() {
   TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "Sweep");
 
-  MutexLocker mld(freelist_[HeapPage::kData].mutex());
-  MutexLocker mle(freelist_[HeapPage::kExecutable].mutex());
-
-  // Sweep all regular sized pages now.
   GCSweeper sweeper;
-  HeapPage* prev_page = NULL;
+  HeapPage* prev_page = nullptr;
   HeapPage* page = pages_;
-  while (page != NULL) {
+  FreeList* freelist = &freelist_[HeapPage::kData];
+  MutexLocker ml(freelist_->mutex());
+  while (page != nullptr) {
     HeapPage* next_page = page->next();
-    bool page_in_use = sweeper.SweepPage(page, &freelist_[page->type()], true);
+    ASSERT(page->type() == HeapPage::kData);
+    bool page_in_use = sweeper.SweepPage(page, freelist, true /*is_locked*/);
     if (page_in_use) {
       prev_page = page;
     } else {
@@ -1244,8 +1237,8 @@
 
 void PageSpace::ConcurrentSweep(Isolate* isolate) {
   // Start the concurrent sweeper task now.
-  GCSweeper::SweepConcurrent(isolate, pages_, pages_tail_,
-                             &freelist_[HeapPage::kData]);
+  GCSweeper::SweepConcurrent(isolate, pages_, pages_tail_, large_pages_,
+                             large_pages_tail_, &freelist_[HeapPage::kData]);
 }
 
 void PageSpace::Compact(Thread* thread) {
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 83ca216..836b2ed 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -275,7 +275,13 @@
 class PageSpace {
  public:
   enum GrowthPolicy { kControlGrowth, kForceGrowth };
-  enum Phase { kDone, kMarking, kAwaitingFinalization, kSweeping };
+  enum Phase {
+    kDone,
+    kMarking,
+    kAwaitingFinalization,
+    kSweepingLarge,
+    kSweepingRegular
+  };
 
   PageSpace(Heap* heap, intptr_t max_capacity_in_words);
   ~PageSpace();
@@ -479,10 +485,19 @@
 
   // Makes bump block walkable; do not call concurrently with mutator.
   void MakeIterable() const;
+
+  void AddPageLocked(HeapPage* page);
+  void AddLargePageLocked(HeapPage* page);
+  void AddExecPageLocked(HeapPage* page);
+  void RemovePageLocked(HeapPage* page, HeapPage* previous_page);
+  void RemoveLargePageLocked(HeapPage* page, HeapPage* previous_page);
+  void RemoveExecPageLocked(HeapPage* page, HeapPage* previous_page);
+
   HeapPage* AllocatePage(HeapPage::PageType type, bool link = true);
-  void FreePage(HeapPage* page, HeapPage* previous_page);
   HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type);
+
   void TruncateLargePage(HeapPage* page, intptr_t new_object_size_in_bytes);
+  void FreePage(HeapPage* page, HeapPage* previous_page);
   void FreeLargePage(HeapPage* page, HeapPage* previous_page);
   void FreePages(HeapPage* pages);
 
@@ -490,7 +505,8 @@
                                  bool finalize,
                                  int64_t pre_wait_for_sweepers,
                                  int64_t pre_safe_point);
-  void BlockingSweep();
+  void SweepLarge();
+  void Sweep();
   void ConcurrentSweep(Isolate* isolate);
   void Compact(Thread* thread);
 
@@ -513,12 +529,13 @@
 
   // Use ExclusivePageIterator for safe access to these.
   mutable Mutex pages_lock_;
-  HeapPage* pages_;
-  HeapPage* pages_tail_;
-  HeapPage* exec_pages_;
-  HeapPage* exec_pages_tail_;
-  HeapPage* large_pages_;
-  HeapPage* image_pages_;
+  HeapPage* pages_ = nullptr;
+  HeapPage* pages_tail_ = nullptr;
+  HeapPage* exec_pages_ = nullptr;
+  HeapPage* exec_pages_tail_ = nullptr;
+  HeapPage* large_pages_ = nullptr;
+  HeapPage* large_pages_tail_ = nullptr;
+  HeapPage* image_pages_ = nullptr;
 
   // A block of memory in a data page, managed by bump allocation. The remainder
   // is kept formatted as a FreeListElement, but is not in any freelist.
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index fa294d9..8f23e7f 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -110,11 +110,15 @@
                         PageSpace* old_space,
                         HeapPage* first,
                         HeapPage* last,
+                        HeapPage* large_first,
+                        HeapPage* large_last,
                         FreeList* freelist)
       : task_isolate_(isolate),
         old_space_(old_space),
         first_(first),
         last_(last),
+        large_first_(large_first),
+        large_last_(large_last),
         freelist_(freelist) {
     ASSERT(task_isolate_ != NULL);
     ASSERT(first_ != NULL);
@@ -123,7 +127,7 @@
     ASSERT(freelist_ != NULL);
     MonitorLocker ml(old_space_->tasks_lock());
     old_space_->set_tasks(old_space_->tasks() + 1);
-    old_space_->set_phase(PageSpace::kSweeping);
+    old_space_->set_phase(PageSpace::kSweepingLarge);
   }
 
   virtual void Run() {
@@ -132,14 +136,42 @@
     ASSERT(result);
     {
       Thread* thread = Thread::Current();
+      ASSERT(thread->BypassSafepoints());  // Or we should be checking in.
       TIMELINE_FUNCTION_GC_DURATION(thread, "ConcurrentSweep");
       GCSweeper sweeper;
 
-      HeapPage* page = first_;
+      HeapPage* page = large_first_;
       HeapPage* prev_page = NULL;
-
       while (page != NULL) {
-        ASSERT(thread->BypassSafepoints());  // Or we should be checking in.
+        HeapPage* next_page;
+        if (page == large_last_) {
+          // Don't access page->next(), which would be a race with mutator
+          // allocating new pages.
+          next_page = NULL;
+        } else {
+          next_page = page->next();
+        }
+        ASSERT(page->type() == HeapPage::kData);
+        const intptr_t words_to_end = sweeper.SweepLargePage(page);
+        if (words_to_end == 0) {
+          old_space_->FreeLargePage(page, prev_page);
+        } else {
+          old_space_->TruncateLargePage(page, words_to_end << kWordSizeLog2);
+          prev_page = page;
+        }
+        page = next_page;
+      }
+
+      {
+        MonitorLocker ml(old_space_->tasks_lock());
+        ASSERT(old_space_->phase() == PageSpace::kSweepingLarge);
+        old_space_->set_phase(PageSpace::kSweepingRegular);
+        ml.NotifyAll();
+      }
+
+      page = first_;
+      prev_page = NULL;
+      while (page != NULL) {
         HeapPage* next_page;
         if (page == last_) {
           // Don't access page->next(), which would be a race with mutator
@@ -170,7 +202,7 @@
     {
       MonitorLocker ml(old_space_->tasks_lock());
       old_space_->set_tasks(old_space_->tasks() - 1);
-      ASSERT(old_space_->phase() == PageSpace::kSweeping);
+      ASSERT(old_space_->phase() == PageSpace::kSweepingRegular);
       old_space_->set_phase(PageSpace::kDone);
       ml.NotifyAll();
     }
@@ -181,15 +213,20 @@
   PageSpace* old_space_;
   HeapPage* first_;
   HeapPage* last_;
+  HeapPage* large_first_;
+  HeapPage* large_last_;
   FreeList* freelist_;
 };
 
 void GCSweeper::SweepConcurrent(Isolate* isolate,
                                 HeapPage* first,
                                 HeapPage* last,
+                                HeapPage* large_first,
+                                HeapPage* large_last,
                                 FreeList* freelist) {
   bool result = Dart::thread_pool()->Run<ConcurrentSweeperTask>(
-      isolate, isolate->heap()->old_space(), first, last, freelist);
+      isolate, isolate->heap()->old_space(), first, last, large_first,
+      large_last, freelist);
   ASSERT(result);
 }
 
diff --git a/runtime/vm/heap/sweeper.h b/runtime/vm/heap/sweeper.h
index 609b962..068a30d 100644
--- a/runtime/vm/heap/sweeper.h
+++ b/runtime/vm/heap/sweeper.h
@@ -38,6 +38,8 @@
   static void SweepConcurrent(Isolate* isolate,
                               HeapPage* first,
                               HeapPage* last,
+                              HeapPage* large_first,
+                              HeapPage* large_last,
                               FreeList* freelist);
 };
 
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index b1ce06c..7f2b3fb 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -5,7 +5,6 @@
 #include <setjmp.h>  // NOLINT
 #include <stdlib.h>
 
-#include "vm/compiler/ffi.h"
 #include "vm/globals.h"
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -14,6 +13,7 @@
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/ffi/abi.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/cpu.h"
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 7bb5bf4..0faf778 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -3369,8 +3369,7 @@
 
   String& func_name = String::Handle();
   func_name = func.name();
-  func_name = String::ScrubName(func_name);
-  function_name_ = NewConstChar(func_name.ToCString());
+  function_name_ = NewConstChar(String::ScrubName(func_name));
   if (!cls.IsTopLevel()) {
     const String& class_name = String::Handle(cls.Name());
     class_name_ = NewConstChar(class_name.ToCString());
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 86d0d43..1fb811b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -187,31 +187,11 @@
 
 const double MegamorphicCache::kLoadFactor = 0.50;
 
-static void AppendSubString(Zone* zone,
-                            GrowableArray<const char*>* segments,
+static void AppendSubString(ZoneTextBuffer* buffer,
                             const char* name,
                             intptr_t start_pos,
                             intptr_t len) {
-  char* segment = zone->Alloc<char>(len + 1);  // '\0'-terminated.
-  memmove(segment, name + start_pos, len);
-  segment[len] = '\0';
-  segments->Add(segment);
-}
-
-static const char* MergeSubStrings(Zone* zone,
-                                   const GrowableArray<const char*>& segments,
-                                   intptr_t alloc_len) {
-  char* result = zone->Alloc<char>(alloc_len + 1);  // '\0'-terminated
-  intptr_t pos = 0;
-  for (intptr_t k = 0; k < segments.length(); k++) {
-    const char* piece = segments[k];
-    const intptr_t piece_len = strlen(segments[k]);
-    memmove(result + pos, piece, piece_len);
-    pos += piece_len;
-    ASSERT(pos <= alloc_len);
-  }
-  result[pos] = '\0';
-  return result;
+  buffer->Printf("%.*s", static_cast<int>(len), &name[start_pos]);
 }
 
 // Remove private keys, but retain getter/setter/constructor/mixin manglings.
@@ -269,14 +249,16 @@
 //   get:ext|sprop -> ext.sprop (static extension getter)
 //   set:ext|sprop -> ext.sprop= (static extension setter)
 //
-RawString* String::ScrubName(const String& name, bool is_extension) {
+const char* String::ScrubName(const String& name, bool is_extension) {
   Thread* thread = Thread::Current();
+  NoSafepointScope no_safepoint(thread);
   Zone* zone = thread->zone();
+  ZoneTextBuffer printer(zone);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (name.Equals(Symbols::TopLevel())) {
     // Name of invisible top-level class.
-    return Symbols::Empty().raw();
+    return "";
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -286,7 +268,6 @@
   // First remove all private name mangling and if 'is_extension' is true
   // substitute the first '|' character with '.'.
   intptr_t start_pos = 0;
-  GrowableArray<const char*> unmangled_segments;
   intptr_t sum_segment_len = 0;
   for (intptr_t i = 0; i < name_len; i++) {
     if ((cname[i] == '@') && ((i + 1) < name_len) && (cname[i + 1] >= '0') &&
@@ -294,7 +275,7 @@
       // Append the current segment to the unmangled name.
       const intptr_t segment_len = i - start_pos;
       sum_segment_len += segment_len;
-      AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len);
+      AppendSubString(&printer, cname, start_pos, segment_len);
       // Advance until past the name mangling. The private keys are only
       // numbers so we skip until the first non-number.
       i++;  // Skip the '@'.
@@ -307,9 +288,9 @@
     } else if (is_extension && cname[i] == '|') {
       // Append the current segment to the unmangled name.
       const intptr_t segment_len = i - start_pos;
-      AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len);
+      AppendSubString(&printer, cname, start_pos, segment_len);
       // Append the '.' character (replaces '|' with '.').
-      AppendSubString(zone, &unmangled_segments, ".", 0, 1);
+      AppendSubString(&printer, ".", 0, 1);
       start_pos = i + 1;
       // Account for length of segments added so far.
       sum_segment_len += (segment_len + 1);
@@ -325,14 +306,14 @@
     // Append the last segment.
     const intptr_t segment_len = name.Length() - start_pos;
     sum_segment_len += segment_len;
-    AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len);
+    AppendSubString(&printer, cname, start_pos, segment_len);
   }
   if (unmangled_name == NULL) {
     // Merge unmangled_segments.
-    unmangled_name = MergeSubStrings(zone, unmangled_segments, sum_segment_len);
+    unmangled_name = printer.buffer();
   }
 
-  unmangled_segments.Clear();
+  printer.Clear();
   intptr_t start = 0;
   intptr_t final_len = 0;
   intptr_t len = sum_segment_len;
@@ -343,7 +324,7 @@
       if (unmangled_name[i] == '.') {
         intptr_t slen = i + 1;
         intptr_t plen = slen - start;
-        AppendSubString(zone, &unmangled_segments, unmangled_name, start, plen);
+        AppendSubString(&printer, unmangled_name, start, plen);
         final_len = plen;
         unmangled_name += slen;
         len -= slen;
@@ -393,7 +374,7 @@
 
   if (!is_extension && (start == 0) && (dot_pos == -1)) {
     // This unmangled_name is fine as it is.
-    return Symbols::New(thread, unmangled_name, sum_segment_len);
+    return unmangled_name;
   }
 
   // Drop the trailing dot if needed.
@@ -401,17 +382,15 @@
 
   intptr_t substr_len = end - start;
   final_len += substr_len;
-  AppendSubString(zone, &unmangled_segments, unmangled_name, start, substr_len);
+  AppendSubString(&printer, unmangled_name, start, substr_len);
   if (is_setter) {
     const char* equals = Symbols::Equals().ToCString();
     const intptr_t equals_len = strlen(equals);
-    AppendSubString(zone, &unmangled_segments, equals, 0, equals_len);
+    AppendSubString(&printer, equals, 0, equals_len);
     final_len += equals_len;
   }
 
-  unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len);
-
-  return Symbols::New(thread, unmangled_name);
+  return printer.buffer();
 }
 
 RawString* String::ScrubNameRetainPrivate(const String& name,
@@ -1678,6 +1657,10 @@
     type.SetIsFinalized();
     type ^= type.Canonicalize();
     object_store->set_array_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_array_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_array_type(type);
 
     cls = object_store->growable_object_array_class();  // Was allocated above.
     RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib);
@@ -1766,6 +1749,10 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_object_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_object_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_object_type(type);
 
     cls = Class::New<Bool>(isolate);
     object_store->set_bool_class(cls);
@@ -1989,12 +1976,20 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_function_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_function_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_function_type(type);
 
     cls = Class::New<Number>(isolate);
     RegisterClass(cls, Symbols::Number(), core_lib);
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_number_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_number_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_number_type(type);
 
     cls = Class::New<Instance>(kIllegalCid, isolate, /*register_class=*/true,
                                /*is_abstract=*/true);
@@ -2004,6 +1999,10 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_int_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_int_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_int_type(type);
 
     cls = Class::New<Instance>(kIllegalCid, isolate, /*register_class=*/true,
                                /*is_abstract=*/true);
@@ -2013,6 +2012,10 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_double_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_double_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_double_type(type);
 
     name = Symbols::_String().raw();
     cls = Class::New<Instance>(kIllegalCid, isolate, /*register_class=*/true,
@@ -2023,18 +2026,34 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_string_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_string_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_string_type(type);
 
     cls = object_store->bool_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_bool_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_bool_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_bool_type(type);
 
     cls = object_store->smi_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_smi_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_smi_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_smi_type(type);
 
     cls = object_store->mint_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_mint_type(type);
+    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
+    object_store->set_legacy_mint_type(type);
+    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
+    object_store->set_non_nullable_mint_type(type);
 
     // The classes 'void' and 'dynamic' are phony classes to make type checking
     // more regular; they live in the VM isolate. The class 'void' is not
@@ -2061,18 +2080,48 @@
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_int(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->legacy_int_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_legacy_int(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->non_nullable_int_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_non_nullable_int(type_args);
 
     type_args = TypeArguments::New(1);
     type = object_store->double_type();
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_double(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->legacy_double_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_legacy_double(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->non_nullable_double_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_non_nullable_double(type_args);
 
     type_args = TypeArguments::New(1);
     type = object_store->string_type();
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_string(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->legacy_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_legacy_string(type_args);
+    type_args = TypeArguments::New(1);
+    type = object_store->non_nullable_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_non_nullable_string(type_args);
 
     type_args = TypeArguments::New(2);
     type = object_store->string_type();
@@ -2080,6 +2129,18 @@
     type_args.SetTypeAt(1, Object::dynamic_type());
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_string_dynamic(type_args);
+    type_args = TypeArguments::New(2);
+    type = object_store->legacy_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args.SetTypeAt(1, Object::dynamic_type());
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_legacy_string_dynamic(type_args);
+    type_args = TypeArguments::New(2);
+    type = object_store->non_nullable_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args.SetTypeAt(1, Object::dynamic_type());
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_non_nullable_string_dynamic(type_args);
 
     type_args = TypeArguments::New(2);
     type = object_store->string_type();
@@ -2087,6 +2148,19 @@
     type_args.SetTypeAt(1, type);
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_string_string(type_args);
+    type_args = TypeArguments::New(2);
+    type = object_store->legacy_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args.SetTypeAt(1, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_legacy_string_legacy_string(type_args);
+    type_args = TypeArguments::New(2);
+    type = object_store->non_nullable_string_type();
+    type_args.SetTypeAt(0, type);
+    type_args.SetTypeAt(1, type);
+    type_args = type_args.Canonicalize();
+    object_store->set_type_argument_non_nullable_string_non_nullable_string(
+        type_args);
 
     lib = Library::LookupLibrary(thread, Symbols::DartFfi());
     if (lib.IsNull()) {
@@ -2517,6 +2591,10 @@
 }
 
 RawString* Class::ScrubbedName() const {
+  return Symbols::New(Thread::Current(), ScrubbedNameCString());
+}
+
+const char* Class::ScrubbedNameCString() const {
   return String::ScrubName(String::Handle(Name()));
 }
 
@@ -2524,6 +2602,15 @@
 #if !defined(PRODUCT)
   ASSERT(raw_ptr()->user_name_ != String::null());
   return raw_ptr()->user_name_;
+#endif  // !defined(PRODUCT)
+  // No caching in PRODUCT, regenerate.
+  return Symbols::New(Thread::Current(), GenerateUserVisibleName());
+}
+
+const char* Class::UserVisibleNameCString() const {
+#if !defined(PRODUCT)
+  ASSERT(raw_ptr()->user_name_ != String::null());
+  return String::Handle(raw_ptr()->user_name_).ToCString();
 #endif                               // !defined(PRODUCT)
   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate.
 }
@@ -4129,7 +4216,8 @@
     // TODO(johnmccutchan): Eagerly set user name for VM isolate classes,
     // lazily set user name for the other classes.
     // Generate and set user_name.
-    const String& user_name = String::Handle(GenerateUserVisibleName());
+    const String& user_name = String::Handle(
+        Symbols::New(Thread::Current(), GenerateUserVisibleName()));
     set_user_name(user_name);
   }
 #endif  // !defined(PRODUCT)
@@ -4141,164 +4229,164 @@
 }
 #endif  // !defined(PRODUCT)
 
-RawString* Class::GenerateUserVisibleName() const {
+const char* Class::GenerateUserVisibleName() const {
   if (FLAG_show_internal_names) {
-    return Name();
+    return String::Handle(Name()).ToCString();
   }
   switch (id()) {
     case kFloat32x4Cid:
-      return Symbols::Float32x4().raw();
+      return Symbols::Float32x4().ToCString();
     case kInt32x4Cid:
-      return Symbols::Int32x4().raw();
+      return Symbols::Int32x4().ToCString();
     case kTypedDataInt8ArrayCid:
     case kExternalTypedDataInt8ArrayCid:
-      return Symbols::Int8List().raw();
+      return Symbols::Int8List().ToCString();
     case kTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ArrayCid:
-      return Symbols::Uint8List().raw();
+      return Symbols::Uint8List().ToCString();
     case kTypedDataUint8ClampedArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
-      return Symbols::Uint8ClampedList().raw();
+      return Symbols::Uint8ClampedList().ToCString();
     case kTypedDataInt16ArrayCid:
     case kExternalTypedDataInt16ArrayCid:
-      return Symbols::Int16List().raw();
+      return Symbols::Int16List().ToCString();
     case kTypedDataUint16ArrayCid:
     case kExternalTypedDataUint16ArrayCid:
-      return Symbols::Uint16List().raw();
+      return Symbols::Uint16List().ToCString();
     case kTypedDataInt32ArrayCid:
     case kExternalTypedDataInt32ArrayCid:
-      return Symbols::Int32List().raw();
+      return Symbols::Int32List().ToCString();
     case kTypedDataUint32ArrayCid:
     case kExternalTypedDataUint32ArrayCid:
-      return Symbols::Uint32List().raw();
+      return Symbols::Uint32List().ToCString();
     case kTypedDataInt64ArrayCid:
     case kExternalTypedDataInt64ArrayCid:
-      return Symbols::Int64List().raw();
+      return Symbols::Int64List().ToCString();
     case kTypedDataUint64ArrayCid:
     case kExternalTypedDataUint64ArrayCid:
-      return Symbols::Uint64List().raw();
+      return Symbols::Uint64List().ToCString();
     case kTypedDataInt32x4ArrayCid:
     case kExternalTypedDataInt32x4ArrayCid:
-      return Symbols::Int32x4List().raw();
+      return Symbols::Int32x4List().ToCString();
     case kTypedDataFloat32x4ArrayCid:
     case kExternalTypedDataFloat32x4ArrayCid:
-      return Symbols::Float32x4List().raw();
+      return Symbols::Float32x4List().ToCString();
     case kTypedDataFloat64x2ArrayCid:
     case kExternalTypedDataFloat64x2ArrayCid:
-      return Symbols::Float64x2List().raw();
+      return Symbols::Float64x2List().ToCString();
     case kTypedDataFloat32ArrayCid:
     case kExternalTypedDataFloat32ArrayCid:
-      return Symbols::Float32List().raw();
+      return Symbols::Float32List().ToCString();
     case kTypedDataFloat64ArrayCid:
     case kExternalTypedDataFloat64ArrayCid:
-      return Symbols::Float64List().raw();
+      return Symbols::Float64List().ToCString();
 
     case kFfiPointerCid:
-      return Symbols::FfiPointer().raw();
+      return Symbols::FfiPointer().ToCString();
     case kFfiDynamicLibraryCid:
-      return Symbols::FfiDynamicLibrary().raw();
+      return Symbols::FfiDynamicLibrary().ToCString();
 
 #if !defined(PRODUCT)
     case kNullCid:
-      return Symbols::Null().raw();
+      return Symbols::Null().ToCString();
     case kDynamicCid:
-      return Symbols::Dynamic().raw();
+      return Symbols::Dynamic().ToCString();
     case kVoidCid:
-      return Symbols::Void().raw();
+      return Symbols::Void().ToCString();
     case kNeverCid:
-      return Symbols::Never().raw();
+      return Symbols::Never().ToCString();
     case kClassCid:
-      return Symbols::Class().raw();
+      return Symbols::Class().ToCString();
     case kTypeArgumentsCid:
-      return Symbols::TypeArguments().raw();
+      return Symbols::TypeArguments().ToCString();
     case kPatchClassCid:
-      return Symbols::PatchClass().raw();
+      return Symbols::PatchClass().ToCString();
     case kFunctionCid:
-      return Symbols::Function().raw();
+      return Symbols::Function().ToCString();
     case kClosureDataCid:
-      return Symbols::ClosureData().raw();
+      return Symbols::ClosureData().ToCString();
     case kSignatureDataCid:
-      return Symbols::SignatureData().raw();
+      return Symbols::SignatureData().ToCString();
     case kRedirectionDataCid:
-      return Symbols::RedirectionData().raw();
+      return Symbols::RedirectionData().ToCString();
     case kFfiTrampolineDataCid:
-      return Symbols::FfiTrampolineData().raw();
+      return Symbols::FfiTrampolineData().ToCString();
     case kFieldCid:
-      return Symbols::Field().raw();
+      return Symbols::Field().ToCString();
     case kScriptCid:
-      return Symbols::Script().raw();
+      return Symbols::Script().ToCString();
     case kLibraryCid:
-      return Symbols::Library().raw();
+      return Symbols::Library().ToCString();
     case kLibraryPrefixCid:
-      return Symbols::LibraryPrefix().raw();
+      return Symbols::LibraryPrefix().ToCString();
     case kNamespaceCid:
-      return Symbols::Namespace().raw();
+      return Symbols::Namespace().ToCString();
     case kKernelProgramInfoCid:
-      return Symbols::KernelProgramInfo().raw();
+      return Symbols::KernelProgramInfo().ToCString();
     case kCodeCid:
-      return Symbols::Code().raw();
+      return Symbols::Code().ToCString();
     case kBytecodeCid:
-      return Symbols::Bytecode().raw();
+      return Symbols::Bytecode().ToCString();
     case kInstructionsCid:
-      return Symbols::Instructions().raw();
+      return Symbols::Instructions().ToCString();
     case kObjectPoolCid:
-      return Symbols::ObjectPool().raw();
+      return Symbols::ObjectPool().ToCString();
     case kCodeSourceMapCid:
-      return Symbols::CodeSourceMap().raw();
+      return Symbols::CodeSourceMap().ToCString();
     case kPcDescriptorsCid:
-      return Symbols::PcDescriptors().raw();
+      return Symbols::PcDescriptors().ToCString();
     case kCompressedStackMapsCid:
-      return Symbols::CompressedStackMaps().raw();
+      return Symbols::CompressedStackMaps().ToCString();
     case kLocalVarDescriptorsCid:
-      return Symbols::LocalVarDescriptors().raw();
+      return Symbols::LocalVarDescriptors().ToCString();
     case kExceptionHandlersCid:
-      return Symbols::ExceptionHandlers().raw();
+      return Symbols::ExceptionHandlers().ToCString();
     case kContextCid:
-      return Symbols::Context().raw();
+      return Symbols::Context().ToCString();
     case kContextScopeCid:
-      return Symbols::ContextScope().raw();
+      return Symbols::ContextScope().ToCString();
     case kParameterTypeCheckCid:
-      return Symbols::ParameterTypeCheck().raw();
+      return Symbols::ParameterTypeCheck().ToCString();
     case kSingleTargetCacheCid:
-      return Symbols::SingleTargetCache().raw();
+      return Symbols::SingleTargetCache().ToCString();
     case kICDataCid:
-      return Symbols::ICData().raw();
+      return Symbols::ICData().ToCString();
     case kMegamorphicCacheCid:
-      return Symbols::MegamorphicCache().raw();
+      return Symbols::MegamorphicCache().ToCString();
     case kSubtypeTestCacheCid:
-      return Symbols::SubtypeTestCache().raw();
+      return Symbols::SubtypeTestCache().ToCString();
     case kApiErrorCid:
-      return Symbols::ApiError().raw();
+      return Symbols::ApiError().ToCString();
     case kLanguageErrorCid:
-      return Symbols::LanguageError().raw();
+      return Symbols::LanguageError().ToCString();
     case kUnhandledExceptionCid:
-      return Symbols::UnhandledException().raw();
+      return Symbols::UnhandledException().ToCString();
     case kUnwindErrorCid:
-      return Symbols::UnwindError().raw();
+      return Symbols::UnwindError().ToCString();
     case kIntegerCid:
     case kSmiCid:
     case kMintCid:
-      return Symbols::Int().raw();
+      return Symbols::Int().ToCString();
     case kDoubleCid:
-      return Symbols::Double().raw();
+      return Symbols::Double().ToCString();
     case kOneByteStringCid:
     case kTwoByteStringCid:
     case kExternalOneByteStringCid:
     case kExternalTwoByteStringCid:
-      return Symbols::_String().raw();
+      return Symbols::_String().ToCString();
     case kArrayCid:
     case kImmutableArrayCid:
     case kGrowableObjectArrayCid:
-      return Symbols::List().raw();
+      return Symbols::List().ToCString();
 #endif  // !defined(PRODUCT)
   }
   String& name = String::Handle(Name());
-  name = String::ScrubName(name);
+  name = Symbols::New(Thread::Current(), String::ScrubName(name));
   if (name.raw() == Symbols::FutureImpl().raw() &&
       library() == Library::AsyncLibrary()) {
-    return Symbols::Future().raw();
+    return Symbols::Future().ToCString();
   }
-  return name.raw();
+  return name.ToCString();
 }
 
 void Class::set_script(const Script& value) const {
@@ -4984,6 +5072,7 @@
 }
 
 const char* Class::ToCString() const {
+  NoSafepointScope no_safepoint;
   const Library& lib = Library::Handle(library());
   const char* library_name = lib.IsNull() ? "" : lib.ToCString();
   const char* patch_prefix = is_patch() ? "Patch " : "";
@@ -5286,32 +5375,38 @@
   return result.raw();
 }
 
-RawString* TypeArguments::SubvectorName(intptr_t from_index,
-                                        intptr_t len,
-                                        NameVisibility name_visibility) const {
+RawString* TypeArguments::Name() const {
   Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  String& name = String::Handle(zone);
-  const intptr_t num_strings =
-      (len == 0) ? 2 : 2 * len + 1;  // "<""T"", ""T"">".
-  GrowableHandlePtrArray<const String> pieces(zone, num_strings);
-  pieces.Add(Symbols::LAngleBracket());
-  AbstractType& type = AbstractType::Handle(zone);
+  ZoneTextBuffer printer(thread->zone());
+  PrintSubvectorName(0, Length(), kInternalName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+RawString* TypeArguments::UserVisibleName() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintSubvectorName(0, Length(), kUserVisibleName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+void TypeArguments::PrintSubvectorName(intptr_t from_index,
+                                       intptr_t len,
+                                       NameVisibility name_visibility,
+                                       ZoneTextBuffer* printer) const {
+  printer->AddString("<");
+  AbstractType& type = AbstractType::Handle();
   for (intptr_t i = 0; i < len; i++) {
     if (from_index + i < Length()) {
       type = TypeAt(from_index + i);
-      name = type.BuildName(name_visibility);
+      type.PrintName(name_visibility, printer);
     } else {
-      name = Symbols::Dynamic().raw();
+      printer->AddString("dynamic");
     }
-    pieces.Add(name);
     if (i < len - 1) {
-      pieces.Add(Symbols::CommaSpace());
+      printer->AddString(", ");
     }
   }
-  pieces.Add(Symbols::RAngleBracket());
-  ASSERT(pieces.length() == num_strings);
-  return Symbols::FromConcatAll(thread, pieces);
+  printer->AddString(">");
 }
 
 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other,
@@ -7439,7 +7534,10 @@
       ASSERT(bound.IsFinalized());
       other_bound = other_type_param.bound();
       ASSERT(other_bound.IsFinalized());
-      if (!bound.Equals(other_bound)) {
+      // TODO(dartbug.com/40259): Treat top types as equivalent and disregard
+      // nullability in weak mode.
+      const bool syntactically = !FLAG_strong_non_nullable_type_checks;
+      if (!bound.IsEquivalent(other_bound, syntactically)) {
         return false;
       }
     }
@@ -7827,11 +7925,24 @@
   }
 }
 
-void Function::BuildSignatureParameters(
-    Thread* thread,
-    Zone* zone,
-    NameVisibility name_visibility,
-    GrowableHandlePtrArray<const String>* pieces) const {
+RawString* Function::Signature() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintSignature(kInternalName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+RawString* Function::UserVisibleSignature() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintSignature(kUserVisibleName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+void Function::PrintSignatureParameters(Thread* thread,
+                                        Zone* zone,
+                                        NameVisibility name_visibility,
+                                        ZoneTextBuffer* printer) const {
   AbstractType& param_type = AbstractType::Handle(zone);
   const intptr_t num_params = NumParameters();
   const intptr_t num_fixed_params = num_fixed_parameters();
@@ -7848,39 +7959,37 @@
   while (i < num_fixed_params) {
     param_type = ParameterTypeAt(i);
     ASSERT(!param_type.IsNull());
-    name = param_type.BuildName(name_visibility);
-    pieces->Add(name);
+    param_type.PrintName(name_visibility, printer);
     if (i != (num_params - 1)) {
-      pieces->Add(Symbols::CommaSpace());
+      printer->AddString(", ");
     }
     i++;
   }
   if (num_opt_params > 0) {
     if (num_opt_pos_params > 0) {
-      pieces->Add(Symbols::LBracket());
+      printer->AddString("[");
     } else {
-      pieces->Add(Symbols::LBrace());
+      printer->AddString("{");
     }
     for (intptr_t i = num_fixed_params; i < num_params; i++) {
       param_type = ParameterTypeAt(i);
       ASSERT(!param_type.IsNull());
-      name = param_type.BuildName(name_visibility);
-      pieces->Add(name);
+      param_type.PrintName(name_visibility, printer);
       // The parameter name of an optional positional parameter does not need
       // to be part of the signature, since it is not used.
       if (num_opt_named_params > 0) {
         name = ParameterNameAt(i);
-        pieces->Add(Symbols::Blank());
-        pieces->Add(name);
+        printer->AddString(" ");
+        printer->AddString(name);
       }
       if (i != (num_params - 1)) {
-        pieces->Add(Symbols::CommaSpace());
+        printer->AddString(", ");
       }
     }
     if (num_opt_pos_params > 0) {
-      pieces->Add(Symbols::RBracket());
+      printer->AddString("]");
     } else {
-      pieces->Add(Symbols::RBrace());
+      printer->AddString("}");
     }
   }
 }
@@ -7922,10 +8031,10 @@
   return result;
 }
 
-RawString* Function::BuildSignature(NameVisibility name_visibility) const {
+void Function::PrintSignature(NameVisibility name_visibility,
+                              ZoneTextBuffer* printer) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  GrowableHandlePtrArray<const String> pieces(zone, 4);
   String& name = String::Handle(zone);
   const TypeArguments& type_params =
       TypeArguments::Handle(zone, type_parameters());
@@ -7934,30 +8043,27 @@
     ASSERT(num_type_params > 0);
     TypeParameter& type_param = TypeParameter::Handle(zone);
     AbstractType& bound = AbstractType::Handle(zone);
-    pieces.Add(Symbols::LAngleBracket());
+    printer->AddString("<");
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       name = type_param.name();
-      pieces.Add(name);
+      printer->AddString(name.ToCString());
       bound = type_param.bound();
       if (!bound.IsNull() && !bound.IsObjectType()) {
-        pieces.Add(Symbols::SpaceExtendsSpace());
-        name = bound.BuildName(name_visibility);
-        pieces.Add(name);
+        printer->AddString(" extends ");
+        bound.PrintName(name_visibility, printer);
       }
       if (i < num_type_params - 1) {
-        pieces.Add(Symbols::CommaSpace());
+        printer->AddString(", ");
       }
     }
-    pieces.Add(Symbols::RAngleBracket());
+    printer->AddString(">");
   }
-  pieces.Add(Symbols::LParen());
-  BuildSignatureParameters(thread, zone, name_visibility, &pieces);
-  pieces.Add(Symbols::RParenArrow());
+  printer->AddString("(");
+  PrintSignatureParameters(thread, zone, name_visibility, printer);
+  printer->AddString(") => ");
   const AbstractType& res_type = AbstractType::Handle(zone, result_type());
-  name = res_type.BuildName(name_visibility);
-  pieces.Add(name);
-  return Symbols::FromConcatAll(thread, pieces);
+  res_type.PrintName(name_visibility, printer);
 }
 
 bool Function::HasInstantiatedSignature(Genericity genericity,
@@ -8157,14 +8263,38 @@
          ForceOptimize();
 }
 
-RawString* Function::UserVisibleName() const {
+const char* Function::UserVisibleNameCString() const {
   if (FLAG_show_internal_names) {
-    return name();
+    return String::Handle(name()).ToCString();
   }
   return String::ScrubName(String::Handle(name()), is_extension_member());
 }
 
-RawString* Function::QualifiedName(NameVisibility name_visibility) const {
+RawString* Function::UserVisibleName() const {
+  if (FLAG_show_internal_names) {
+    return name();
+  }
+  return Symbols::New(
+      Thread::Current(),
+      String::ScrubName(String::Handle(name()), is_extension_member()));
+}
+
+RawString* Function::QualifiedScrubbedName() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintQualifiedName(kScrubbedName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+RawString* Function::QualifiedUserVisibleName() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintQualifiedName(kUserVisibleName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+void Function::PrintQualifiedName(NameVisibility name_visibility,
+                                  ZoneTextBuffer* printer) const {
   ASSERT(name_visibility != kInternalName);  // We never request it.
   // If |this| is the generated asynchronous body closure, use the
   // name of the parent function.
@@ -8180,37 +8310,36 @@
       fun = raw();
     }
   }
-  // A function's scrubbed name and its user visible name are identical.
-  String& result = String::Handle(fun.UserVisibleName());
   if (IsClosureFunction()) {
-    while (fun.IsLocalFunction() && !fun.IsImplicitClosureFunction()) {
-      fun = fun.parent_function();
-      if (fun.IsAsyncClosure() || fun.IsSyncGenClosure() ||
-          fun.IsAsyncGenClosure()) {
+    if (fun.IsLocalFunction() && !fun.IsImplicitClosureFunction()) {
+      Function& parent = Function::Handle(fun.parent_function());
+      if (parent.IsAsyncClosure() || parent.IsSyncGenClosure() ||
+          parent.IsAsyncGenClosure()) {
         // Skip the closure and use the real function name found in
         // the parent.
-        fun = fun.parent_function();
+        parent = parent.parent_function();
       }
-      result = String::Concat(Symbols::Dot(), result, Heap::kOld);
-      result = String::Concat(String::Handle(fun.UserVisibleName()), result,
-                              Heap::kOld);
+      parent.PrintQualifiedName(name_visibility, printer);
+      // A function's scrubbed name and its user visible name are identical.
+      printer->AddString(".");
+      printer->AddString(fun.UserVisibleNameCString());
+      return;
     }
   }
   const Class& cls = Class::Handle(Owner());
   if (!cls.IsTopLevel()) {
     if (fun.kind() == RawFunction::kConstructor) {
-      result = String::Concat(Symbols::ConstructorStacktracePrefix(), result,
-                              Heap::kOld);
+      printer->AddString("new ");
     } else {
       const Class& mixin = Class::Handle(cls.Mixin());
-      result = String::Concat(Symbols::Dot(), result, Heap::kOld);
-      const String& cls_name = String::Handle(name_visibility == kScrubbedName
-                                                  ? cls.ScrubbedName()
-                                                  : mixin.UserVisibleName());
-      result = String::Concat(cls_name, result, Heap::kOld);
+      printer->AddString(name_visibility == kScrubbedName
+                             ? cls.ScrubbedNameCString()
+                             : mixin.UserVisibleNameCString());
+      printer->AddString(".");
     }
   }
-  return result.raw();
+  // A function's scrubbed name and its user visible name are identical.
+  printer->AddString(fun.UserVisibleNameCString());
 }
 
 RawString* Function::GetSource() const {
@@ -8445,6 +8574,7 @@
 }
 
 const char* Function::ToCString() const {
+  NoSafepointScope no_safepoint;
   if (IsNull()) {
     return "Function: null";
   }
@@ -8971,11 +9101,21 @@
   return String::null();
 }
 
+const char* Field::UserVisibleNameCString() const {
+  NoSafepointScope no_safepoint;
+  if (FLAG_show_internal_names) {
+    return String::Handle(name()).ToCString();
+  }
+  return String::ScrubName(String::Handle(name()), is_extension_member());
+}
+
 RawString* Field::UserVisibleName() const {
   if (FLAG_show_internal_names) {
     return name();
   }
-  return String::ScrubName(String::Handle(name()), is_extension_member());
+  return Symbols::New(
+      Thread::Current(),
+      String::ScrubName(String::Handle(name()), is_extension_member()));
 }
 
 intptr_t Field::guarded_list_length() const {
@@ -9037,6 +9177,7 @@
 }
 
 const char* Field::ToCString() const {
+  NoSafepointScope no_safepoint;
   if (IsNull()) {
     return "Field: null";
   }
@@ -12050,6 +12191,7 @@
 }
 
 const char* Library::ToCString() const {
+  NoSafepointScope no_safepoint;
   const String& name = String::Handle(url());
   return OS::SCreate(Thread::Current()->zone(), "Library:'%s'",
                      name.ToCString());
@@ -12344,7 +12486,7 @@
 }
 
 const char* KernelProgramInfo::ToCString() const {
-  return OS::SCreate(Thread::Current()->zone(), "[KernelProgramInfo]");
+  return "[KernelProgramInfo]";
 }
 
 RawScript* KernelProgramInfo::ScriptAt(intptr_t index) const {
@@ -15343,11 +15485,10 @@
   Zone* zone = Thread::Current()->zone();
   const Object& obj = Object::Handle(zone, owner());
   if (obj.IsFunction()) {
-    const char* opt = is_optimized() ? "[Optimized]" : "[Unoptimized]";
-    const char* function_name =
-        String::Handle(zone, Function::Cast(obj).QualifiedUserVisibleName())
-            .ToCString();
-    return zone->PrintToString("%s %s", opt, function_name);
+    ZoneTextBuffer printer(zone);
+    printer.AddString(is_optimized() ? "[Optimized] " : "[Unoptimized] ");
+    Function::Cast(obj).PrintQualifiedName(kUserVisibleName, &printer);
+    return printer.buffer();
   }
   return Name();
 }
@@ -17662,33 +17803,47 @@
   return Symbols::FromConcatAll(thread, pieces);
 }
 
-static const String& NullabilitySuffix(Nullability value) {
+static const char* NullabilitySuffix(Nullability value) {
   // Keep in sync with Nullability enum in runtime/vm/object.h.
   switch (value) {
     case Nullability::kUndetermined:
-      return Symbols::Percent();
+      return "%";
     case Nullability::kNullable:
-      return Symbols::QuestionMark();
+      return "?";
     case Nullability::kNonNullable:
-      return Symbols::Empty();
+      return "";
     case Nullability::kLegacy:
-      return Symbols::Star();
+      return "*";
     default:
       UNREACHABLE();
   }
 }
 
-RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
+RawString* AbstractType::Name() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintName(kInternalName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+RawString* AbstractType::UserVisibleName() const {
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  PrintName(kUserVisibleName, &printer);
+  return Symbols::New(thread, printer.buffer());
+}
+
+void AbstractType::PrintName(NameVisibility name_visibility,
+                             ZoneTextBuffer* printer) const {
   ASSERT(name_visibility != kScrubbedName);
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   if (IsTypeParameter()) {
+    printer->AddString(String::Handle(zone, TypeParameter::Cast(*this).name()));
     if (FLAG_show_nullability) {
-      return Symbols::FromConcat(
-          thread, String::Handle(zone, TypeParameter::Cast(*this).name()),
-          NullabilitySuffix(nullability()));
+      printer->AddString(NullabilitySuffix(nullability()));
     }
-    return TypeParameter::Cast(*this).name();
+    return;
   }
   const TypeArguments& args = TypeArguments::Handle(zone, arguments());
   const intptr_t num_args = args.IsNull() ? 0 : args.Length();
@@ -17700,25 +17855,22 @@
     const Function& signature_function =
         Function::Handle(zone, Type::Cast(*this).signature());
     if (!cls.IsTypedefClass()) {
+      signature_function.PrintSignature(kUserVisibleName, printer);
       if (FLAG_show_nullability) {
-        return Symbols::FromConcat(
-            thread,
-            String::Handle(zone, signature_function.UserVisibleSignature()),
-            NullabilitySuffix(nullability()));
+        printer->AddString(NullabilitySuffix(nullability()));
       }
-      return signature_function.UserVisibleSignature();
+      return;
     }
     // Instead of printing the actual signature, use the typedef name with
     // its type arguments, if any.
     class_name = cls.Name();  // Typedef name.
     if (!IsFinalized() || IsBeingFinalized()) {
       // TODO(regis): Check if this is dead code.
+      printer->AddString(class_name);
       if (FLAG_show_nullability) {
-        return Symbols::FromConcat(thread,
-                                   String::Handle(zone, class_name.raw()),
-                                   NullabilitySuffix(nullability()));
+        printer->AddString(NullabilitySuffix(nullability()));
       }
-      return class_name.raw();
+      return;
     }
     // Print the name of a typedef as a regular, possibly parameterized, class.
   }
@@ -17726,10 +17878,11 @@
   num_type_params = cls.NumTypeParameters();
   if (name_visibility == kInternalName) {
     class_name = cls.Name();
+    printer->AddString(class_name);
   } else {
     ASSERT(name_visibility == kUserVisibleName);
     // Map internal types to their corresponding public interfaces.
-    class_name = cls.UserVisibleName();
+    printer->AddString(cls.UserVisibleNameCString());
   }
   if (num_type_params > num_args) {
     first_type_param_index = 0;
@@ -17748,23 +17901,18 @@
       first_type_param_index = num_args - num_type_params;
     }
   }
-  GrowableHandlePtrArray<const String> pieces(zone, 4);
-  pieces.Add(class_name);
   if (num_type_params == 0) {
     // Do nothing.
   } else {
-    const String& args_name = String::Handle(
-        zone, args.SubvectorName(first_type_param_index, num_type_params,
-                                 name_visibility));
-    pieces.Add(args_name);
+    args.PrintSubvectorName(first_type_param_index, num_type_params,
+                            name_visibility, printer);
   }
   if (FLAG_show_nullability) {
-    pieces.Add(NullabilitySuffix(nullability()));
+    printer->AddString(NullabilitySuffix(nullability()));
   }
   // The name is only used for type checking and debugging purposes.
   // Unless profiling data shows otherwise, it is not worth caching the name in
   // the type.
-  return Symbols::FromConcatAll(thread, pieces);
 }
 
 RawString* AbstractType::ClassName() const {
@@ -18841,13 +18989,14 @@
   class_name = name.IsNull() ? "<null>" : name.ToCString();
   if (IsFunctionType()) {
     const Function& sig_fun = Function::Handle(zone, signature());
-    const String& sig = String::Handle(zone, sig_fun.Signature());
+    ZoneTextBuffer sig(zone);
+    sig_fun.PrintSignature(kInternalName, &sig);
     if (cls.IsClosureClass()) {
       ASSERT(type_args.IsNull());
-      return OS::SCreate(zone, "Function Type: %s", sig.ToCString());
+      return OS::SCreate(zone, "Function Type: %s", sig.buffer());
     }
     return OS::SCreate(zone, "Function Type: %s (class: %s, args: %s)",
-                       sig.ToCString(), class_name, args_cstr);
+                       sig.buffer(), class_name, args_cstr);
   }
   if (type_args.IsNull()) {
     return OS::SCreate(zone, "Type: class '%s'", class_name);
@@ -19002,13 +19151,14 @@
   if (ref_type.IsNull()) {
     return "TypeRef: null";
   }
-  const char* type_cstr = String::Handle(zone, ref_type.Name()).ToCString();
+  ZoneTextBuffer printer(zone);
+  printer.AddString("TypeRef: ");
+  ref_type.PrintName(kInternalName, &printer);
   if (ref_type.IsFinalized()) {
     const intptr_t hash = ref_type.Hash();
-    return OS::SCreate(zone, "TypeRef: %s (H%" Px ")", type_cstr, hash);
-  } else {
-    return OS::SCreate(zone, "TypeRef: %s", type_cstr);
+    printer.Printf(" (H%" Px ")", hash);
   }
+  return printer.buffer();
 }
 
 void TypeParameter::SetIsFinalized() const {
@@ -19264,37 +19414,28 @@
 }
 
 const char* TypeParameter::ToCString() const {
-  const char* name_cstr = String::Handle(Name()).ToCString();
-  const AbstractType& upper_bound = AbstractType::Handle(bound());
-  const char* bound_cstr = upper_bound.IsNull()
-                               ? "<null>"
-                               : String::Handle(upper_bound.Name()).ToCString();
+  Thread* thread = Thread::Current();
+  ZoneTextBuffer printer(thread->zone());
+  printer.Printf("TypeParameter: name ");
+  printer.AddString(String::Handle(Name()));
+  printer.Printf("; index: %" Pd ";", index());
   if (IsFunctionTypeParameter()) {
-    const char* format =
-        "TypeParameter: name %s; index: %d; function: %s; bound: %s";
     const Function& function = Function::Handle(parameterized_function());
-    const char* fun_cstr = String::Handle(function.name()).ToCString();
-    intptr_t len = Utils::SNPrint(NULL, 0, format, name_cstr, index(), fun_cstr,
-                                  bound_cstr) +
-                   1;
-    char* chars = Thread::Current()->zone()->Alloc<char>(len);
-    Utils::SNPrint(chars, len, format, name_cstr, index(), fun_cstr,
-                   bound_cstr);
-    return chars;
+    printer.Printf(" function: ");
+    printer.AddString(String::Handle(function.name()));
   } else {
-    const char* format =
-        "TypeParameter: name %s; index: %d; class: %s; bound: %s";
     const Class& cls = Class::Handle(parameterized_class());
-    const char* cls_cstr =
-        cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString();
-    intptr_t len = Utils::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr,
-                                  bound_cstr) +
-                   1;
-    char* chars = Thread::Current()->zone()->Alloc<char>(len);
-    Utils::SNPrint(chars, len, format, name_cstr, index(), cls_cstr,
-                   bound_cstr);
-    return chars;
+    printer.Printf(" class: ");
+    printer.AddString(String::Handle(cls.Name()));
   }
+  printer.Printf("; bound: ");
+  const AbstractType& upper_bound = AbstractType::Handle(bound());
+  if (upper_bound.IsNull()) {
+    printer.AddString("<null>");
+  } else {
+    upper_bound.PrintName(kInternalName, &printer);
+  }
+  return printer.buffer();
 }
 
 RawInstance* Number::CheckAndCanonicalize(Thread* thread,
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 10cdbf0..2759213 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -70,6 +70,7 @@
 #undef REUSABLE_FORWARD_DECLARATION
 
 class Symbols;
+class ZoneTextBuffer;
 
 #if defined(DEBUG)
 #define CHECK_HANDLE() CheckHandle();
@@ -931,7 +932,9 @@
 
   RawString* Name() const;
   RawString* ScrubbedName() const;
+  const char* ScrubbedNameCString() const;
   RawString* UserVisibleName() const;
+  const char* UserVisibleNameCString() const;
 
   // The mixin for this class if one exists. Otherwise, returns a raw pointer
   // to this class.
@@ -1526,7 +1529,7 @@
 
   void set_name(const String& value) const;
   void set_user_name(const String& value) const;
-  RawString* GenerateUserVisibleName() const;
+  const char* GenerateUserVisibleName() const;
   void set_state_bits(intptr_t bits) const;
 
   RawArray* invocation_dispatcher_cache() const;
@@ -2238,12 +2241,13 @@
  public:
   RawString* name() const { return raw_ptr()->name_; }
   RawString* UserVisibleName() const;  // Same as scrubbed name.
-  RawString* QualifiedScrubbedName() const {
-    return QualifiedName(kScrubbedName);
-  }
-  RawString* QualifiedUserVisibleName() const {
-    return QualifiedName(kUserVisibleName);
-  }
+  const char* UserVisibleNameCString() const;
+
+  void PrintQualifiedName(NameVisibility name_visibility,
+                          ZoneTextBuffer* printer) const;
+  RawString* QualifiedScrubbedName() const;
+  RawString* QualifiedUserVisibleName() const;
+
   virtual RawString* DictionaryName() const { return name(); }
 
   RawString* GetSource() const;
@@ -2303,16 +2307,17 @@
   // internal signature of the given function. In this example, T is a type
   // parameter of this function and R is a type parameter of class C, the owner
   // of the function. B and C are not type parameters.
-  RawString* Signature() const { return BuildSignature(kInternalName); }
+  RawString* Signature() const;
 
   // Build a string of the form '<T>(T, {B b, C c}) => R' representing the
   // user visible signature of the given function. In this example, T is a type
   // parameter of this function and R is a type parameter of class C, the owner
   // of the function. B and C are not type parameters.
   // Implicit parameters are hidden.
-  RawString* UserVisibleSignature() const {
-    return BuildSignature(kUserVisibleName);
-  }
+  RawString* UserVisibleSignature() const;
+
+  void PrintSignature(NameVisibility name_visibility,
+                      ZoneTextBuffer* printer) const;
 
   // Returns true if the signature of this function is instantiated, i.e. if it
   // does not involve generic parameter types or generic result type.
@@ -3333,14 +3338,10 @@
   void set_data(const Object& value) const;
   static RawFunction* New(Heap::Space space = Heap::kOld);
 
-  RawString* QualifiedName(NameVisibility name_visibility) const;
-
-  void BuildSignatureParameters(
-      Thread* thread,
-      Zone* zone,
-      NameVisibility name_visibility,
-      GrowableHandlePtrArray<const String>* pieces) const;
-  RawString* BuildSignature(NameVisibility name_visibility) const;
+  void PrintSignatureParameters(Thread* thread,
+                                Zone* zone,
+                                NameVisibility name_visibility,
+                                ZoneTextBuffer* printer) const;
 
   // Returns true if the type of the formal parameter at the given position in
   // this function is contravariant with the type of the other formal parameter
@@ -3507,6 +3508,7 @@
 
   RawString* name() const { return raw_ptr()->name_; }
   RawString* UserVisibleName() const;  // Same as scrubbed name.
+  const char* UserVisibleNameCString() const;
   virtual RawString* DictionaryName() const { return name(); }
 
   bool is_static() const { return StaticBit::decode(raw_ptr()->kind_bits_); }
@@ -6818,13 +6820,11 @@
   };
 
   // The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>".
-  RawString* Name() const { return SubvectorName(0, Length(), kInternalName); }
+  RawString* Name() const;
 
   // The name of this type argument vector, e.g. "<T, dynamic, List<T>, int>".
   // Names of internal classes are mapped to their public interfaces.
-  RawString* UserVisibleName() const {
-    return SubvectorName(0, Length(), kUserVisibleName);
-  }
+  RawString* UserVisibleName() const;
 
   // Check if the subvector of length 'len' starting at 'from_index' of this
   // type argument vector consists solely of DynamicType.
@@ -7004,9 +7004,10 @@
 
   // Return the internal or public name of a subvector of this type argument
   // vector, e.g. "<T, dynamic, List<T>, int>".
-  RawString* SubvectorName(intptr_t from_index,
-                           intptr_t len,
-                           NameVisibility name_visibility) const;
+  void PrintSubvectorName(intptr_t from_index,
+                          intptr_t len,
+                          NameVisibility name_visibility,
+                          ZoneTextBuffer* printer) const;
 
   RawArray* instantiations() const;
   void set_instantiations(const Array& value) const;
@@ -7139,13 +7140,15 @@
   static RawString* PrintURIs(URIs* uris);
 
   // The name of this type, including the names of its type arguments, if any.
-  virtual RawString* Name() const { return BuildName(kInternalName); }
+  virtual RawString* Name() const;
 
   // The name of this type, including the names of its type arguments, if any.
   // Names of internal classes are mapped to their public interfaces.
-  virtual RawString* UserVisibleName() const {
-    return BuildName(kUserVisibleName);
-  }
+  virtual RawString* UserVisibleName() const;
+
+  // Return the internal or public name of this type, including the names of its
+  // type arguments, if any.
+  void PrintName(NameVisibility visibility, ZoneTextBuffer* printer) const;
 
   // Add the class name and URI of each occuring type to the uris
   // list and mark ambiguous triplets to be printed.
@@ -7261,10 +7264,6 @@
                            const AbstractType& other,
                            Heap::Space space) const;
 
-  // Return the internal or public name of this type, including the names of its
-  // type arguments, if any.
-  RawString* BuildName(NameVisibility visibility) const;
-
  protected:
   HEAP_OBJECT_IMPLEMENTATION(AbstractType, Instance);
   friend class Class;
@@ -8147,7 +8146,7 @@
 
   static RawString* RemovePrivateKey(const String& name);
 
-  static RawString* ScrubName(const String& name, bool is_extension = false);
+  static const char* ScrubName(const String& name, bool is_extension = false);
   static RawString* ScrubNameRetainPrivate(const String& name,
                                            bool is_extension = false);
 
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index f889268..cf6b22f 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -285,9 +285,9 @@
   JSONObject jsobj(stream);
   AddCommonObjectProperties(&jsobj, "Function", ref);
   AddFunctionServiceId(jsobj, *this, cls);
-  const String& user_name = String::Handle(UserVisibleName());
+  const char* user_name = UserVisibleNameCString();
   const String& vm_name = String::Handle(name());
-  AddNameProperties(&jsobj, user_name.ToCString(), vm_name.ToCString());
+  AddNameProperties(&jsobj, user_name, vm_name.ToCString());
   const Function& parent = Function::Handle(parent_function());
   if (!parent.IsNull()) {
     jsobj.AddProperty("owner", parent);
@@ -367,9 +367,9 @@
   jsobj.AddFixedServiceId("classes/%" Pd "/fields/%s", cls.id(),
                           encoded_field_name);
 
-  const String& user_name = String::Handle(UserVisibleName());
+  const char* user_name = UserVisibleNameCString();
   const String& vm_name = String::Handle(name());
-  AddNameProperties(&jsobj, user_name.ToCString(), vm_name.ToCString());
+  AddNameProperties(&jsobj, user_name, vm_name.ToCString());
   if (cls.IsTopLevel()) {
     const Library& library = Library::Handle(cls.library());
     jsobj.AddProperty("owner", library);
@@ -481,8 +481,8 @@
   AddCommonObjectProperties(&jsobj, "Library", ref);
   jsobj.AddFixedServiceId("libraries/%s", id.ToCString());
   const String& vm_name = String::Handle(name());
-  const String& scrubbed_name = String::Handle(String::ScrubName(vm_name));
-  AddNameProperties(&jsobj, scrubbed_name.ToCString(), vm_name.ToCString());
+  const char* scrubbed_name = String::ScrubName(vm_name);
+  AddNameProperties(&jsobj, scrubbed_name, vm_name.ToCString());
   const String& library_url = String::Handle(url());
   jsobj.AddPropertyStr("uri", library_url);
   if (ref) {
@@ -1427,8 +1427,8 @@
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
   const Class& cls = Class::Handle(clazz());
-  const String& kind = String::Handle(cls.UserVisibleName());
-  jsobj.AddProperty("kind", kind.ToCString());
+  const char* kind = cls.UserVisibleNameCString();
+  jsobj.AddProperty("kind", kind);
   jsobj.AddServiceId(*this);
   jsobj.AddProperty("length", Length());
   if (ref) {
@@ -1462,8 +1462,8 @@
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
   const Class& cls = Class::Handle(clazz());
-  const String& kind = String::Handle(cls.UserVisibleName());
-  jsobj.AddProperty("kind", kind.ToCString());
+  const char* kind = cls.UserVisibleNameCString();
+  jsobj.AddProperty("kind", kind);
   jsobj.AddServiceId(*this);
   jsobj.AddProperty("length", Length());
   if (ref) {
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 0c5149b..933b3a7 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -31,33 +31,62 @@
   M(VMService, _vmservice)                                                     \
   M(Wasm, wasm)
 
+// TODO(liama): Once NNBD is enabled, *_type will be deleted and all uses will
+// be replaced with *_type_non_nullable. Later, once we drop support for opted
+// out code, *_type_legacy will be deleted.
 #define OBJECT_STORE_FIELD_LIST(R_, RW)                                        \
   RW(Class, object_class)                                                      \
   RW(Type, object_type)                                                        \
+  RW(Type, legacy_object_type)                                                 \
+  RW(Type, non_nullable_object_type)                                           \
   RW(Class, null_class)                                                        \
   RW(Type, null_type)                                                          \
   RW(Type, function_type)                                                      \
+  RW(Type, legacy_function_type)                                               \
+  RW(Type, non_nullable_function_type)                                         \
   RW(Type, type_type)                                                          \
   RW(Class, closure_class)                                                     \
   RW(Type, number_type)                                                        \
+  RW(Type, legacy_number_type)                                                 \
+  RW(Type, non_nullable_number_type)                                           \
   RW(Type, int_type)                                                           \
+  RW(Type, legacy_int_type)                                                    \
+  RW(Type, non_nullable_int_type)                                              \
   RW(Class, integer_implementation_class)                                      \
   RW(Type, int64_type)                                                         \
   RW(Class, smi_class)                                                         \
   RW(Type, smi_type)                                                           \
+  RW(Type, legacy_smi_type)                                                    \
+  RW(Type, non_nullable_smi_type)                                              \
   RW(Class, mint_class)                                                        \
   RW(Type, mint_type)                                                          \
+  RW(Type, legacy_mint_type)                                                   \
+  RW(Type, non_nullable_mint_type)                                             \
   RW(Class, double_class)                                                      \
   RW(Type, double_type)                                                        \
+  RW(Type, legacy_double_type)                                                 \
+  RW(Type, non_nullable_double_type)                                           \
   RW(Type, float32x4_type)                                                     \
   RW(Type, int32x4_type)                                                       \
   RW(Type, float64x2_type)                                                     \
   RW(Type, string_type)                                                        \
+  RW(Type, legacy_string_type)                                                 \
+  RW(Type, non_nullable_string_type)                                           \
   RW(TypeArguments, type_argument_int)                                         \
+  RW(TypeArguments, type_argument_legacy_int)                                  \
+  RW(TypeArguments, type_argument_non_nullable_int)                            \
   RW(TypeArguments, type_argument_double)                                      \
+  RW(TypeArguments, type_argument_legacy_double)                               \
+  RW(TypeArguments, type_argument_non_nullable_double)                         \
   RW(TypeArguments, type_argument_string)                                      \
+  RW(TypeArguments, type_argument_legacy_string)                               \
+  RW(TypeArguments, type_argument_non_nullable_string)                         \
   RW(TypeArguments, type_argument_string_dynamic)                              \
+  RW(TypeArguments, type_argument_legacy_string_dynamic)                       \
+  RW(TypeArguments, type_argument_non_nullable_string_dynamic)                 \
   RW(TypeArguments, type_argument_string_string)                               \
+  RW(TypeArguments, type_argument_legacy_string_legacy_string)                 \
+  RW(TypeArguments, type_argument_non_nullable_string_non_nullable_string)     \
   RW(Class, compiletime_error_class)                                           \
   RW(Class, pragma_class)                                                      \
   RW(Field, pragma_name)                                                       \
@@ -70,9 +99,13 @@
   RW(Class, external_one_byte_string_class)                                    \
   RW(Class, external_two_byte_string_class)                                    \
   RW(Type, bool_type)                                                          \
+  RW(Type, legacy_bool_type)                                                   \
+  RW(Type, non_nullable_bool_type)                                             \
   RW(Class, bool_class)                                                        \
   RW(Class, array_class)                                                       \
   RW(Type, array_type)                                                         \
+  RW(Type, legacy_array_type)                                                  \
+  RW(Type, non_nullable_array_type)                                            \
   RW(Class, immutable_array_class)                                             \
   RW(Class, growable_object_array_class)                                       \
   RW(Class, linked_hash_map_class)                                             \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index c6decf2..e16b264 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4003,6 +4003,34 @@
   GrowableArray<Object*>* objects_;
 };
 
+ISOLATE_UNIT_TEST_CASE(ToCString) {
+  // Set native resolvers in case we need to read native methods.
+  {
+    TransitionVMToNative transition(thread);
+    bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
+    bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+    bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
+    bin::VmService::SetNativeResolver();
+  }
+
+  GCTestHelper::CollectAllGarbage();
+  GrowableArray<Object*> objects;
+  {
+    HeapIterationScope iteration(Thread::Current());
+    ObjectAccumulator acc(&objects);
+    iteration.IterateObjects(&acc);
+  }
+  for (intptr_t i = 0; i < objects.length(); ++i) {
+    StackZone zone(thread);
+    HANDLESCOPE(thread);
+
+    // All ToCString implementations should not allocate on the Dart heap so
+    // they remain useful in all parts of the VM.
+    NoSafepointScope no_safepoint;
+    objects[i]->ToCString();
+  }
+}
+
 ISOLATE_UNIT_TEST_CASE(PrintJSON) {
   // Set native resolvers in case we need to read native methods.
   {
@@ -4544,11 +4572,11 @@
       {"_MyClass@6328321.named", "_MyClass.named"},
   };
   String& test = String::Handle();
-  String& result = String::Handle();
+  const char* result;
   for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
     test = String::New(tests[i].in);
     result = String::ScrubName(test);
-    EXPECT_STREQ(tests[i].out, result.ToCString());
+    EXPECT_STREQ(tests[i].out, result);
   }
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 5cb5956..acfaf53 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2607,13 +2607,13 @@
 };
 
 // VM implementations of the basic types in the isolate.
-class RawCapability : public RawInstance {
+class alignas(8) RawCapability : public RawInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Capability);
   VISIT_NOTHING();
   uint64_t id_;
 };
 
-class RawSendPort : public RawInstance {
+class alignas(8) RawSendPort : public RawInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(SendPort);
   VISIT_NOTHING();
   Dart_Port id_;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 02c49f9..df6d240 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2221,6 +2221,7 @@
         intptr_t offset = slot_offset.Value();
         if (offset > 0 && offset < element_field_map.Length()) {
           field ^= element_field_map.At(offset);
+          ASSERT(!field.IsNull());
           // TODO(bkonyi): check for mapping between C++ name and Dart name (V8
           // snapshot writer?)
           name ^= field.name();
@@ -2365,10 +2366,6 @@
 };
 
 static bool Invoke(Thread* thread, JSONStream* js) {
-  if (CheckDebuggerDisabled(thread, js)) {
-    return true;
-  }
-
   const char* receiver_id = js->LookupParam("targetId");
   if (receiver_id == NULL) {
     PrintMissingParamError(js, "targetId");
@@ -2385,10 +2382,12 @@
     return true;
   }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
   bool disable_breakpoints =
       BoolParameter::Parse(js->LookupParam("disableBreakpoints"), false);
   DisableBreakpointsScope db(thread->isolate()->debugger(),
                              disable_breakpoints);
+#endif
 
   Zone* zone = thread->zone();
   ObjectIdRing::LookupResult lookup_result;
diff --git a/runtime/vm/service/feature_availability.md b/runtime/vm/service/feature_availability.md
new file mode 100644
index 0000000..c95350e6
--- /dev/null
+++ b/runtime/vm/service/feature_availability.md
@@ -0,0 +1,25 @@
+# VM Service Feature Availability
+
+This table describe which features of the [VM service protocol](service.md) are available in different modes of the Dart VM. In general, the JIT supports the full set of features, and AOT supports features that do not require code generation or modification. When attempting to use a feature in a mode where it is not supported, the service RPC will return error code 100 ("Feature is disabled").
+
+| Feature                         | Supported Modes                         |
+| ---                             | ---                                     |
+| CPU Profiler                    | All Modes                               |
+| Dart Allocation Site Profiler   | JIT only                                |
+| Malloc Allocation Site Profiler | Debug VM builds only                    |
+| Allocation Table                | All Modes                               |
+| Heap Snapshot                   | All Modes                               |
+| Metrics                         | All Modes                               |
+| Timeline/Tracing                | All Modes                               |
+| Object Inspection               | All Modes                               |
+| Stack Inspection                | JIT only                                |
+| Breakpoints/Pause-on-Exception  | JIT only                                |
+| Stepping                        | JIT only                                |
+| Pausing/Resuming                | JIT only [1]                            |
+| Reload                          | JIT with a compilation server available |
+| Evaluate                        | JIT with a compilation server available |
+| Invoke                          | JIT + AOT [2]                           |
+
+[1] This could be added to AOT without affecting AOT code generation, but has not yet been implemented.
+
+[2] The target function must be annotated as an entry point to work under AOT.
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 4d7bfea..75e507c 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -51,7 +51,9 @@
 
 static bool IsObjectStoreTypeId(intptr_t index) {
   // Check if this is a type which is stored in the object store.
-  return (index >= kObjectType && index <= kStringStringTypeArguments);
+  static_assert(kFirstTypeArgumentsSnapshotId == kLastTypeSnapshotId + 1,
+                "Type and type arguments snapshot ids should be adjacent");
+  return index >= kFirstTypeSnapshotId && index <= kLastTypeArgumentsSnapshotId;
 }
 
 static bool IsSplitClassId(intptr_t class_id) {
@@ -76,38 +78,69 @@
 
 static RawObject* GetType(ObjectStore* object_store, intptr_t index) {
   switch (index) {
-    case kObjectType:
-      return object_store->object_type();
+    case kLegacyObjectType:
+      return object_store->legacy_object_type();
     case kNullType:
       return object_store->null_type();
-    case kFunctionType:
-      return object_store->function_type();
-    case kNumberType:
-      return object_store->number_type();
-    case kSmiType:
-      return object_store->smi_type();
-    case kMintType:
-      return object_store->mint_type();
-    case kDoubleType:
-      return object_store->double_type();
-    case kIntType:
-      return object_store->int_type();
-    case kBoolType:
-      return object_store->bool_type();
-    case kStringType:
-      return object_store->string_type();
-    case kArrayType:
-      return object_store->array_type();
-    case kIntTypeArguments:
-      return object_store->type_argument_int();
-    case kDoubleTypeArguments:
-      return object_store->type_argument_double();
-    case kStringTypeArguments:
-      return object_store->type_argument_string();
-    case kStringDynamicTypeArguments:
-      return object_store->type_argument_string_dynamic();
-    case kStringStringTypeArguments:
-      return object_store->type_argument_string_string();
+    case kLegacyFunctionType:
+      return object_store->legacy_function_type();
+    case kLegacyNumberType:
+      return object_store->legacy_number_type();
+    case kLegacySmiType:
+      return object_store->legacy_smi_type();
+    case kLegacyMintType:
+      return object_store->legacy_mint_type();
+    case kLegacyDoubleType:
+      return object_store->legacy_double_type();
+    case kLegacyIntType:
+      return object_store->legacy_int_type();
+    case kLegacyBoolType:
+      return object_store->legacy_bool_type();
+    case kLegacyStringType:
+      return object_store->legacy_string_type();
+    case kLegacyArrayType:
+      return object_store->legacy_array_type();
+    case kLegacyIntTypeArguments:
+      return object_store->type_argument_legacy_int();
+    case kLegacyDoubleTypeArguments:
+      return object_store->type_argument_legacy_double();
+    case kLegacyStringTypeArguments:
+      return object_store->type_argument_legacy_string();
+    case kLegacyStringDynamicTypeArguments:
+      return object_store->type_argument_legacy_string_dynamic();
+    case kLegacyStringLegacyStringTypeArguments:
+      return object_store->type_argument_legacy_string_legacy_string();
+    case kNonNullableObjectType:
+      return object_store->non_nullable_object_type();
+    case kNonNullableFunctionType:
+      return object_store->non_nullable_function_type();
+    case kNonNullableNumberType:
+      return object_store->non_nullable_number_type();
+    case kNonNullableSmiType:
+      return object_store->non_nullable_smi_type();
+    case kNonNullableMintType:
+      return object_store->non_nullable_mint_type();
+    case kNonNullableDoubleType:
+      return object_store->non_nullable_double_type();
+    case kNonNullableIntType:
+      return object_store->non_nullable_int_type();
+    case kNonNullableBoolType:
+      return object_store->non_nullable_bool_type();
+    case kNonNullableStringType:
+      return object_store->non_nullable_string_type();
+    case kNonNullableArrayType:
+      return object_store->non_nullable_array_type();
+    case kNonNullableIntTypeArguments:
+      return object_store->type_argument_non_nullable_int();
+    case kNonNullableDoubleTypeArguments:
+      return object_store->type_argument_non_nullable_double();
+    case kNonNullableStringTypeArguments:
+      return object_store->type_argument_non_nullable_string();
+    case kNonNullableStringDynamicTypeArguments:
+      return object_store->type_argument_non_nullable_string_dynamic();
+    case kNonNullableStringNonNullableStringTypeArguments:
+      return object_store
+          ->type_argument_non_nullable_string_non_nullable_string();
     default:
       break;
   }
@@ -117,38 +150,72 @@
 
 static intptr_t GetTypeIndex(ObjectStore* object_store,
                              const RawObject* raw_type) {
-  if (raw_type == object_store->object_type()) {
-    return kObjectType;
+  if (raw_type == object_store->legacy_object_type()) {
+    return kLegacyObjectType;
   } else if (raw_type == object_store->null_type()) {
     return kNullType;
-  } else if (raw_type == object_store->function_type()) {
-    return kFunctionType;
-  } else if (raw_type == object_store->number_type()) {
-    return kNumberType;
-  } else if (raw_type == object_store->smi_type()) {
-    return kSmiType;
-  } else if (raw_type == object_store->mint_type()) {
-    return kMintType;
-  } else if (raw_type == object_store->double_type()) {
-    return kDoubleType;
-  } else if (raw_type == object_store->int_type()) {
-    return kIntType;
-  } else if (raw_type == object_store->bool_type()) {
-    return kBoolType;
-  } else if (raw_type == object_store->string_type()) {
-    return kStringType;
-  } else if (raw_type == object_store->array_type()) {
-    return kArrayType;
-  } else if (raw_type == object_store->type_argument_int()) {
-    return kIntTypeArguments;
-  } else if (raw_type == object_store->type_argument_double()) {
-    return kDoubleTypeArguments;
-  } else if (raw_type == object_store->type_argument_string()) {
-    return kStringTypeArguments;
-  } else if (raw_type == object_store->type_argument_string_dynamic()) {
-    return kStringDynamicTypeArguments;
-  } else if (raw_type == object_store->type_argument_string_string()) {
-    return kStringStringTypeArguments;
+  } else if (raw_type == object_store->legacy_function_type()) {
+    return kLegacyFunctionType;
+  } else if (raw_type == object_store->legacy_number_type()) {
+    return kLegacyNumberType;
+  } else if (raw_type == object_store->legacy_smi_type()) {
+    return kLegacySmiType;
+  } else if (raw_type == object_store->legacy_mint_type()) {
+    return kLegacyMintType;
+  } else if (raw_type == object_store->legacy_double_type()) {
+    return kLegacyDoubleType;
+  } else if (raw_type == object_store->legacy_int_type()) {
+    return kLegacyIntType;
+  } else if (raw_type == object_store->legacy_bool_type()) {
+    return kLegacyBoolType;
+  } else if (raw_type == object_store->legacy_string_type()) {
+    return kLegacyStringType;
+  } else if (raw_type == object_store->legacy_array_type()) {
+    return kLegacyArrayType;
+  } else if (raw_type == object_store->type_argument_legacy_int()) {
+    return kLegacyIntTypeArguments;
+  } else if (raw_type == object_store->type_argument_legacy_double()) {
+    return kLegacyDoubleTypeArguments;
+  } else if (raw_type == object_store->type_argument_legacy_string()) {
+    return kLegacyStringTypeArguments;
+  } else if (raw_type == object_store->type_argument_legacy_string_dynamic()) {
+    return kLegacyStringDynamicTypeArguments;
+  } else if (raw_type ==
+             object_store->type_argument_legacy_string_legacy_string()) {
+    return kLegacyStringLegacyStringTypeArguments;
+  } else if (raw_type == object_store->non_nullable_object_type()) {
+    return kNonNullableObjectType;
+  } else if (raw_type == object_store->non_nullable_function_type()) {
+    return kNonNullableFunctionType;
+  } else if (raw_type == object_store->non_nullable_number_type()) {
+    return kNonNullableNumberType;
+  } else if (raw_type == object_store->non_nullable_smi_type()) {
+    return kNonNullableSmiType;
+  } else if (raw_type == object_store->non_nullable_mint_type()) {
+    return kNonNullableMintType;
+  } else if (raw_type == object_store->non_nullable_double_type()) {
+    return kNonNullableDoubleType;
+  } else if (raw_type == object_store->non_nullable_int_type()) {
+    return kNonNullableIntType;
+  } else if (raw_type == object_store->non_nullable_bool_type()) {
+    return kNonNullableBoolType;
+  } else if (raw_type == object_store->non_nullable_string_type()) {
+    return kNonNullableStringType;
+  } else if (raw_type == object_store->non_nullable_array_type()) {
+    return kNonNullableArrayType;
+  } else if (raw_type == object_store->type_argument_non_nullable_int()) {
+    return kNonNullableIntTypeArguments;
+  } else if (raw_type == object_store->type_argument_non_nullable_double()) {
+    return kNonNullableDoubleTypeArguments;
+  } else if (raw_type == object_store->type_argument_non_nullable_string()) {
+    return kNonNullableStringTypeArguments;
+  } else if (raw_type ==
+             object_store->type_argument_non_nullable_string_dynamic()) {
+    return kNonNullableStringDynamicTypeArguments;
+  } else if (raw_type ==
+             object_store
+                 ->type_argument_non_nullable_string_non_nullable_string()) {
+    return kNonNullableStringNonNullableStringTypeArguments;
   }
   return kInvalidIndex;
 }
@@ -332,7 +399,7 @@
   if (str_.raw() == Symbols::TopLevel().raw()) {
     cls = library_.toplevel_class();
   } else {
-    str_ = String::ScrubName(str_);
+    str_ = String::New(String::ScrubName(str_));
     cls = library_.LookupClassAllowPrivate(str_);
   }
   if (cls.IsNull()) {
@@ -366,10 +433,10 @@
   str_ ^= ReadObjectImpl(kAsInlinedObject);
   if (str_.Equals(Symbols::TopLevel())) {
     str_ ^= ReadObjectImpl(kAsInlinedObject);
-    str_ = String::ScrubName(str_);
+    str_ = String::New(String::ScrubName(str_));
     func = library_.LookupFunctionAllowPrivate(str_);
   } else {
-    str_ = String::ScrubName(str_);
+    str_ = String::New(String::ScrubName(str_));
     cls_ = library_.LookupClassAllowPrivate(str_);
     if (cls_.IsNull()) {
       OS::PrintErr("Name of class not found %s\n", str_.ToCString());
@@ -377,7 +444,7 @@
     }
     cls_.EnsureIsFinalized(thread());
     str_ ^= ReadObjectImpl(kAsInlinedObject);
-    str_ = String::ScrubName(str_);
+    str_ = String::New(String::ScrubName(str_));
     func = cls_.LookupFunctionAllowPrivate(str_);
   }
   if (func.IsNull()) {
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
index f81f6e7..f071bea 100644
--- a/runtime/vm/snapshot_ids.h
+++ b/runtime/vm/snapshot_ids.h
@@ -29,26 +29,46 @@
   // The class ids of predefined classes are included in this list
   // at an offset of kClassIdsOffset.
 
-  kObjectType = (kNumPredefinedCids + kClassIdsOffset),
+  kFirstTypeSnapshotId = (kNumPredefinedCids + kClassIdsOffset),
+  kLegacyObjectType = kFirstTypeSnapshotId,
   kNullType,
   kDynamicType,
   kVoidType,
   kNeverType,
-  kFunctionType,
-  kNumberType,
-  kSmiType,
-  kMintType,
-  kDoubleType,
-  kIntType,
-  kBoolType,
-  kStringType,
-  kArrayType,
-  kIntTypeArguments,
-  kDoubleTypeArguments,
-  kStringTypeArguments,
-  kStringDynamicTypeArguments,
-  kStringStringTypeArguments,
+  kLegacyFunctionType,
+  kLegacyNumberType,
+  kLegacySmiType,
+  kLegacyMintType,
+  kLegacyDoubleType,
+  kLegacyIntType,
+  kLegacyBoolType,
+  kLegacyStringType,
+  kLegacyArrayType,
+  kNonNullableObjectType,
+  kNonNullableFunctionType,
+  kNonNullableNumberType,
+  kNonNullableSmiType,
+  kNonNullableMintType,
+  kNonNullableDoubleType,
+  kNonNullableIntType,
+  kNonNullableBoolType,
+  kNonNullableStringType,
+  kNonNullableArrayType,
+  kLastTypeSnapshotId = kNonNullableArrayType,
+
+  kFirstTypeArgumentsSnapshotId = kLastTypeSnapshotId + 1,
+  kLegacyIntTypeArguments = kFirstTypeArgumentsSnapshotId,
+  kLegacyDoubleTypeArguments,
+  kLegacyStringTypeArguments,
+  kLegacyStringDynamicTypeArguments,
+  kLegacyStringLegacyStringTypeArguments,
+  kNonNullableIntTypeArguments,
+  kNonNullableDoubleTypeArguments,
+  kNonNullableStringTypeArguments,
+  kNonNullableStringDynamicTypeArguments,
+  kNonNullableStringNonNullableStringTypeArguments,
   kEmptyTypeArguments,
+  kLastTypeArgumentsSnapshotId = kEmptyTypeArguments,
 
   kExtractorParameterTypes,
   kExtractorParameterNames,
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 13ca47f..7ea29a1 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -106,14 +106,16 @@
         controller_(Object::Handle(zone)),
         state_(Object::Handle(zone)),
         var_data_(Object::Handle(zone)),
+        callback_instance_(Object::Handle(zone)),
         future_impl_class(Class::Handle(zone)),
         async_await_completer_class(Class::Handle(zone)),
         future_listener_class(Class::Handle(zone)),
         async_start_stream_controller_class(Class::Handle(zone)),
         stream_controller_class(Class::Handle(zone)),
+        async_stream_controller_class(Class::Handle(zone)),
         controller_subscription_class(Class::Handle(zone)),
         buffering_stream_subscription_class(Class::Handle(zone)),
-        async_stream_controller_class(Class::Handle(zone)),
+        stream_iterator_class(Class::Handle(zone)),
         completer_is_sync_field(Field::Handle(zone)),
         completer_future_field(Field::Handle(zone)),
         future_result_or_listeners_field(Field::Handle(zone)),
@@ -121,7 +123,8 @@
         controller_controller_field(Field::Handle(zone)),
         var_data_field(Field::Handle(zone)),
         state_field(Field::Handle(zone)),
-        on_data_field(Field::Handle(zone)) {
+        on_data_field(Field::Handle(zone)),
+        state_data_field(Field::Handle(zone)) {
     const auto& async_lib = Library::Handle(zone, Library::AsyncLibrary());
     // Look up classes:
     // - async:
@@ -150,6 +153,9 @@
     buffering_stream_subscription_class = async_lib.LookupClassAllowPrivate(
         Symbols::_BufferingStreamSubscription());
     ASSERT(!buffering_stream_subscription_class.IsNull());
+    stream_iterator_class =
+        async_lib.LookupClassAllowPrivate(Symbols::_StreamIterator());
+    ASSERT(!stream_iterator_class.IsNull());
 
     // Look up fields:
     // - async:
@@ -180,15 +186,12 @@
     on_data_field = buffering_stream_subscription_class.LookupFieldAllowPrivate(
         Symbols::_onData());
     ASSERT(!on_data_field.IsNull());
+    state_data_field =
+        stream_iterator_class.LookupFieldAllowPrivate(Symbols::_stateData());
+    ASSERT(!state_data_field.IsNull());
   }
 
-  RawClosure* FindCallerInAsyncClosure(const Context& receiver_context) {
-    context_entry_ = receiver_context.At(Context::kAsyncCompleterIndex);
-    ASSERT(context_entry_.IsInstance());
-    ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
-
-    const Instance& completer = Instance::Cast(context_entry_);
-    future_ = completer.GetField(completer_future_field);
+  RawClosure* GetCallerInFutureImpl(const Object& future_) {
     ASSERT(!future_.IsNull());
     ASSERT(future_.GetClassId() == future_impl_class.id());
 
@@ -208,6 +211,16 @@
     return Closure::Cast(callback_).raw();
   }
 
+  RawClosure* FindCallerInAsyncClosure(const Context& receiver_context) {
+    context_entry_ = receiver_context.At(Context::kAsyncCompleterIndex);
+    ASSERT(context_entry_.IsInstance());
+    ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
+
+    const Instance& completer = Instance::Cast(context_entry_);
+    future_ = completer.GetField(completer_future_field);
+    return GetCallerInFutureImpl(future_);
+  }
+
   RawClosure* FindCallerInAsyncGenClosure(const Context& receiver_context) {
     context_entry_ = receiver_context.At(Context::kControllerIndex);
     ASSERT(context_entry_.IsInstance());
@@ -225,13 +238,37 @@
       return Closure::null();
     }
 
+    // _StreamController._varData
     var_data_ = Instance::Cast(controller_).GetField(var_data_field);
     ASSERT(var_data_.GetClassId() == controller_subscription_class.id());
 
+    // _ControllerSubscription<T>/_BufferingStreamSubscription.<T>_onData
     callback_ = Instance::Cast(var_data_).GetField(on_data_field);
     ASSERT(callback_.IsClosure());
 
-    return Closure::Cast(callback_).raw();
+    // If this is not the "_StreamIterator._onData" tear-off, we return the
+    // callback we found.
+    receiver_function_ = Closure::Cast(callback_).function();
+    if (!receiver_function_.IsImplicitInstanceClosureFunction() ||
+        receiver_function_.Owner() != stream_iterator_class.raw()) {
+      return Closure::Cast(callback_).raw();
+    }
+
+    // All implicit closure functions (tear-offs) have the "this" receiver
+    // captured.
+    receiver_context_ = Closure::Cast(callback_).context();
+    ASSERT(receiver_context_.num_variables() == 1);
+    callback_instance_ = receiver_context_.At(0);
+    ASSERT(callback_instance_.IsInstance());
+
+    // If the async* stream is await-for'd:
+    if (callback_instance_.GetClassId() == stream_iterator_class.id()) {
+      // _StreamIterator._stateData
+      future_ = Instance::Cast(callback_instance_).GetField(state_data_field);
+      return GetCallerInFutureImpl(future_);
+    }
+
+    UNREACHABLE();  // If no onData is found we have a bug.
   }
 
   RawClosure* FindCaller(const Closure& receiver_closure) {
@@ -284,15 +321,17 @@
   Object& controller_;
   Object& state_;
   Object& var_data_;
+  Object& callback_instance_;
 
   Class& future_impl_class;
   Class& async_await_completer_class;
   Class& future_listener_class;
   Class& async_start_stream_controller_class;
   Class& stream_controller_class;
+  Class& async_stream_controller_class;
   Class& controller_subscription_class;
   Class& buffering_stream_subscription_class;
-  Class& async_stream_controller_class;
+  Class& stream_iterator_class;
 
   Field& completer_is_sync_field;
   Field& completer_future_field;
@@ -302,6 +341,7 @@
   Field& var_data_field;
   Field& state_field;
   Field& on_data_field;
+  Field& state_data_field;
 };
 
 void StackTraceUtils::CollectFramesLazy(
@@ -309,11 +349,21 @@
     const GrowableObjectArray& code_array,
     const GrowableObjectArray& pc_offset_array,
     int skip_frames,
-    std::function<void(StackFrame*)>* on_sync_frames) {
+    std::function<void(StackFrame*)>* on_sync_frames,
+    bool* has_async) {
+  if (has_async != nullptr) {
+    *has_async = false;
+  }
   Zone* zone = thread->zone();
   DartFrameIterator frames(thread, StackFrameIterator::kNoCrossThreadIteration);
   StackFrame* frame = frames.NextFrame();
-  ASSERT(frame != nullptr);  // We expect to find a dart invocation frame.
+
+  // If e.g. the isolate is paused before executing anything, we might not get
+  // any frames at all. Bail:
+  if (frame == nullptr) {
+    return;
+  }
+
   auto& function = Function::Handle(zone);
   auto& code = Code::Handle(zone);
   auto& bytecode = Bytecode::Handle(zone);
@@ -347,7 +397,7 @@
     if (frame->is_interpreted()) {
       code_array.Add(bytecode);
       const intptr_t pc_offset = frame->pc() - bytecode.PayloadStart();
-      ASSERT(pc_offset >= 0 && pc_offset < bytecode.Size());
+      ASSERT(pc_offset >= 0 && pc_offset <= bytecode.Size());
       offset = Smi::New(pc_offset);
     } else {
       code = frame->LookupDartCode();
@@ -363,6 +413,10 @@
     // Either continue the loop (sync-async case) or find all await'ers and
     // return.
     if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+      if (has_async != nullptr) {
+        *has_async = true;
+      }
+
       // Next, look up caller's closure on the stack and walk backwards through
       // the yields.
       frame = frames.NextFrame();
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 306c2e7..d40784a 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -37,7 +37,8 @@
       const GrowableObjectArray& code_array,
       const GrowableObjectArray& pc_offset_array,
       int skip_frames,
-      std::function<void(StackFrame*)>* on_sync_frames = nullptr);
+      std::function<void(StackFrame*)>* on_sync_frames = nullptr,
+      bool* has_async = nullptr);
 
   /// Counts the number of stack frames.
   /// Skips over the first |skip_frames|.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 1124888..e8b5a14 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -396,6 +396,7 @@
   V(_StackTrace, "_StackTrace")                                                \
   V(_StreamController, "_StreamController")                                    \
   V(_StreamImpl, "_StreamImpl")                                                \
+  V(_StreamIterator, "_StreamIterator")                                        \
   V(_String, "String")                                                         \
   V(_SyncIterable, "_SyncIterable")                                            \
   V(_SyncIterableConstructor, "_SyncIterable.")                                \
@@ -444,6 +445,7 @@
   V(_simpleInstanceOfTrue, "_simpleInstanceOfTrue")                            \
   V(_stackTrace, "_stackTrace")                                                \
   V(_state, "_state")                                                          \
+  V(_stateData, "_stateData")                                                  \
   V(_varData, "_varData")                                                      \
   V(_wordCharacterMap, "_wordCharacterMap")                                    \
   V(add, "add")                                                                \
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 6c3a3fa..c50bd59 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -24,6 +24,7 @@
 
 const char* TypeTestingStubNamer::StubNameForType(
     const AbstractType& type) const {
+  NoSafepointScope no_safepoint;
   const uintptr_t address =
       reinterpret_cast<uintptr_t>(type.raw()) & 0x7fffffff;
   Zone* Z = Thread::Current()->zone();
@@ -33,6 +34,7 @@
 
 const char* TypeTestingStubNamer::StringifyType(
     const AbstractType& type) const {
+  NoSafepointScope no_safepoint;
   Zone* Z = Thread::Current()->zone();
   if (type.IsType() && !type.IsFunctionType()) {
     const intptr_t cid = Type::Cast(type).type_class_id();
@@ -50,10 +52,8 @@
       curl = OS::SCreate(Z, "nolib%" Pd "_", counter++);
     }
 
-    string_ = klass_.ScrubbedName();
-    ASSERT(!string_.IsNull());
-    const char* concatenated =
-        AssemblerSafeName(OS::SCreate(Z, "%s_%s", curl, string_.ToCString()));
+    const char* concatenated = AssemblerSafeName(
+        OS::SCreate(Z, "%s_%s", curl, klass_.ScrubbedNameCString()));
 
     const intptr_t type_parameters = klass_.NumTypeParameters();
     if (type.arguments() != TypeArguments::null() && type_parameters > 0) {
diff --git a/runtime/vm/zone_text_buffer.cc b/runtime/vm/zone_text_buffer.cc
index 8d3032b..c7548eb 100644
--- a/runtime/vm/zone_text_buffer.cc
+++ b/runtime/vm/zone_text_buffer.cc
@@ -7,6 +7,7 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 #include "platform/utils.h"
+#include "vm/object.h"
 #include "vm/os.h"
 #include "vm/zone.h"
 
@@ -47,6 +48,18 @@
   Printf("%s", s);
 }
 
+void ZoneTextBuffer::AddString(const String& s) {
+  Printf("%s", s.ToCString());
+}
+
+void ZoneTextBuffer::Clear() {
+  const intptr_t initial_capacity = 64;
+  buffer_ = reinterpret_cast<char*>(zone_->Alloc<char>(initial_capacity));
+  capacity_ = initial_capacity;
+  length_ = 0;
+  buffer_[length_] = '\0';
+}
+
 void ZoneTextBuffer::EnsureCapacity(intptr_t len) {
   intptr_t remaining = capacity_ - length_;
   if (remaining <= len) {
diff --git a/runtime/vm/zone_text_buffer.h b/runtime/vm/zone_text_buffer.h
index 8d6ae11..3d5207b 100644
--- a/runtime/vm/zone_text_buffer.h
+++ b/runtime/vm/zone_text_buffer.h
@@ -10,21 +10,25 @@
 
 namespace dart {
 
+class String;
 class Zone;
 
 // TextBuffer maintains a dynamic character buffer with a printf-style way to
 // append text.
 class ZoneTextBuffer : ValueObject {
  public:
-  ZoneTextBuffer(Zone* zone, intptr_t initial_capacity);
+  explicit ZoneTextBuffer(Zone* zone, intptr_t initial_capacity = 64);
   ~ZoneTextBuffer() {}
 
   intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   void AddString(const char* s);
+  void AddString(const String& s);
 
   char* buffer() { return buffer_; }
   intptr_t length() { return length_; }
 
+  void Clear();
+
  private:
   void EnsureCapacity(intptr_t len);
   Zone* zone_;
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 94eefcf..49377f6 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -329,7 +329,7 @@
       ignore_patterns = "{}"
     },
   ]
-  if (is_linux) {
+  if (is_linux || is_android) {
     copy_tree_specs += [
       {
         target = "copy_libtensorflowlite_c"
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
index 7795c8f..aff5a64 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
@@ -31,7 +31,7 @@
 MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;
 
 @patch
-InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
+InstanceMirror reflect(dynamic reflectee) => js.reflect(reflectee);
 
 @patch
 ClassMirror reflectClass(Type key) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_mirrors.dart b/sdk/lib/_internal/js_dev_runtime/private/js_mirrors.dart
index 38402be..2e95c3c 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_mirrors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_mirrors.dart
@@ -193,7 +193,7 @@
     return reflect(field);
   }
 
-  InstanceMirror setField(Symbol symbol, Object value) {
+  InstanceMirror setField(Symbol symbol, dynamic value) {
     var name = _getMember(symbol);
     dart.dputMirror(reflectee, name, value);
     return reflect(value);
@@ -392,7 +392,7 @@
     return reflect(JS('', '#[#]', dart.unwrapType(_cls), name));
   }
 
-  InstanceMirror setField(Symbol symbol, Object value) {
+  InstanceMirror setField(Symbol symbol, dynamic value) {
     var name = getName(symbol);
     JS('', '#[#] = #', dart.unwrapType(_cls), name, value);
     return reflect(value);
diff --git a/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
index 767de5f..5940845 100644
--- a/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
+++ b/sdk/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
@@ -15,7 +15,7 @@
 MirrorSystem currentMirrorSystem() => throw new UnsupportedError(_message);
 
 @patch
-InstanceMirror reflect(Object reflectee) =>
+InstanceMirror reflect(dynamic reflectee) =>
     throw new UnsupportedError(_message);
 
 @patch
diff --git a/sdk/lib/_internal/vm/bin/file_patch.dart b/sdk/lib/_internal/vm/bin/file_patch.dart
index 01681f4..6ee0c5b 100644
--- a/sdk/lib/_internal/vm/bin/file_patch.dart
+++ b/sdk/lib/_internal/vm/bin/file_patch.dart
@@ -173,9 +173,11 @@
       assert(_watcherPath.count > 0);
       _watcherPath.count--;
       if (_watcherPath.count == 0) {
-        _unwatchPath(_id, _watcherPath.pathId);
-        _pathWatchedEnd();
-        _idMap.remove(_watcherPath.pathId);
+        if (_idMap.containsKey(_watcherPath.pathId)) {
+          _unwatchPath(_id, _watcherPath.pathId);
+          _pathWatchedEnd();
+          _idMap.remove(_watcherPath.pathId);
+        }
       }
       _watcherPath = null;
     }
@@ -297,6 +299,15 @@
           }
         }
       } else if (event == RawSocketEvent.closed) {
+        // After this point we should not try to do anything with pathId as
+        // the handle it represented is closed and gone now.
+        if (_idMap.containsKey(pathId)) {
+          _idMap.remove(pathId);
+          if (_idMap.isEmpty && _id != null) {
+            _closeWatcher(_id);
+            _id = null;
+          }
+        }
       } else if (event == RawSocketEvent.readClosed) {
         // If Directory watcher buffer overflows, it will send an readClosed event.
         // Normal closing will cancel stream subscription so that path is
diff --git a/sdk/lib/_internal/vm/lib/mirrors_impl.dart b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
index 156d992..57af07f 100644
--- a/sdk/lib/_internal/vm/lib/mirrors_impl.dart
+++ b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
@@ -223,7 +223,7 @@
 
   _ObjectMirror._(this._reflectee);
 
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
+  InstanceMirror invoke(Symbol memberName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]) {
     int numPositionalArguments = positionalArguments.length;
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
@@ -247,7 +247,7 @@
     return reflect(this._invokeGetter(_reflectee, _n(memberName)));
   }
 
-  InstanceMirror setField(Symbol memberName, Object value) {
+  InstanceMirror setField(Symbol memberName, dynamic value) {
     this._invokeSetter(_reflectee, _n(memberName), value);
     return reflect(value);
   }
@@ -307,13 +307,13 @@
     return reflect(_invokeGetter(_reflectee, _n(memberName)));
   }
 
-  InstanceMirror setField(Symbol memberName, arg) {
+  InstanceMirror setField(Symbol memberName, dynamic arg) {
     _invokeSetter(_reflectee, _n(memberName), arg);
     return reflect(arg);
   }
 
   // Override to include the receiver in the arguments.
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
+  InstanceMirror invoke(Symbol memberName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]) {
     int numPositionalArguments = positionalArguments.length + 1; // Receiver.
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
@@ -355,7 +355,7 @@
     return _function = _computeFunction(reflectee);
   }
 
-  InstanceMirror apply(List positionalArguments,
+  InstanceMirror apply(List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]) {
     return this.invoke(#call, positionalArguments, namedArguments);
   }
@@ -646,7 +646,8 @@
 
   String toString() => "ClassMirror on '${MirrorSystem.getName(simpleName)}'";
 
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
+  InstanceMirror newInstance(
+      Symbol constructorName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]) {
     // Native code will add the 1 or 2 implicit arguments depending on whether
     // we end up invoking a factory or constructor respectively.
@@ -1442,7 +1443,7 @@
   }
 
   // Creates a new local mirror for some Object.
-  static InstanceMirror reflect(Object reflectee) {
+  static InstanceMirror reflect(dynamic reflectee) {
     return reflectee is Function
         ? new _ClosureMirror._(reflectee)
         : new _InstanceMirror._(reflectee);
diff --git a/sdk/lib/_internal/vm/lib/mirrors_patch.dart b/sdk/lib/_internal/vm/lib/mirrors_patch.dart
index 299ff50..6b8edd6 100644
--- a/sdk/lib/_internal/vm/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/vm/lib/mirrors_patch.dart
@@ -36,7 +36,7 @@
  * current running isolate.
  */
 @patch
-InstanceMirror reflect(Object reflectee) {
+InstanceMirror reflect(dynamic reflectee) {
   return _Mirrors.reflect(reflectee);
 }
 
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 0b7cc5a..b62ad88 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -962,6 +962,7 @@
   ///
   /// After calling [moveNext] and the returned future has completed
   /// with `false`, or after calling [cancel]: `null`.
+  @pragma("vm:entry-point")
   Object _stateData;
 
   /// Whether the iterator is between calls to `moveNext`.
diff --git a/sdk/lib/core/iterator.dart b/sdk/lib/core/iterator.dart
index 73a7d3f..1860497 100644
--- a/sdk/lib/core/iterator.dart
+++ b/sdk/lib/core/iterator.dart
@@ -34,17 +34,23 @@
  */
 abstract class Iterator<E> {
   /**
-   * Moves to the next element.
+   * Advances the iterator to the next element of the iteration.
    *
-   * Returns true if [current] contains the next element.
-   * Returns false if no elements are left.
+   * Should be called before reading [current].
+   * It the call to `moveNext` returns `true`,
+   * then [current] will contain the next element of the iteration
+   * until `moveNext` is called again.
+   * If the call returns `false`, there are no further elements
+   * and [current] should not be used any more.
    *
-   * It is safe to invoke [moveNext] even when the iterator is already
-   * positioned after the last element.
-   * In this case [moveNext] returns false again and has no effect.
+   * It is safe to call [moveNext] after it has already returned `false`,
+   * but it must keep returning `false` and not have any other effect.
    *
-   * A call to `moveNext` may throw if iteration has been broken by
-   * changing the underlying collection.
+   * A call to `moveNext` may throw for various reasons,
+   * including a concurrent change to an underlying collection.
+   * If that happens, the iterator may be in an inconsistent
+   * state, and any further behavior of the iterator is unspecified,
+   * including the effect of reading [current].
    */
   bool moveNext();
 
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
index 385d68a..8104bbb 100644
--- a/sdk/lib/developer/profiler.dart
+++ b/sdk/lib/developer/profiler.dart
@@ -127,6 +127,7 @@
   }
 
   // ignore: unused_element, called from native code
+  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
   static String _printMetric(String id) {
     var metric = _metrics[id];
     if (metric == null) {
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index f15e3d3..2a1e197 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -151,7 +151,7 @@
  * function can only be used to obtain  mirrors on objects of the current
  * isolate.
  */
-external InstanceMirror reflect(Object reflectee);
+external InstanceMirror reflect(dynamic reflectee);
 
 /**
  * Reflects a class declaration.
@@ -401,11 +401,7 @@
    * If the invocation throws an exception *e* (that it does not catch), this
    * method throws *e*.
    */
-  /*
-   * TODO(turnidge): Handle ambiguous names.
-   * TODO(turnidge): Handle optional & named arguments.
-   */
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
+  InstanceMirror invoke(Symbol memberName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]);
 
   /**
@@ -469,8 +465,7 @@
    * If the invocation throws an exception *e* (that it does not catch) this
    * method throws *e*.
    */
-  /* TODO(turnidge): Handle ambiguous names.*/
-  InstanceMirror setField(Symbol fieldName, Object value);
+  InstanceMirror setField(Symbol fieldName, dynamic value);
 
   /**
    * Performs [invocation] on the reflectee of this [ObjectMirror].
@@ -529,7 +524,7 @@
    * If you access [reflectee] when [hasReflectee] is false, an
    * exception is thrown.
    */
-  get reflectee;
+  dynamic get reflectee;
 
   /**
    * Whether this mirror is equal to [other].
@@ -597,7 +592,7 @@
    * If the invocation throws an exception *e* (that it does not catch), this
    * method throws *e*.
    */
-  InstanceMirror apply(List positionalArguments,
+  InstanceMirror apply(List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]);
 }
 
@@ -845,11 +840,6 @@
    */
   ClassMirror get mixin;
 
-  // TODO(ahe): What about:
-  // /// Finds the instance member named [name] declared or inherited in the
-  // /// reflected class.
-  // DeclarationMirror instanceLookup(Symbol name);
-
   /**
    * Invokes the named constructor and returns a mirror on the result.
    *
@@ -878,7 +868,8 @@
    * * If evaluating the expression throws an exception *e* (that it does not
    *   catch), this method throws *e*.
    */
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
+  InstanceMirror newInstance(
+      Symbol constructorName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments]);
 
   /**
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index d5f091b..e1d8f7e 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -14,7 +14,7 @@
 /// {@category Core}
 library dart.typed_data;
 
-import "dart:_internal" show UnmodifiableListBase;
+import "dart:_internal" show Since, UnmodifiableListBase;
 
 part "unmodifiable_typed_data.dart";
 
@@ -445,12 +445,12 @@
  * Finally, `ByteData` may be used to intentionally reinterpret the bytes
  * representing one arithmetic type as another.
  * For example this code fragment determine what 32-bit signed integer
- * is represented by the bytes of a 32-bit floating point number:
+ * is represented by the bytes of a 32-bit floating point number
+ * (both stored as big endian):
  *
- *     var buffer = new Uint8List(8).buffer;
- *     var bdata = new ByteData.view(buffer);
+ *     var bdata = new ByteData(8);
  *     bdata.setFloat32(0, 3.04);
- *     int huh = bdata.getInt32(0);
+ *     int huh = bdata.getInt32(0); // 0x40428f5c
  */
 abstract class ByteData implements TypedData {
   /**
@@ -473,6 +473,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `ByteData.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * ByteData.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [ByteData.sublistView]
+   * which includes this computation.
+   * ```dart
+   * ByteData.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory ByteData.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -480,6 +497,33 @@
   }
 
   /**
+   * Creates a [ByteData] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory ByteData.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    return data.buffer.asByteData(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns the (possibly negative) integer represented by the byte at the
    * specified [byteOffset] in this object, in two's complement binary
    * representation.
@@ -743,6 +787,8 @@
   /**
    * Creates an [Int8List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Int8List(int length);
 
@@ -752,6 +798,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Int8List.fromList(List<int> elements);
 
@@ -768,6 +817,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int8List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int8List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int8List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Int8List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int8List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -775,6 +841,33 @@
   }
 
   /**
+   * Creates an [Int8List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Int8List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    return data.buffer.asInt8List(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int8List` containing the elements of this list at
@@ -816,6 +909,8 @@
   /**
    * Creates a [Uint8List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Uint8List(int length);
 
@@ -825,6 +920,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Uint8List.fromList(List<int> elements);
 
@@ -841,6 +939,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint8List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint8List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint8List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Uint8List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint8List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -848,6 +963,33 @@
   }
 
   /**
+   * Creates a [Uint8List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Uint8List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    return data.buffer.asUint8List(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a concatenation of this list and [other].
    *
    * If [other] is also a typed-data list, then the return list will be a
@@ -898,6 +1040,8 @@
   /**
    * Creates a [Uint8ClampedList] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Uint8ClampedList(int length);
 
@@ -907,6 +1051,9 @@
    *
    * Values are clamped to fit in the list when they are copied,
    * the same way storing values clamps them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Uint8ClampedList.fromList(List<int> elements);
 
@@ -924,6 +1071,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint8ClampedList.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint8ClampedList.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint8ClampedList.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Uint8ClampedList.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint8ClampedList.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -931,6 +1095,34 @@
   }
 
   /**
+   * Creates a [Uint8ClampedList] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Uint8ClampedList.sublistView(TypedData data,
+      [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    return data.buffer.asUint8ClampedList(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint8ClampedList` containing the elements of this
@@ -973,6 +1165,9 @@
   /**
    * Creates an [Int16List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 2 bytes.
    */
   external factory Int16List(int length);
 
@@ -982,6 +1177,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 2 bytes.
    */
   external factory Int16List.fromList(List<int> elements);
 
@@ -1001,6 +1199,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int16List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int16List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int16List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Int16List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int16List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1008,6 +1223,41 @@
   }
 
   /**
+   * Creates an [Int16List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of two.
+   */
+  @Since("2.8")
+  factory Int16List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt16List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int16List` containing the elements of this
@@ -1050,6 +1300,9 @@
   /**
    * Creates a [Uint16List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 2 bytes.
    */
   external factory Uint16List(int length);
 
@@ -1059,6 +1312,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 2 bytes.
    */
   external factory Uint16List.fromList(List<int> elements);
 
@@ -1079,6 +1335,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint16List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint16List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint16List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Uint16List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint16List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1086,6 +1359,41 @@
   }
 
   /**
+   * Creates a [Uint16List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of two.
+   */
+  @Since("2.8")
+  factory Uint16List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint16List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint16List` containing the elements of this
@@ -1128,6 +1436,9 @@
   /**
    * Creates an [Int32List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Int32List(int length);
 
@@ -1137,6 +1448,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Int32List.fromList(List<int> elements);
 
@@ -1156,6 +1470,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int32List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Int32List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1163,6 +1494,41 @@
   }
 
   /**
+   * Creates an [Int32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Int32List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int32List` containing the elements of this
@@ -1205,6 +1571,9 @@
   /**
    * Creates a [Uint32List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Uint32List(int length);
 
@@ -1214,6 +1583,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Uint32List.fromList(List<int> elements);
 
@@ -1234,6 +1606,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint32List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Uint32List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1241,6 +1630,41 @@
   }
 
   /**
+   * Creates a [Uint32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Uint32List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint32List` containing the elements of this
@@ -1283,6 +1707,9 @@
   /**
    * Creates an [Int64List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Int64List(int length);
 
@@ -1292,6 +1719,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Int64List.fromList(List<int> elements);
 
@@ -1311,6 +1741,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int64List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Int64List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1318,6 +1765,41 @@
   }
 
   /**
+   * Creates an [Int64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Int64List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int64List` containing the elements of this
@@ -1360,6 +1842,9 @@
   /**
    * Creates a [Uint64List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Uint64List(int length);
 
@@ -1369,6 +1854,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Uint64List.fromList(List<int> elements);
 
@@ -1389,6 +1877,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint64List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Uint64List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1396,6 +1901,41 @@
   }
 
   /**
+   * Creates a [Uint64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Uint64List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint64List` containing the elements of this
@@ -1439,6 +1979,9 @@
   /**
    * Creates a [Float32List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Float32List(int length);
 
@@ -1448,6 +1991,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Float32List.fromList(List<double> elements);
 
@@ -1467,6 +2013,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float32List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Float32List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1474,6 +2037,41 @@
   }
 
   /**
+   * Creates an [Float32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Float32List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float32List` containing the elements of this
@@ -1513,12 +2111,18 @@
   /**
    * Creates a [Float64List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Float64List(int length);
 
   /**
    * Creates a [Float64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Float64List.fromList(List<double> elements);
 
@@ -1538,6 +2142,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float64List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Float64List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1545,6 +2166,41 @@
   }
 
   /**
+   * Creates a [Float64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Float64List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float64List` containing the elements of this
@@ -1583,12 +2239,18 @@
   /**
    * Creates a [Float32x4List] of the specified length (in elements),
    * all of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Float32x4List(int length);
 
   /**
    * Creates a [Float32x4List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Float32x4List.fromList(List<Float32x4> elements);
 
@@ -1608,6 +2270,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float32x4List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float32x4List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float32x4List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Float32x4List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float32x4List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1615,6 +2294,41 @@
   }
 
   /**
+   * Creates a [Float32x4List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Float32x4List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat32x4List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns the concatenation of this list and [other].
    *
    * If [other] is also a [Float32x4List], the result is a new [Float32x4List],
@@ -1661,12 +2375,18 @@
   /**
    * Creates a [Int32x4List] of the specified length (in elements),
    * all of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Int32x4List(int length);
 
   /**
    * Creates a [Int32x4List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Int32x4List.fromList(List<Int32x4> elements);
 
@@ -1686,6 +2406,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int32x4List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int32x4List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int32x4List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Int32x4List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int32x4List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1693,6 +2430,41 @@
   }
 
   /**
+   * Creates an [Int32x4List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Int32x4List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt32x4List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns the concatenation of this list and [other].
    *
    * If [other] is also a [Int32x4List], the result is a new [Int32x4List],
@@ -1739,12 +2511,18 @@
   /**
    * Creates a [Float64x2List] of the specified length (in elements),
    * all of whose elements have all lanes set to zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Float64x2List(int length);
 
   /**
    * Creates a [Float64x2List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Float64x2List.fromList(List<Float64x2> elements);
 
@@ -1772,6 +2550,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float64x2List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float64x2List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float64x2List.sublistView]
+   * which includes this computation.
+   * ```dart
+   * Float64x2List.sublistView(other, 0, count)
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float64x2List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int length]) {
@@ -1779,6 +2574,41 @@
   }
 
   /**
+   * Creates an [Float64x2List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Float64x2List.sublistView(TypedData data, [int start = 0, int end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat64x2List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float64x2List` containing the elements of this
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
index 94eefcf..49377f6 100644
--- a/sdk_nnbd/BUILD.gn
+++ b/sdk_nnbd/BUILD.gn
@@ -329,7 +329,7 @@
       ignore_patterns = "{}"
     },
   ]
-  if (is_linux) {
+  if (is_linux || is_android) {
     copy_tree_specs += [
       {
         target = "copy_libtensorflowlite_c"
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
index c18d12d..b5cc680 100644
--- a/sdk_nnbd/lib/_http/http_impl.dart
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -1057,7 +1057,7 @@
     implements HttpClientRequest {
   final String method;
   final Uri uri;
-  final List<Cookie> cookies = new List<Cookie>();
+  final List<Cookie> cookies = [];
 
   // The HttpClient this request belongs to.
   final _HttpClient _httpClient;
@@ -2926,7 +2926,7 @@
   static const String PROXY_PREFIX = "PROXY ";
   static const String DIRECT_PREFIX = "DIRECT";
 
-  _ProxyConfiguration(String configuration) : proxies = new List<_Proxy>() {
+  _ProxyConfiguration(String configuration) : proxies = <_Proxy>[] {
     if (configuration == null) {
       throw new HttpException("Invalid proxy configuration $configuration");
     }
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
index 1561ce8..4a4f196 100644
--- a/sdk_nnbd/lib/_http/http_parser.dart
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -941,7 +941,7 @@
   }
 
   static List<String> _tokenizeFieldValue(String headerValue) {
-    List<String> tokens = new List<String>();
+    List<String> tokens = <String>[];
     int start = 0;
     int index = 0;
     while (index < headerValue.length) {
diff --git a/sdk_nnbd/lib/_http/websocket_impl.dart b/sdk_nnbd/lib/_http/websocket_impl.dart
index 22befce..3fb8274 100644
--- a/sdk_nnbd/lib/_http/websocket_impl.dart
+++ b/sdk_nnbd/lib/_http/websocket_impl.dart
@@ -95,7 +95,7 @@
   EventSink<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ >? _eventSink;
 
   final bool _serverSide;
-  final List _maskingBytes = new List(4);
+  final Uint8List _maskingBytes = Uint8List(4);
   final BytesBuilder _payload = new BytesBuilder(copy: false);
 
   _WebSocketPerMessageDeflate? _deflate;
@@ -429,7 +429,7 @@
   }
 
   static List<String> _tokenizeFieldValue(String headerValue) {
-    List<String> tokens = new List<String>();
+    List<String> tokens = <String>[];
     int start = 0;
     int index = 0;
     while (index < headerValue.length) {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
index b018b3f..401233c 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
@@ -29,7 +29,7 @@
 MirrorSystem currentMirrorSystem() => js.currentJsMirrorSystem;
 
 @patch
-InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
+InstanceMirror reflect(dynamic reflectee) => js.reflect(reflectee);
 
 @patch
 ClassMirror reflectClass(Type key) {
@@ -66,7 +66,7 @@
   }
 
   var typeArgsLenth = typeArguments.length;
-  var unwrappedArgs = List(typeArgsLenth);
+  var unwrappedArgs = List.filled(typeArgsLenth, null);
   for (int i = 0; i < typeArgsLenth; i++) {
     unwrappedArgs[i] = dart.unwrapType(typeArguments[i]);
   }
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 3078863..b58a312 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -268,12 +268,12 @@
 // TODO(nshahan): Update after the normalization doc PR lands.
 @notNull
 Object legacy(type) {
-  // TODO(nshahan) Maybe normailize never*,  Null*.
-  if (_isLegacy(type) || _isNullable(type) || _isTop(type)) return type;
+  if (_isLegacy(type) || _isNullable(type) || _isTop(type) || _isNullType(type))
+    return type;
 
   // Check if a legacy version of this type has already been created.
   if (JS<bool>('!', '#.hasOwnProperty(#)', type, _cachedLegacy)) {
-    return JS<NullableType>('!', '#[#]', type, _cachedLegacy);
+    return JS<LegacyType>('!', '#[#]', type, _cachedLegacy);
   }
   // Cache a canonical legacy version of this type on this type.
   var cachedType = LegacyType(type);
@@ -324,10 +324,14 @@
   String toString() => name;
 
   @JSExportName('is')
-  // Object is the only legacy type that should return true if obj is `null`.
-  bool is_T(obj) => obj == null
-      ? type == unwrapType(Object)
-      : JS<bool>('!', '#.is(#)', type, obj);
+  bool is_T(obj) {
+    if (obj == null) {
+      // Object and Never are the only legacy types that should return true if
+      // obj is `null`.
+      return type == unwrapType(Object) || type == unwrapType(Never);
+    }
+    return JS<bool>('!', '#.is(#)', type, obj);
+  }
 
   @JSExportName('as')
   as_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj)
@@ -455,11 +459,12 @@
   return wrapType(normType, isNormalized: true);
 }
 
-/// Generates new values by applying [transform] to the keys of [srcObject],
-/// storing them in [dstObject].
+/// Generates new values by applying [transform] to the values of [srcObject],
+/// storing them in [dstObject] with the same key.
 void _transformJSObject(srcObject, dstObject, Function transform) {
   for (Object key in JS('!', '#.Object.keys(#)', global_, srcObject)) {
-    JS('', '#[#] = #', dstObject, key, transform(key));
+    JS('', '#[#] = #', dstObject, key,
+        transform(JS('', '#[#]', srcObject, key)));
   }
 }
 
@@ -696,7 +701,7 @@
         var typeNameString = typeName(JS('', '#[#[#]]', named, names, i));
         buffer += '$typeNameString ${JS('', '#[#]', names, i)}';
       }
-      if (JS('!', '#.length > 0', names)) buffer += ', ';
+      if (JS('!', '#.length > 0', requiredNamed)) buffer += ', ';
       names = getOwnPropertyNames(requiredNamed);
       JS('', '#.sort()', names);
       for (var i = 0; JS<bool>('!', '# < #.length', i, names); i++) {
@@ -841,7 +846,7 @@
     // formal if known, or it will be the original TypeVariable if we are still
     // solving for it. This array is passed to `instantiateToBounds` as we are
     // progressively solving for type variables.
-    var defaults = List<Object?>(typeFormals.length);
+    var defaults = List<Object?>.filled(typeFormals.length, null);
     // not ground
     var partials = Map<TypeVariable, Object>.identity();
 
@@ -1475,7 +1480,7 @@
 
   /// Returns the inferred types based on the current constraints.
   List<Object>? getInferredTypes() {
-    var result = List<Object>();
+    var result = <Object>[];
     for (var constraint in _typeVariables.values) {
       // Prefer the known bound, if any.
       if (constraint.lower != null) {
@@ -1840,4 +1845,4 @@
   }
 
   return null;
-}
\ No newline at end of file
+}
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
index 4670dc9..97a6b6b 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
@@ -207,7 +207,7 @@
 
   String join([String separator = ""]) {
     var length = this.length;
-    var list = List(length);
+    var list = List<String>.filled(length, "");
     for (int i = 0; i < length; i++) {
       list[i] = "${this[i]}";
     }
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
index 4d66e7d..c9ffaca 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
@@ -191,7 +191,7 @@
     return reflect(field);
   }
 
-  InstanceMirror setField(Symbol symbol, Object value) {
+  InstanceMirror setField(Symbol symbol, dynamic value) {
     var name = _getMember(symbol);
     dart.dputMirror(reflectee, name, value);
     return reflect(value);
@@ -390,7 +390,7 @@
     return reflect(JS('', '#[#]', dart.unwrapType(_cls), name));
   }
 
-  InstanceMirror setField(Symbol symbol, Object value) {
+  InstanceMirror setField(Symbol symbol, dynamic value) {
     var name = getName(symbol);
     JS('', '#[#] = #', dart.unwrapType(_cls), name, value);
     return reflect(value);
@@ -571,7 +571,7 @@
     // TODO(vsm): Add named args.
     List args = ftype.args;
     List opts = ftype.optionals;
-    var params = List<ParameterMirror>(args.length + opts.length);
+    var params = List<ParameterMirror>.filled(args.length + opts.length, null);
 
     for (var i = 0; i < args.length; ++i) {
       var type = args[i];
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
index 60f8033..f797ea4 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
@@ -99,7 +99,6 @@
       key = JS('', 'null');
     } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
         dart.identityEquals)) {
-      @notNull
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode);
       if (buckets != null) {
         for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
@@ -141,7 +140,6 @@
       key = JS('', 'null');
     } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
         dart.identityEquals)) {
-      @notNull
       var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode);
       if (buckets != null) {
         for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
index e1ed809..4ef894a 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
@@ -402,7 +402,7 @@
 // returns a copy of the list.
 List _ensureNativeList(List list) {
   if (list is JSIndexable) return list;
-  List result = List(list.length);
+  List result = List.filled(list.length, null);
   for (int i = 0; i < list.length; i++) {
     result[i] = list[i];
   }
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
index ceb9f11..7a0de57 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
@@ -39,7 +39,7 @@
   }
 
   List<String> groups(List<int> groups_) {
-    List<String> result = List<String>();
+    List<String> result = <String>[];
     for (int g in groups_) {
       result.add(group(g));
     }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
index 622e548..ffddbac 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -237,7 +237,7 @@
 
   List _computeKeys() {
     if (_keys != null) return _keys;
-    List result = new List(_length);
+    List result = List.filled(_length, null);
     int index = 0;
 
     // Add all string keys to the list.
@@ -986,7 +986,7 @@
 
   List _computeElements() {
     if (_elements != null) return _elements;
-    List result = new List(_length);
+    List result = List.filled(_length, null);
     int index = 0;
 
     // Add all string elements to the list.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
index 716e85f..b9c3994 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
@@ -266,7 +266,7 @@
   }
 
   String join([String separator = '']) {
-    var list = new List(this.length);
+    var list = List.filled(this.length, null);
     for (int i = 0; i < this.length; i++) {
       list[i] = '${this[i]}';
     }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
index 40490a3..91e454d 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
@@ -13,7 +13,7 @@
 MirrorSystem currentMirrorSystem() => throw new UnsupportedError(_message);
 
 @patch
-InstanceMirror reflect(Object reflectee) =>
+InstanceMirror reflect(dynamic reflectee) =>
     throw new UnsupportedError(_message);
 
 @patch
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
index 63c4cba..47aa6a0 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -378,7 +378,7 @@
 // returns a copy of the list.
 List _ensureNativeList(List list) {
   if (list is JSIndexable) return list;
-  List result = new List(list.length);
+  List result = List.filled(list.length, null);
   for (int i = 0; i < list.length; i++) {
     result[i] = list[i];
   }
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
index 5290dc9..ec66cc4 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
@@ -42,7 +42,7 @@
   }
 
   List<String> groups(List<int> groups_) {
-    List<String> result = new List<String>();
+    List<String> result = <String>[];
     for (int g in groups_) {
       result.add(group(g));
     }
diff --git a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
index 046377d..8589244 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
@@ -85,7 +85,7 @@
   }
 }
 
-List<_SignalController> _signalControllers = new List(32);
+List<_SignalController> _signalControllers = new List.filled(32, null);
 
 class _SignalController {
   final ProcessSignal signal;
@@ -248,7 +248,7 @@
       throw new ArgumentError("Arguments is not a List: $arguments");
     }
     int len = arguments.length;
-    _arguments = new List<String>(len);
+    _arguments = new List<String>.filled(len, "");
     for (int i = 0; i < len; i++) {
       var arg = arguments[i];
       if (arg is! String) {
@@ -446,7 +446,7 @@
       if (_modeIsAttached(_mode)) {
         int exitDataRead = 0;
         final int EXIT_DATA_SIZE = 8;
-        List<int> exitDataBuffer = new List<int>(EXIT_DATA_SIZE);
+        List<int> exitDataBuffer = new List<int>.filled(EXIT_DATA_SIZE, 0);
         _exitHandler.listen((data) {
           int exitCode(List<int> ints) {
             var code = _intFromBytes(ints, 0);
diff --git a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
index 8969aa4..af22246 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
@@ -78,7 +78,8 @@
   static final int ENCRYPTED_SIZE = 10 * 1024;
 
   _SecureFilterImpl._() {
-    buffers = new List<_ExternalBuffer>(_RawSecureSocket.bufferCount);
+    buffers =
+        new List<_ExternalBuffer>.filled(_RawSecureSocket.bufferCount, null);
     for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) {
       buffers[i] = new _ExternalBuffer(
           _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE);
diff --git a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
index 84baa46..caf7055 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
@@ -33,7 +33,7 @@
 @patch
 class RawSocketOption {
   static final List<int> _optionsCache =
-      List<int>(_RawSocketOptions.values.length);
+      List<int>.filled(_RawSocketOptions.values.length, null);
 
   @patch
   static int _getOptionValue(int key) {
@@ -351,7 +351,7 @@
   Completer closeCompleter = new Completer.sync();
 
   // Handlers and receive port for socket events from the event handler.
-  final List eventHandlers = new List(eventCount + 1);
+  final List eventHandlers = new List.filled(eventCount + 1, null);
   RawReceivePort eventPort;
   bool flagsSent = false;
 
diff --git a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
index 941aba4..dcdafff 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
@@ -185,7 +185,7 @@
       throw response;
     }
     List<_InternetAddress> addresses =
-        new List<_InternetAddress>(response.length);
+        new List<_InternetAddress>.filled(response.length, null);
     for (int i = 0; i < response.length; ++i) {
       var result = response[i];
       addresses[i] = new _InternetAddress(result[1], host, result[2]);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array.dart b/sdk_nnbd/lib/_internal/vm/lib/array.dart
index 1cefea5..73e1237 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array.dart
@@ -175,11 +175,11 @@
     final int actualEnd = RangeError.checkValidRange(start, end, this.length);
     int length = actualEnd - start;
     if (length == 0) return <E>[];
-    List list = new _List(length);
+    final list = new _List(length);
     for (int i = 0; i < length; i++) {
       list[i] = this[start + i];
     }
-    var result = new _GrowableList<E>._withData(list);
+    final result = new _GrowableList<E>._withData(list);
     result._setLength(length);
     return result;
   }
@@ -241,7 +241,7 @@
   final List<E> _array;
   final int _length; // Cache array length for faster access.
   int _index;
-  E _current;
+  E? _current;
 
   _FixedSizeArrayIterator(List<E> array)
       : _array = array,
@@ -250,7 +250,7 @@
     assert(array is _List<E> || array is _ImmutableList<E>);
   }
 
-  E get current => _current;
+  E get current => _current as E;
 
   @pragma("vm:prefer-inline")
   bool moveNext() {
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
index ba97574..db69321 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
@@ -81,7 +81,7 @@
     if (elements.isEmpty) {
       return new _GrowableList<E>(0);
     }
-    var result = new _GrowableList<E>._withData(elements);
+    final result = new _GrowableList<E>._withData(unsafeCast<_List>(elements));
     result._setLength(elements.length);
     return result;
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
index ca74fe2..044c0de 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
@@ -27,9 +27,9 @@
 
   void complete([FutureOr<T>? value]) {
     if (!isSync || value is Future<T>) {
-      _future._asyncComplete(value);
+      _future._asyncComplete(value as FutureOr<T>);
     } else {
-      _future._completeWithValue(value);
+      _future._completeWithValue(value as T);
     }
   }
 
@@ -88,10 +88,16 @@
 ///
 /// Returns the result of registering with `.then`.
 Future _awaitHelper(
-    var object, Function thenCallback, Function errorCallback, var awaiter) {
+    var object,
+    FutureOr<dynamic> Function(dynamic) thenCallback,
+    Function errorCallback,
+    var awaiter) {
+  late _Future future;
   if (object is! Future) {
-    object = new _Future().._setValue(object);
-  } else if (object is! _Future) {
+    future = new _Future().._setValue(object);
+  } else if (object is _Future) {
+    future = object;
+  } else {
     return object.then(thenCallback, onError: errorCallback);
   }
   // `object` is a `_Future`.
@@ -102,8 +108,8 @@
   //
   // We can only do this for our internal futures (the default implementation of
   // all futures that are constructed by the `dart:async` library).
-  object._awaiter = awaiter;
-  return object._thenAwait(thenCallback, errorCallback);
+  future._awaiter = awaiter;
+  return future._thenAwait(thenCallback, errorCallback);
 }
 
 // Called as part of the 'await for (...)' construct. Registers the
@@ -122,11 +128,12 @@
     return;
   }
   // stream is a _StreamImpl.
-  if (stream._generator == null) {
+  final generator = stream._generator;
+  if (generator == null) {
     // No generator registered, this isn't an async* Stream.
     return;
   }
-  _moveNextDebuggerStepCheck(stream._generator);
+  _moveNextDebuggerStepCheck(generator);
 }
 
 // _AsyncStarStreamController is used by the compiler to implement
@@ -140,7 +147,7 @@
   bool onListenReceived = false;
   bool isScheduled = false;
   bool isSuspendedAtYield = false;
-  _Future cancellationFuture = null;
+  _Future? cancellationFuture = null;
 
   Stream<T> get stream {
     final Stream<T> local = controller.stream;
@@ -207,10 +214,11 @@
   }
 
   void addError(Object error, StackTrace stackTrace) {
-    if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
+    final future = cancellationFuture;
+    if ((future != null) && future._mayComplete) {
       // If the stream has been cancelled, complete the cancellation future
       // with the error.
-      cancellationFuture._completeError(error, stackTrace);
+      future._completeError(error, stackTrace);
       return;
     }
     // If stream is cancelled, tell caller to exit the async generator.
@@ -223,19 +231,20 @@
   }
 
   close() {
-    if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
+    final future = cancellationFuture;
+    if ((future != null) && future._mayComplete) {
       // If the stream has been cancelled, complete the cancellation future
       // with the error.
-      cancellationFuture._completeWithValue(null);
+      future._completeWithValue(null);
     }
     controller.close();
   }
 
-  _AsyncStarStreamController(this.asyncStarBody) {
-    controller = new StreamController(
-        onListen: this.onListen,
-        onResume: this.onResume,
-        onCancel: this.onCancel);
+  _AsyncStarStreamController(this.asyncStarBody)
+      : controller = new StreamController() {
+    controller.onListen = this.onListen;
+    controller.onResume = this.onResume;
+    controller.onCancel = this.onCancel;
   }
 
   onListen() {
@@ -273,17 +282,17 @@
 @patch
 class _Future<T> {
   /// The closure implementing the async[*]-body that is `await`ing this future.
-  Function _awaiter;
+  Function? _awaiter;
 }
 
 @patch
 class _StreamImpl<T> {
   /// The closure implementing the async[*]-body that is `await`ing this future.
-  Function _awaiter;
+  Function? _awaiter;
 
   /// The closure implementing the async-generator body that is creating events
   /// for this stream.
-  Function _generator;
+  Function? _generator;
 }
 
 @pragma("vm:entry-point", "call")
diff --git a/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
index dbd22d8..6c20b56 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
@@ -1832,7 +1832,7 @@
       }
       return z._revert(resultDigits, resultUsed);
     }
-    var k;
+    late int k;
     if (exponentBitlen < 18)
       k = 1;
     else if (exponentBitlen < 48)
@@ -1845,10 +1845,10 @@
       k = 6;
     _BigIntReduction z = new _BigIntMontgomeryReduction(modulus);
     var n = 3;
-    final k1 = k - 1;
+    final int k1 = k - 1;
     final km = (1 << k) - 1;
-    List gDigits = new List(km + 1);
-    List gUsed = new List(km + 1);
+    List gDigits = new List.filled(km + 1, null);
+    List gUsed = new List.filled(km + 1, null);
     gDigits[1] = _newDigits(z._normModulusUsed);
     gUsed[1] = z._convert(this, gDigits[1]);
     if (k > 1) {
@@ -1869,7 +1869,7 @@
     var result2Used;
     var exponentDigits = exponent._digits;
     var j = exponent._used - 1;
-    var i = exponentDigits[j].bitLength - 1;
+    int i = exponentDigits[j].bitLength - 1;
     while (j >= 0) {
       if (i >= k1) {
         w = (exponentDigits[j] >> (i - k1)) & km;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
index 06c4869..2feba14 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
@@ -186,7 +186,7 @@
   }
 
   void clear() {
-    _buckets = new List(_INITIAL_CAPACITY);
+    _buckets = new List.filled(_INITIAL_CAPACITY, null);
     if (_elementCount > 0) {
       _elementCount = 0;
       _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
@@ -202,7 +202,7 @@
     }
   }
 
-  void _addEntry(List<_HashMapEntry<K, V>> buckets, int index, int length,
+  void _addEntry(List<_HashMapEntry<K, V>?> buckets, int index, int length,
       K key, V value, int hashCode) {
     final entry = new _HashMapEntry<K, V>(key, value, hashCode, buckets[index]);
     buckets[index] = entry;
@@ -240,17 +240,18 @@
   final _Equality<K> _equals;
   final _Hasher<K> _hashCode;
   final _Predicate _validKey;
-  _CustomHashMap(this._equals, this._hashCode, validKey)
+  _CustomHashMap(this._equals, this._hashCode, _Predicate? validKey)
       : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
 
   bool containsKey(Object? key) {
     if (!_validKey(key)) return false;
-    final hashCode = _hashCode(key);
+    K lkey = key as K;
+    final hashCode = _hashCode(lkey);
     final buckets = _buckets;
     final index = hashCode & (buckets.length - 1);
     var entry = buckets[index];
     while (entry != null) {
-      if (hashCode == entry.hashCode && _equals(entry.key, key)) return true;
+      if (hashCode == entry.hashCode && _equals(entry.key, lkey)) return true;
       entry = entry.next;
     }
     return false;
@@ -258,12 +259,13 @@
 
   V? operator [](Object? key) {
     if (!_validKey(key)) return null;
-    final hashCode = _hashCode(key);
+    K lkey = key as K;
+    final hashCode = _hashCode(lkey);
     final buckets = _buckets;
     final index = hashCode & (buckets.length - 1);
     var entry = buckets[index];
     while (entry != null) {
-      if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+      if (hashCode == entry.hashCode && _equals(entry.key, lkey)) {
         return entry.value;
       }
       entry = entry.next;
@@ -311,14 +313,15 @@
 
   V? remove(Object? key) {
     if (!_validKey(key)) return null;
-    final hashCode = _hashCode(key);
+    K lkey = key as K;
+    final hashCode = _hashCode(lkey);
     final buckets = _buckets;
     final index = hashCode & (buckets.length - 1);
     var entry = buckets[index];
     _HashMapEntry<K, V>? previous = null;
     while (entry != null) {
       final next = entry.next;
-      if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+      if (hashCode == entry.hashCode && _equals(entry.key, lkey)) {
         _removeEntry(entry, previous, index);
         _elementCount--;
         _modificationCount =
@@ -503,21 +506,21 @@
 
 class _HashMapKeyIterator<K, V> extends _HashMapIterator<K, V, K> {
   _HashMapKeyIterator(_HashMap<K, V> map) : super(map);
-  K get current => _entry?.key;
+  K get current => _entry!.key;
 }
 
 class _HashMapValueIterator<K, V> extends _HashMapIterator<K, V, V> {
   _HashMapValueIterator(_HashMap<K, V> map) : super(map);
-  V get current => _entry?.value;
+  V get current => _entry!.value;
 }
 
 @patch
 class HashSet<E> {
   @patch
   factory HashSet(
-      {bool equals(E e1, E e2),
-      int hashCode(E e),
-      bool isValidKey(potentialKey)}) {
+      {bool equals(E e1, E e2)?,
+      int hashCode(E e)?,
+      bool isValidKey(potentialKey)?}) {
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
@@ -549,8 +552,8 @@
   int _elementCount = 0;
   int _modificationCount = 0;
 
-  bool _equals(e1, e2) => e1 == e2;
-  int _hashCode(e) => e.hashCode;
+  bool _equals(Object? e1, Object? e2) => e1 == e2;
+  int _hashCode(Object? e) => e.hashCode;
 
   static Set<R> _newEmpty<R>() => new _HashSet<R>();
 
@@ -741,8 +744,8 @@
 }
 
 class _IdentityHashSet<E> extends _HashSet<E> {
-  int _hashCode(e) => identityHashCode(e);
-  bool _equals(e1, e2) => identical(e1, e2);
+  int _hashCode(Object? e) => identityHashCode(e);
+  bool _equals(Object? e1, Object? e2) => identical(e1, e2);
 
   HashSet<E> _newSet() => new _IdentityHashSet<E>();
   HashSet<R> _newSimilarSet<R>() => new _IdentityHashSet<R>();
@@ -752,7 +755,7 @@
   final _Equality<E> _equality;
   final _Hasher<E> _hasher;
   final _Predicate _validKey;
-  _CustomHashSet(this._equality, this._hasher, bool validKey(Object o))
+  _CustomHashSet(this._equality, this._hasher, _Predicate? validKey)
       : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
 
   bool remove(Object? element) {
@@ -771,7 +774,7 @@
   }
 
   bool containsAll(Iterable<Object?> elements) {
-    for (Object element in elements) {
+    for (Object? element in elements) {
       if (!_validKey(element) || !this.contains(element)) return false;
     }
     return true;
@@ -780,13 +783,13 @@
   void removeAll(Iterable<Object?> elements) {
     for (Object? element in elements) {
       if (_validKey(element)) {
-        super._remove(element, _hasher(element));
+        super._remove(element, _hashCode(element));
       }
     }
   }
 
-  bool _equals(e1, e2) => _equality(e1, e2);
-  int _hashCode(e) => _hasher(e);
+  bool _equals(Object? e1, Object? e2) => _equality(e1 as E, e2 as E);
+  int _hashCode(Object? e) => _hasher(e as E);
 
   HashSet<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
   HashSet<R> _newSimilarSet<R>() => new _HashSet<R>();
@@ -798,7 +801,7 @@
   _HashSetEntry<E>? next;
   _HashSetEntry(this.key, this.hashCode, this.next);
 
-  _HashSetEntry<E> remove() {
+  _HashSetEntry<E>? remove() {
     final result = next;
     next = null;
     return result;
@@ -916,11 +919,13 @@
   @patch
   Node _splayMin(Node node) {
     Node current = node;
-    while (current.left != null) {
-      Node left = internal.unsafeCast<Node>(current.left);
+    Object? nextLeft = current.left;
+    while (nextLeft != null) {
+      Node left = internal.unsafeCast<Node>(nextLeft);
       current.left = left.right;
       left.right = current;
       current = left;
+      nextLeft = current.left;
     }
     return current;
   }
@@ -928,11 +933,13 @@
   @patch
   Node _splayMax(Node node) {
     Node current = node;
-    while (current.right != null) {
-      Node right = internal.unsafeCast<Node>(current.right);
+    Object? nextRight = current.right;
+    while (nextRight != null) {
+      Node right = internal.unsafeCast<Node>(nextRight);
       current.right = right.left;
       right.left = current;
       current = right;
+      nextRight = current.right;
     }
     return current;
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
index cedcd0c..3a8c7cf 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
@@ -41,7 +41,7 @@
   // Note: All fields are initialized in a single constructor so that the VM
   // recognizes they cannot hold null values. This makes a big (20%) performance
   // difference on some operations.
-  _HashFieldBase(int dataSize) : this._data = new List(dataSize);
+  _HashFieldBase(int dataSize) : this._data = new List.filled(dataSize, null);
 }
 
 // Base class for VM-internal classes; keep in sync with _HashFieldBase.
@@ -157,7 +157,7 @@
   _InternalLinkedHashMap() {
     _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE);
     _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE);
-    _data = new List(_HashBase._INITIAL_INDEX_SIZE);
+    _data = new List.filled(_HashBase._INITIAL_INDEX_SIZE, null);
     _usedData = 0;
     _deletedKeys = 0;
   }
@@ -191,12 +191,12 @@
   }
 
   // Allocate new _index and _data, and optionally copy existing contents.
-  void _init(int size, int hashMask, List oldData, int oldUsed) {
+  void _init(int size, int hashMask, List? oldData, int oldUsed) {
     assert(size & (size - 1) == 0);
     assert(_HashBase._UNUSED_PAIR == 0);
     _index = new Uint32List(size);
     _hashMask = hashMask;
-    _data = new List(size);
+    _data = new List.filled(size, null);
     _usedData = 0;
     _deletedKeys = 0;
     if (oldData != null) {
@@ -441,7 +441,7 @@
   int _offset;
   final int _step;
   final int _checkSum;
-  E current;
+  E? _current;
 
   _CompactIterator(
       _HashBase table, this._data, this._len, this._offset, this._step)
@@ -456,13 +456,15 @@
       _offset += _step;
     } while (_offset < _len && _HashBase._isDeleted(_data, _data[_offset]));
     if (_offset < _len) {
-      current = internal.unsafeCast<E>(_data[_offset]);
+      _current = internal.unsafeCast<E>(_data[_offset]);
       return true;
     } else {
-      current = null;
+      _current = null;
       return false;
     }
   }
+
+  E get current => _current as E;
 }
 
 // Set implementation, analogous to _CompactLinkedHashMap.
@@ -482,7 +484,7 @@
     for (int offset = 0; offset < _usedData; offset++) {
       Object current = _data[offset];
       if (!_HashBase._isDeleted(_data, current)) {
-        return current;
+        return current as E;
       }
     }
     throw IterableElementError.noElement();
@@ -492,7 +494,7 @@
     for (int offset = _usedData - 1; offset >= 0; offset--) {
       Object current = _data[offset];
       if (!_HashBase._isDeleted(_data, current)) {
-        return current;
+        return current as E;
       }
     }
     throw IterableElementError.noElement();
@@ -512,10 +514,10 @@
     }
   }
 
-  void _init(int size, int hashMask, List oldData, int oldUsed) {
+  void _init(int size, int hashMask, List? oldData, int oldUsed) {
     _index = new Uint32List(size);
     _hashMask = hashMask;
-    _data = new List(size >> 1);
+    _data = new List.filled(size >> 1, null);
     _usedData = 0;
     _deletedKeys = 0;
     if (oldData != null) {
@@ -588,7 +590,7 @@
 
   E? lookup(Object? key) {
     var k = _getKeyOrData(key);
-    return identical(_data, k) ? null : k;
+    return identical(_data, k) ? null : internal.unsafeCast<E>(k);
   }
 
   bool contains(Object? key) => !identical(_data, _getKeyOrData(key));
diff --git a/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart
index 1d8e063..ee3b5a3 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart
@@ -49,8 +49,9 @@
       int second, int millisecond, int microsecond, bool isUtc)
       : this.isUtc = isUtc,
         this._value = _brokenDownDateToValue(year, month, day, hour, minute,
-            second, millisecond, microsecond, isUtc) {
-    if (_value == null) throw new ArgumentError();
+                second, millisecond, microsecond, isUtc) ??
+            -1 {
+    if (_value == -1) throw new ArgumentError();
     if (isUtc == null) throw new ArgumentError();
   }
 
@@ -99,7 +100,7 @@
     const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
   ];
 
-  static List _computeUpperPart(int localMicros) {
+  static List<int> _computeUpperPart(int localMicros) {
     const int DAYS_IN_4_YEARS = 4 * 365 + 1;
     const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
     const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
@@ -118,18 +119,18 @@
     int days = daysSince1970;
     days += DAYS_OFFSET;
     resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
-    days = days.remainder(DAYS_IN_400_YEARS);
+    days = unsafeCast<int>(days.remainder(DAYS_IN_400_YEARS));
     days--;
     int yd1 = days ~/ DAYS_IN_100_YEARS;
-    days = days.remainder(DAYS_IN_100_YEARS);
+    days = unsafeCast<int>(days.remainder(DAYS_IN_100_YEARS));
     resultYear += 100 * yd1;
     days++;
     int yd2 = days ~/ DAYS_IN_4_YEARS;
-    days = days.remainder(DAYS_IN_4_YEARS);
+    days = unsafeCast<int>(days.remainder(DAYS_IN_4_YEARS));
     resultYear += 4 * yd2;
     days--;
     int yd3 = days ~/ 365;
-    days = days.remainder(365);
+    days = unsafeCast<int>(days.remainder(365));
     resultYear += yd3;
 
     bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0;
@@ -166,7 +167,7 @@
             DateTime.daysPerWeek) +
         DateTime.monday;
 
-    List list = new List(_YEAR_INDEX + 1);
+    List<int> list = new List<int>.filled(_YEAR_INDEX + 1, 0);
     list[_MICROSECOND_INDEX] = resultMicrosecond;
     list[_MILLISECOND_INDEX] = resultMillisecond;
     list[_SECOND_INDEX] = resultSecond;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart
index 554b44f..3f3cf12 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart
@@ -12,7 +12,7 @@
   Future<Null> load() {
     // Dummy implementation that should eventually be replaced by real
     // implementation.
-    Future future = new Future<Null>.value(null);
+    Future<Null> future = new Future<Null>.value(null);
     _loadedLibraries.add(libraryName);
     return future;
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/double.dart b/sdk_nnbd/lib/_internal/vm/lib/double.dart
index 0f20d6e..c5472c9 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/double.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/double.dart
@@ -199,7 +199,7 @@
   static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1);
   static const int CACHE_MASK = CACHE_LENGTH - 1;
   // Each key (double) followed by its toString result.
-  static final List _cache = new List(CACHE_LENGTH);
+  static final List _cache = new List.filled(CACHE_LENGTH, null);
   static int _cacheEvictIndex = 0;
 
   String _toString() native "Double_toString";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart
index de8a689..0c706ce 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart
@@ -93,9 +93,10 @@
 
   static double? _parse(String str) {
     int len = str.length;
-    int start = str._firstNonWhitespace();
+    final strbase = str as _StringBase;
+    int start = strbase._firstNonWhitespace();
     if (start == len) return null; // All whitespace.
-    int end = str._lastNonWhitespace() + 1;
+    int end = strbase._lastNonWhitespace() + 1;
     assert(start < end);
     var result = _tryParseDouble(str, start, end);
     if (result != null) return result;
@@ -104,7 +105,7 @@
 
   @patch
   static double parse(String source,
-      [@deprecated double onError(String source)]) {
+      [@deprecated double onError(String source)?]) {
     var result = _parse(source);
     if (result == null) {
       if (onError == null) throw new FormatException("Invalid double", source);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
index 1d2194c..0bee1e5 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
@@ -17,7 +17,7 @@
   }
 
   @patch
-  StackTrace get stackTrace => _stackTrace!;
+  StackTrace? get stackTrace => _stackTrace;
 
   @pragma("vm:entry-point")
   StackTrace? _stackTrace;
@@ -32,11 +32,11 @@
   // out of the script. It expects a Dart stack frame from class
   // _AssertionError. Thus we need a Dart stub that calls the native code.
   @pragma("vm:entry-point", "call")
-  static _throwNew(int assertionStart, int assertionEnd, Object message) {
+  static _throwNew(int assertionStart, int assertionEnd, Object? message) {
     _doThrowNew(assertionStart, assertionEnd, message);
   }
 
-  static _doThrowNew(int assertionStart, int assertionEnd, Object message)
+  static _doThrowNew(int assertionStart, int assertionEnd, Object? message)
       native "AssertionError_throwNew";
 
   @pragma("vm:entry-point", "call")
@@ -54,9 +54,10 @@
   }
 
   String get _messageString {
-    if (message == null) return "is not true.";
-    if (message is String) return message;
-    return Error.safeToString(message);
+    final msg = message;
+    if (msg == null) return "is not true.";
+    if (msg is String) return msg;
+    return Error.safeToString(msg);
   }
 
   String toString() {
@@ -77,7 +78,7 @@
   final String _url;
   final int _line;
   final int _column;
-  final Object message;
+  final Object? message;
 }
 
 class _TypeError extends _AssertionError implements TypeError {
@@ -88,7 +89,7 @@
   static _throwNew(int location, Object srcValue, _Type dstType, String dstName)
       native "TypeError_throwNew";
 
-  String toString() => super.message;
+  String toString() => super.message as String;
 }
 
 class _CastError extends Error implements CastError {
@@ -224,7 +225,7 @@
   @patch
   NoSuchMethodError(Object receiver, Symbol memberName,
       List positionalArguments, Map<Symbol, dynamic> namedArguments,
-      [List existingArgumentNames = null])
+      [List? existingArgumentNames = null])
       : _receiver = receiver,
         _invocation = null,
         _memberName = memberName,
@@ -277,34 +278,37 @@
   @patch
   String toString() {
     // TODO(regis): Remove this null check once dart2js is updated.
-    if (_invocation == null) {
+    final localInvocation = _invocation;
+    if (localInvocation == null) {
       // Use deprecated version of toString.
       return _toStringDeprecated();
     }
-    String memberName =
-        internal.Symbol.computeUnmangledName(_invocation.memberName);
-    var level = (_invocation._type >> _InvocationMirror._LEVEL_SHIFT) &
+    var internalName = localInvocation.memberName as internal.Symbol;
+    String memberName = internal.Symbol.computeUnmangledName(internalName);
+
+    var level = (localInvocation._type >> _InvocationMirror._LEVEL_SHIFT) &
         _InvocationMirror._LEVEL_MASK;
-    var kind = _invocation._type & _InvocationMirror._KIND_MASK;
+    var kind = localInvocation._type & _InvocationMirror._KIND_MASK;
     if (kind == _InvocationMirror._LOCAL_VAR) {
       return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
     }
 
-    StringBuffer typeArgumentsBuf = null;
-    var typeArguments = _invocation.typeArguments;
+    StringBuffer? typeArgumentsBuf = null;
+    final typeArguments = localInvocation.typeArguments;
     if ((typeArguments != null) && (typeArguments.length > 0)) {
-      typeArgumentsBuf = new StringBuffer();
-      typeArgumentsBuf.write("<");
+      final argsBuf = new StringBuffer();
+      argsBuf.write("<");
       for (int i = 0; i < typeArguments.length; i++) {
         if (i > 0) {
-          typeArgumentsBuf.write(", ");
+          argsBuf.write(", ");
         }
-        typeArgumentsBuf.write(Error.safeToString(typeArguments[i]));
+        argsBuf.write(Error.safeToString(typeArguments[i]));
       }
-      typeArgumentsBuf.write(">");
+      argsBuf.write(">");
+      typeArgumentsBuf = argsBuf;
     }
     StringBuffer argumentsBuf = new StringBuffer();
-    var positionalArguments = _invocation.positionalArguments;
+    var positionalArguments = localInvocation.positionalArguments;
     int argumentCount = 0;
     if (positionalArguments != null) {
       for (; argumentCount < positionalArguments.length; argumentCount++) {
@@ -315,20 +319,21 @@
             .write(Error.safeToString(positionalArguments[argumentCount]));
       }
     }
-    var namedArguments = _invocation.namedArguments;
+    var namedArguments = localInvocation.namedArguments;
     if (namedArguments != null) {
       namedArguments.forEach((Symbol key, var value) {
         if (argumentCount > 0) {
           argumentsBuf.write(", ");
         }
-        argumentsBuf.write(internal.Symbol.computeUnmangledName(key));
+        var internalName = key as internal.Symbol;
+        argumentsBuf.write(internal.Symbol.computeUnmangledName(internalName));
         argumentsBuf.write(": ");
         argumentsBuf.write(Error.safeToString(value));
         argumentCount++;
       });
     }
     String existingSig =
-        _existingMethodSignature(_receiver, memberName, _invocation._type);
+        _existingMethodSignature(_receiver, memberName, localInvocation._type);
     String argsMsg = existingSig != null ? " with matching arguments" : "";
 
     assert(kind >= 0 && kind < 5);
@@ -433,7 +438,7 @@
     var type = _invocationType & _InvocationMirror._KIND_MASK;
     String memberName = (_memberName == null)
         ? ""
-        : internal.Symbol.computeUnmangledName(_memberName);
+        : internal.Symbol.computeUnmangledName(_memberName as internal.Symbol);
 
     if (type == _InvocationMirror._LOCAL_VAR) {
       return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
@@ -441,25 +446,25 @@
 
     StringBuffer arguments = new StringBuffer();
     int argumentCount = 0;
-    if (_arguments != null) {
-      for (; argumentCount < _arguments.length; argumentCount++) {
+    final args = _arguments;
+    if (args != null) {
+      for (; argumentCount < args.length; argumentCount++) {
         if (argumentCount > 0) {
           arguments.write(", ");
         }
-        arguments.write(Error.safeToString(_arguments[argumentCount]));
+        arguments.write(Error.safeToString(args[argumentCount]));
       }
     }
-    if (_namedArguments != null) {
-      _namedArguments.forEach((Symbol key, var value) {
-        if (argumentCount > 0) {
-          arguments.write(", ");
-        }
-        arguments.write(internal.Symbol.computeUnmangledName(key));
-        arguments.write(": ");
-        arguments.write(Error.safeToString(value));
-        argumentCount++;
-      });
-    }
+    _namedArguments?.forEach((Symbol key, var value) {
+      if (argumentCount > 0) {
+        arguments.write(", ");
+      }
+      var internalName = key as internal.Symbol;
+      arguments.write(internal.Symbol.computeUnmangledName(internalName));
+      arguments.write(": ");
+      arguments.write(Error.safeToString(value));
+      argumentCount++;
+    });
     bool argsMismatch = _existingArgumentNames != null;
     String argsMessage = argsMismatch ? " with matching arguments" : "";
 
@@ -549,11 +554,12 @@
 
     if (argsMismatch) {
       StringBuffer formalParameters = new StringBuffer();
-      for (int i = 0; i < _existingArgumentNames.length; i++) {
+      final argumentNames = _existingArgumentNames!;
+      for (int i = 0; i < argumentNames.length; i++) {
         if (i > 0) {
           formalParameters.write(", ");
         }
-        formalParameters.write(_existingArgumentNames[i]);
+        formalParameters.write(argumentNames[i]);
       }
       msgBuf.write("\nFound: $memberName($formalParameters)");
     }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart
index d8e873c..1d99cab 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart
@@ -9,7 +9,7 @@
   @patch
   Expando([String? name])
       : name = name,
-        _data = new List(_minSize),
+        _data = new List.filled(_minSize, null),
         _used = 0;
 
   static const _minSize = 8;
@@ -116,7 +116,7 @@
 
     // Reset the mappings to empty so that we can just add the existing
     // valid entries.
-    _data = new List(new_size);
+    _data = new List.filled(new_size, null);
     _used = 0;
 
     for (var i = 0; i < old_data.length; i++) {
diff --git a/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart
index cb9d205..0caf7ed 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart
@@ -17,18 +17,18 @@
         (positionalArguments != null ? positionalArguments.length : 0);
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
     int numArguments = numPositionalArguments + numNamedArguments;
-    List arguments = new List(numArguments);
+    List arguments = new List.filled(numArguments, null);
     arguments[0] = function;
     if (positionalArguments != null) {
       arguments.setRange(1, numPositionalArguments, positionalArguments);
     }
-    List names = new List(numNamedArguments);
+    List names = new List.filled(numNamedArguments, null);
     int argumentIndex = numPositionalArguments;
     int nameIndex = 0;
     if (numNamedArguments > 0) {
       namedArguments?.forEach((name, value) {
         arguments[argumentIndex++] = value;
-        names[nameIndex++] = internal.Symbol.getName(name);
+        names[nameIndex++] = internal.Symbol.getName(name as internal.Symbol);
       });
     }
     return _apply(arguments, names);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
index b3623ce..9b66fad 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
@@ -77,11 +77,11 @@
     final int actualEnd = RangeError.checkValidRange(start, end, this.length);
     int length = actualEnd - start;
     if (length == 0) return <T>[];
-    List list = new _List(length);
+    final list = new _List(length);
     for (int i = 0; i < length; i++) {
       list[i] = this[start + i];
     }
-    var result = new _GrowableList<T>._withData(list);
+    final result = new _GrowableList<T>._withData(list);
     result._setLength(length);
     return result;
   }
@@ -186,7 +186,7 @@
           throw new ConcurrentModificationError(this);
         }
         this._setLength(newLen);
-        final ListBase<T> iterableAsList = iterable;
+        final ListBase<T> iterableAsList = iterable as ListBase<T>;
         for (int i = 0; i < iterLen; i++) {
           this[len++] = iterableAsList[i];
         }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/integers.dart b/sdk_nnbd/lib/_internal/vm/lib/integers.dart
index dcce105..9fd3a76 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/integers.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/integers.dart
@@ -303,7 +303,7 @@
       // -MIN_INT64 == MIN_INT64, so it requires special handling.
       return _minInt64ToRadixString(radix);
     }
-    var temp = new List<int>();
+    var temp = <int>[];
     do {
       int digit = value % radix;
       value ~/= radix;
@@ -351,7 +351,7 @@
   /// This method is only used to handle corner case of
   /// MIN_INT64 = -0x8000000000000000.
   String _minInt64ToRadixString(int radix) {
-    var temp = new List<int>();
+    var temp = <int>[];
     int value = this;
     assert(value < 0);
     do {
@@ -637,10 +637,14 @@
     } while (smi >= 100);
     if (smi < 10) {
       // Character code for '0'.
-      result._setAt(index, DIGIT_ZERO + smi);
+      // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
+      // result type as `num`.
+      result._setAt(index, unsafeCast<int>(DIGIT_ZERO + smi));
     } else {
       // No remainder for this case.
-      int digitIndex = smi * 2;
+      // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
+      // result type as `num`.
+      int digitIndex = unsafeCast<int>(smi * 2);
       result._setAt(index, _digitTable[digitIndex + 1]);
       result._setAt(index - 1, _digitTable[digitIndex]);
     }
@@ -694,7 +698,7 @@
     result._setAt(0, MINUS_SIGN); // '-'.
     int index = digitCount;
     do {
-      var twoDigits = negSmi.remainder(100);
+      int twoDigits = unsafeCast<int>(negSmi.remainder(100));
       negSmi = negSmi ~/ 100;
       int digitIndex = -twoDigits * 2;
       result._setAt(index, _digitTable[digitIndex + 1]);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index fe05552..927ef2f 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -121,4 +121,4 @@
 // type of a value.
 //
 // Important: this is unsafe and must be used with care.
-T unsafeCast<T>(Object v) native "Internal_unsafeCast";
+T unsafeCast<T>(Object? v) native "Internal_unsafeCast";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
index e7e2fe3..e65d3d6 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
@@ -10,6 +10,7 @@
 class _InvocationMirror implements Invocation {
   // Constants describing the invocation kind.
   // _FIELD cannot be generated by regular invocation mirrors.
+  static const int _UNINITIALIZED = -1;
   static const int _METHOD = 0;
   static const int _GETTER = 1;
   static const int _SETTER = 2;
@@ -37,18 +38,18 @@
   static const int _FIRST_NAMED_ENTRY = 3;
 
   // Internal representation of the invocation mirror.
-  String _functionName;
-  List _argumentsDescriptor;
-  List _arguments;
-  bool _isSuperInvocation;
-  int _delayedTypeArgumentsLen;
+  String? _functionName;
+  List? _argumentsDescriptor;
+  List? _arguments;
+  bool _isSuperInvocation = false;
+  int _delayedTypeArgumentsLen = 0;
 
   // External representation of the invocation mirror; populated on demand.
-  Symbol _memberName;
-  int _type;
-  List<Type> _typeArguments;
-  List _positionalArguments;
-  Map<Symbol, dynamic> _namedArguments;
+  Symbol? _memberName;
+  int _type = _UNINITIALIZED;
+  List<Type>? _typeArguments;
+  List? _positionalArguments;
+  Map<Symbol, dynamic>? _namedArguments;
 
   _InvocationMirror._withType(this._memberName, this._type, this._typeArguments,
       this._positionalArguments, this._namedArguments) {
@@ -57,19 +58,20 @@
     _namedArguments ??= const {};
   }
 
-  void _setMemberNameAndType() {
-    _type ??= 0;
-    if (_functionName.startsWith("get:")) {
+  Symbol _setMemberNameAndType() {
+    final funcName = _functionName!;
+    _type = _METHOD;
+    if (funcName.startsWith("get:")) {
       _type |= _GETTER;
-      _memberName = new internal.Symbol.unvalidated(_functionName.substring(4));
-    } else if (_functionName.startsWith("set:")) {
+      _memberName = new internal.Symbol.unvalidated(funcName.substring(4));
+    } else if (funcName.startsWith("set:")) {
       _type |= _SETTER;
       _memberName =
-          new internal.Symbol.unvalidated(_functionName.substring(4) + "=");
+          new internal.Symbol.unvalidated(funcName.substring(4) + "=");
     } else {
       _type |=
           _isSuperInvocation ? (_SUPER << _LEVEL_SHIFT) | _METHOD : _METHOD;
-      _memberName = new internal.Symbol.unvalidated(_functionName);
+      _memberName = new internal.Symbol.unvalidated(funcName);
     }
   }
 
@@ -77,11 +79,11 @@
     if (_memberName == null) {
       _setMemberNameAndType();
     }
-    return _memberName;
+    return _memberName!;
   }
 
   int get _typeArgsLen {
-    int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
+    int typeArgsLen = _argumentsDescriptor![_TYPE_ARGS_LEN];
     return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen;
   }
 
@@ -93,9 +95,9 @@
       // A TypeArguments object does not have a corresponding Dart class and
       // cannot be accessed as an array in Dart. Therefore, we need a native
       // call to unpack the individual types into a list.
-      _typeArguments = _unpackTypeArguments(_arguments[0], _typeArgsLen);
+      _typeArguments = _unpackTypeArguments(_arguments![0], _typeArgsLen);
     }
-    return _typeArguments;
+    return _typeArguments!;
   }
 
   // Unpack the given TypeArguments object into a new list of individual types.
@@ -106,63 +108,65 @@
     if (_positionalArguments == null) {
       // The argument descriptor counts the receiver, but not the type arguments
       // as positional arguments.
-      int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
+      int numPositionalArguments = _argumentsDescriptor![_POSITIONAL_COUNT] - 1;
       if (numPositionalArguments == 0) {
         return _positionalArguments = const [];
       }
       // Exclude receiver and type args in the returned list.
       int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
+      var args = _arguments!;
       _positionalArguments = new _ImmutableList._from(
-          _arguments, receiverIndex + 1, numPositionalArguments);
+          args, receiverIndex + 1, numPositionalArguments);
     }
-    return _positionalArguments;
+    return _positionalArguments!;
   }
 
   Map<Symbol, dynamic> get namedArguments {
     if (_namedArguments == null) {
-      int numArguments = _argumentsDescriptor[_COUNT] - 1; // Exclude receiver.
-      int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
+      final argsDescriptor = _argumentsDescriptor!;
+      int numArguments = argsDescriptor[_COUNT] - 1; // Exclude receiver.
+      int numPositionalArguments = argsDescriptor[_POSITIONAL_COUNT] - 1;
       int numNamedArguments = numArguments - numPositionalArguments;
       if (numNamedArguments == 0) {
         return _namedArguments = const {};
       }
       int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
-      _namedArguments = new Map<Symbol, dynamic>();
+      final namedArguments = new Map<Symbol, dynamic>();
       for (int i = 0; i < numNamedArguments; i++) {
         int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i;
-        String arg_name = _argumentsDescriptor[namedEntryIndex];
-        var arg_value = _arguments[
-            receiverIndex + _argumentsDescriptor[namedEntryIndex + 1]];
-        _namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value;
+        int pos = argsDescriptor[namedEntryIndex + 1];
+        String arg_name = argsDescriptor[namedEntryIndex];
+        var arg_value = _arguments![receiverIndex + pos];
+        namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value;
       }
-      _namedArguments = new Map.unmodifiable(_namedArguments);
+      _namedArguments = new Map.unmodifiable(namedArguments);
     }
-    return _namedArguments;
+    return _namedArguments!;
   }
 
   bool get isMethod {
-    if (_type == null) {
+    if (_type == _UNINITIALIZED) {
       _setMemberNameAndType();
     }
     return (_type & _KIND_MASK) == _METHOD;
   }
 
   bool get isAccessor {
-    if (_type == null) {
+    if (_type == _UNINITIALIZED) {
       _setMemberNameAndType();
     }
     return (_type & _KIND_MASK) != _METHOD;
   }
 
   bool get isGetter {
-    if (_type == null) {
+    if (_type == _UNINITIALIZED) {
       _setMemberNameAndType();
     }
     return (_type & _KIND_MASK) == _GETTER;
   }
 
   bool get isSetter {
-    if (_type == null) {
+    if (_type == _UNINITIALIZED) {
       _setMemberNameAndType();
     }
     return (_type & _KIND_MASK) == _SETTER;
@@ -179,7 +183,7 @@
   @pragma("vm:entry-point", "call")
   static _allocateInvocationMirror(String functionName,
       List argumentsDescriptor, List arguments, bool isSuperInvocation,
-      [int type = null]) {
+      [int type = _UNINITIALIZED]) {
     return new _InvocationMirror(
         functionName, argumentsDescriptor, arguments, isSuperInvocation, type);
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart
index 085d0a9..b41daad 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart
@@ -27,7 +27,7 @@
         // The following returns -0.0 if either a or b is -0.0, and it
         // returns NaN if b is NaN.
         num n = (a + b) * a * b;
-        return n;
+        return n as T;
       }
     }
     // Check for NaN and b == -0.0.
@@ -51,7 +51,7 @@
         // The following returns 0.0 if either a or b is 0.0, and it
         // returns NaN if b is NaN.
         num n = a + b;
-        return n;
+        return n as T;
       }
     }
     // Check for NaN.
diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
index 671b062..73ea82c 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
@@ -70,7 +70,7 @@
 List<dynamic> _metadata(reflectee) native 'DeclarationMirror_metadata';
 
 List<InstanceMirror> _wrapMetadata(List reflectees) {
-  var mirrors = new List<InstanceMirror>();
+  var mirrors = <InstanceMirror>[];
   for (var reflectee in reflectees) {
     mirrors.add(reflect(reflectee));
   }
@@ -226,9 +226,9 @@
     int numPositionalArguments = positionalArguments.length;
     int numNamedArguments = namedArguments.length;
     int numArguments = numPositionalArguments + numNamedArguments;
-    List arguments = new List(numArguments);
+    List arguments = new List.filled(numArguments, null);
     arguments.setRange(0, numPositionalArguments, positionalArguments);
-    List names = new List(numNamedArguments);
+    List names = new List.filled(numNamedArguments, null);
     int argumentIndex = numPositionalArguments;
     int nameIndex = 0;
     if (numNamedArguments > 0) {
@@ -245,7 +245,7 @@
     return reflect(this._invokeGetter(_reflectee, _n(memberName)));
   }
 
-  InstanceMirror setField(Symbol memberName, Object value) {
+  InstanceMirror setField(Symbol memberName, dynamic value) {
     this._invokeSetter(_reflectee, _n(memberName), value);
     return reflect(value);
   }
@@ -291,7 +291,7 @@
 
   String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}';
 
-  bool operator ==(other) {
+  bool operator ==(Object other) {
     return other is _InstanceMirror && identical(_reflectee, other._reflectee);
   }
 
@@ -305,7 +305,7 @@
     return reflect(_invokeGetter(_reflectee, _n(memberName)));
   }
 
-  InstanceMirror setField(Symbol memberName, arg) {
+  InstanceMirror setField(Symbol memberName, dynamic arg) {
     _invokeSetter(_reflectee, _n(memberName), arg);
     return reflect(arg);
   }
@@ -316,10 +316,10 @@
     int numPositionalArguments = positionalArguments.length + 1; // Receiver.
     int numNamedArguments = namedArguments.length;
     int numArguments = numPositionalArguments + numNamedArguments;
-    List arguments = new List(numArguments);
+    List arguments = new List.filled(numArguments, null);
     arguments[0] = _reflectee; // Receiver.
     arguments.setRange(1, numPositionalArguments, positionalArguments);
-    List names = new List(numNamedArguments);
+    List names = new List.filled(numNamedArguments, null);
     int argumentIndex = numPositionalArguments;
     int nameIndex = 0;
     if (numNamedArguments > 0) {
@@ -471,7 +471,7 @@
     if (_isTransformedMixinApplication) {
       interfaceTypes = interfaceTypes.sublist(0, interfaceTypes.length - 1);
     }
-    var interfaceMirrors = new List<ClassMirror>();
+    var interfaceMirrors = <ClassMirror>[];
     for (var interfaceType in interfaceTypes) {
       interfaceMirrors.add(reflectType(interfaceType) as ClassMirror);
     }
@@ -480,7 +480,7 @@
   }
 
   Symbol get _mixinApplicationName {
-    var mixins = new List<ClassMirror>();
+    var mixins = <ClassMirror>[];
     var klass = this;
     while (_nativeMixin(klass._reflectedType) != null) {
       mixins.add(klass.mixin);
@@ -605,7 +605,7 @@
     if (!_isTransformedMixinApplication && _isAnonymousMixinApplication) {
       return _typeVariables = const <TypeVariableMirror>[];
     }
-    var result = new List<TypeVariableMirror>();
+    var result = <TypeVariableMirror>[];
 
     List params = _ClassMirror_type_variables(_reflectee);
     ClassMirror owner = originalDeclaration;
@@ -651,9 +651,9 @@
     int numPositionalArguments = positionalArguments.length;
     int numNamedArguments = namedArguments.length;
     int numArguments = numPositionalArguments + numNamedArguments;
-    List arguments = new List(numArguments);
+    List arguments = new List.filled(numArguments, null);
     arguments.setRange(0, numPositionalArguments, positionalArguments);
-    List names = new List(numNamedArguments);
+    List names = new List.filled(numNamedArguments, null);
     int argumentIndex = numPositionalArguments;
     int nameIndex = 0;
     if (numNamedArguments > 0) {
@@ -671,8 +671,8 @@
     return _wrapMetadata(_metadata(_reflectee));
   }
 
-  bool operator ==(other) {
-    return this.runtimeType == other.runtimeType &&
+  bool operator ==(Object other) {
+    return other is _ClassMirror &&
         this._reflectee == other._reflectee &&
         this._reflectedType == other._reflectedType &&
         this._isGenericDeclaration == other._isGenericDeclaration;
@@ -834,9 +834,8 @@
     return _wrapMetadata(_metadata(_reflectee));
   }
 
-  bool operator ==(other) {
-    return this.runtimeType == other.runtimeType &&
-        this._reflectee == other._reflectee;
+  bool operator ==(Object other) {
+    return other is _DeclarationMirror && this._reflectee == other._reflectee;
   }
 
   int get hashCode => simpleName.hashCode;
@@ -881,7 +880,7 @@
 
   String toString() => "TypeVariableMirror on '${_n(simpleName)}'";
 
-  bool operator ==(other) {
+  bool operator ==(Object other) {
     return other is TypeVariableMirror &&
         simpleName == other.simpleName &&
         owner == other.owner;
@@ -963,7 +962,7 @@
     var v = _typeVariables;
     if (v != null) return v;
 
-    var result = new List<TypeVariableMirror>();
+    var result = <TypeVariableMirror>[];
     List params = _ClassMirror._ClassMirror_type_variables(_reflectee);
     TypedefMirror owner = originalDeclaration;
     var mirror;
@@ -1059,9 +1058,8 @@
     return _wrapMetadata(_metadata(_reflectee));
   }
 
-  bool operator ==(other) {
-    return this.runtimeType == other.runtimeType &&
-        this._reflectee == other._reflectee;
+  bool operator ==(Object other) {
+    return other is _LibraryMirror && this._reflectee == other._reflectee;
   }
 
   int get hashCode => simpleName.hashCode;
@@ -1414,7 +1412,7 @@
 
   Symbol get qualifiedName => simpleName;
 
-  bool operator ==(other) {
+  bool operator ==(Object other) {
     if (other is! _SpecialTypeMirror) {
       return false;
     }
@@ -1441,7 +1439,7 @@
   }
 
   // Creates a new local mirror for some Object.
-  static InstanceMirror reflect(Object reflectee) {
+  static InstanceMirror reflect(dynamic reflectee) {
     return reflectee is Function
         ? new _ClosureMirror._(reflectee)
         : new _InstanceMirror._(reflectee);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
index ca51d0c..4fd4d31 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
@@ -34,7 +34,7 @@
  * current running isolate.
  */
 @patch
-InstanceMirror reflect(Object reflectee) {
+InstanceMirror reflect(dynamic reflectee) {
   return _Mirrors.reflect(reflectee);
 }
 
diff --git a/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart
index 5b43e89..a2390a4 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart
@@ -219,7 +219,7 @@
   RegExpMatch? firstMatch(String input) {
     // TODO: Remove these null checks once all code is opted into strong nonnullable mode.
     if (input == null) throw new ArgumentError.notNull('input');
-    List<int> match = _ExecuteMatch(input, 0);
+    final match = _ExecuteMatch(input, 0);
     if (match == null) {
       return null;
     }
@@ -236,14 +236,14 @@
     return new _AllMatchesIterable(this, string, start);
   }
 
-  RegExpMatch matchAsPrefix(String string, [int start = 0]) {
+  RegExpMatch? matchAsPrefix(String string, [int start = 0]) {
     // TODO: Remove these null checks once all code is opted into strong nonnullable mode.
     if (string == null) throw new ArgumentError.notNull('string');
     if (start == null) throw new ArgumentError.notNull('start');
     if (start < 0 || start > string.length) {
       throw new RangeError.range(start, 0, string.length);
     }
-    List<int> list = _ExecuteMatchSticky(string, start);
+    final list = _ExecuteMatchSticky(string, start);
     if (list == null) return null;
     return new _RegExpMatch._(this, string, list);
   }
@@ -251,14 +251,14 @@
   bool hasMatch(String input) {
     // TODO: Remove these null checks once all code is opted into strong nonnullable mode.
     if (input == null) throw new ArgumentError.notNull('input');
-    List match = _ExecuteMatch(input, 0);
+    List? match = _ExecuteMatch(input, 0);
     return (match == null) ? false : true;
   }
 
-  String stringMatch(String input) {
+  String? stringMatch(String input) {
     // TODO: Remove these null checks once all code is opted into strong nonnullable mode.
     if (input == null) throw new ArgumentError.notNull('input');
-    List match = _ExecuteMatch(input, 0);
+    List? match = _ExecuteMatch(input, 0);
     if (match == null) {
       return null;
     }
@@ -344,9 +344,10 @@
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   ];
 
-  List _ExecuteMatch(String str, int start_index) native "RegExp_ExecuteMatch";
+  List<int>? _ExecuteMatch(String str, int start_index)
+      native "RegExp_ExecuteMatch";
 
-  List _ExecuteMatchSticky(String str, int start_index)
+  List<int>? _ExecuteMatchSticky(String str, int start_index)
       native "RegExp_ExecuteMatchSticky";
 }
 
@@ -364,12 +365,12 @@
 class _AllMatchesIterator implements Iterator<RegExpMatch> {
   final String _str;
   int _nextIndex;
-  _RegExp _re;
-  RegExpMatch _current;
+  _RegExp? _re;
+  RegExpMatch? _current;
 
   _AllMatchesIterator(this._re, this._str, this._nextIndex);
 
-  RegExpMatch get current => _current;
+  RegExpMatch get current => _current!;
 
   static bool _isLeadSurrogate(int c) {
     return c >= 0xd800 && c <= 0xdbff;
@@ -380,17 +381,19 @@
   }
 
   bool moveNext() {
-    if (_re == null) return false; // Cleared after a failed match.
+    final re = _re;
+    if (re == null) return false; // Cleared after a failed match.
     if (_nextIndex <= _str.length) {
-      var match = _re._ExecuteMatch(_str, _nextIndex);
+      final match = re._ExecuteMatch(_str, _nextIndex);
       if (match != null) {
-        _current = new _RegExpMatch._(_re, _str, match);
-        _nextIndex = _current.end;
-        if (_nextIndex == _current.start) {
+        var current = new _RegExpMatch._(re, _str, match);
+        _current = current;
+        _nextIndex = current.end;
+        if (_nextIndex == current.start) {
           // Zero-width match. Advance by one more, unless the regexp
           // is in unicode mode and it would put us within a surrogate
           // pair. In that case, advance past the code point as a whole.
-          if (_re.isUnicode &&
+          if (re.isUnicode &&
               _nextIndex + 1 < _str.length &&
               _isLeadSurrogate(_str.codeUnitAt(_nextIndex)) &&
               _isTrailSurrogate(_str.codeUnitAt(_nextIndex + 1))) {
diff --git a/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart
index 0f90f1e..3abbcb5 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart
@@ -8,17 +8,18 @@
 class _AsyncRun {
   @patch
   static void _scheduleImmediate(void callback()) {
-    if (_ScheduleImmediate._closure == null) {
+    final closure = _ScheduleImmediate._closure;
+    if (closure == null) {
       throw new UnsupportedError("Microtasks are not supported");
     }
-    _ScheduleImmediate._closure(callback);
+    closure(callback);
   }
 }
 
 typedef void _ScheduleImmediateClosure(void callback());
 
 class _ScheduleImmediate {
-  static _ScheduleImmediateClosure _closure;
+  static _ScheduleImmediateClosure? _closure;
 }
 
 @pragma("vm:entry-point", "call")
diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart
index e4eb156..0a1b06d 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart
@@ -127,7 +127,7 @@
     final localParts = _parts;
     return (_partsCodeUnits == 0 || localParts == null)
         ? ""
-        : _StringBase._concatRange(_parts, 0, localParts.length);
+        : _StringBase._concatRange(localParts, 0, localParts.length);
   }
 
   /** Ensures that the buffer has enough capacity to add n code units. */
@@ -148,7 +148,7 @@
   void _consumeBuffer() {
     if (_bufferPosition == 0) return;
     bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF;
-    String str = _create(_buffer, _bufferPosition, isLatin1);
+    String str = _create(_buffer!, _bufferPosition, isLatin1);
     _bufferPosition = _bufferCodeUnitMagnitude = 0;
     _addPart(str);
   }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
index 8d44760c..e9d094f 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
@@ -125,20 +125,22 @@
         (ccid != ClassID.cidGrowableObjectArray) &&
         (ccid != ClassID.cidImmutableArray)) {
       if (charCodes is Uint8List) {
-        final actualEnd = RangeError.checkValidRange(start, end, charCodes.length);
+        final actualEnd =
+            RangeError.checkValidRange(start, end, charCodes.length);
         return _createOneByteString(charCodes, start, actualEnd - start);
       } else if (charCodes is! Uint16List) {
         return _createStringFromIterable(charCodes, start, end);
       }
     }
     final int codeCount = charCodes.length;
-    final int actualEnd = RangeError.checkValidRange(start, end, codeCount);
+    final actualEnd = RangeError.checkValidRange(start, end, codeCount);
     final len = actualEnd - start;
     if (len == 0) return "";
 
     final typedCharCodes = unsafeCast<List<int>>(charCodes);
 
-    final int actualLimit = limit ?? _scanCodeUnits(typedCharCodes, start, actualEnd);
+    final int actualLimit =
+        limit ?? _scanCodeUnits(typedCharCodes, start, actualEnd);
     if (actualLimit < 0) {
       throw new ArgumentError(typedCharCodes);
     }
@@ -146,8 +148,8 @@
       return _createOneByteString(typedCharCodes, start, len);
     }
     if (actualLimit <= _maxUtf16) {
-      return _TwoByteString._allocateFromTwoByteList(typedCharCodes, start,
-          actualEnd);
+      return _TwoByteString._allocateFromTwoByteList(
+          typedCharCodes, start, actualEnd);
     }
     // TODO(lrn): Consider passing limit to _createFromCodePoints, because
     // the function is currently fully generic and doesn't know that its
@@ -170,9 +172,10 @@
     // Treat charCodes as Iterable.
     if (charCodes is EfficientLengthIterable) {
       int length = charCodes.length;
-      end = RangeError.checkValidRange(start, end, length);
-      final charCodeList =
-          new List<int>.from(charCodes.take(end).skip(start), growable: false);
+      final endVal = RangeError.checkValidRange(start, end, length);
+      final charCodeList = new List<int>.from(
+          charCodes.take(endVal).skip(start),
+          growable: false);
       return createFromCharCodes(charCodeList, 0, charCodeList.length, null);
     }
     // Don't know length of iterable, so iterate and see if all the values
@@ -186,7 +189,8 @@
     }
     List<int> charCodeList;
     int bits = 0; // Bitwise-or of all char codes in list.
-    if (end == null) {
+    final endVal = end;
+    if (endVal == null) {
       var list = <int>[];
       while (it.moveNext()) {
         int code = it.current;
@@ -195,21 +199,18 @@
       }
       charCodeList = makeListFixedLength<int>(list);
     } else {
-      if (end < start) {
-        throw new RangeError.range(end, start, charCodes.length);
+      if (endVal < start) {
+        throw new RangeError.range(endVal, start, charCodes.length);
       }
-      int len = end - start;
-      charCodeList = new List<int>.generate(
-        len,
-        (int i) {
-          if (!it.moveNext()) {
-            throw new RangeError.range(end, start, start + i);
-          }
-          int code = it.current;
-          bits |= code;
-          return code;
+      int len = endVal - start;
+      charCodeList = new List<int>.generate(len, (int i) {
+        if (!it.moveNext()) {
+          throw new RangeError.range(endVal, start, start + i);
         }
-      );
+        int code = it.current;
+        bits |= code;
+        return code;
+      });
     }
     int length = charCodeList.length;
     if (bits < 0) {
@@ -596,24 +597,24 @@
   }
 
   String replaceRange(int start, int? end, String replacement) {
-    int length = this.length;
-    end = RangeError.checkValidRange(start, end, length);
+    final length = this.length;
+    final localEnd = RangeError.checkValidRange(start, end, length);
     bool replacementIsOneByte = replacement._isOneByte;
-    if (start == 0 && end == length) return replacement;
+    if (start == 0 && localEnd == length) return replacement;
     int replacementLength = replacement.length;
-    int totalLength = start + (length - end) + replacementLength;
+    int totalLength = start + (length - localEnd) + replacementLength;
     if (replacementIsOneByte && this._isOneByte) {
       var result = _OneByteString._allocate(totalLength);
       int index = 0;
       index = result._setRange(index, this, 0, start);
       index = result._setRange(start, replacement, 0, replacementLength);
-      result._setRange(index, this, end, length);
+      result._setRange(index, this, localEnd, length);
       return result;
     }
     List slices = [];
     _addReplaceSlice(slices, 0, start);
     if (replacement.length > 0) slices.add(replacement);
-    _addReplaceSlice(slices, end, length);
+    _addReplaceSlice(slices, localEnd, length);
     return _joinReplaceAllResult(
         this, slices, totalLength, replacementIsOneByte);
   }
@@ -890,8 +891,8 @@
 
   List<String> split(Pattern pattern) {
     if ((pattern is String) && pattern.isEmpty) {
-      List<String> result = new List<String>.generate(
-        this.length, (int i) => this[i]);
+      List<String> result =
+          new List<String>.generate(this.length, (int i) => this[i]);
       return result;
     }
     int length = this.length;
@@ -900,7 +901,7 @@
       // A matched empty string input returns the empty list.
       return <String>[];
     }
-    List<String> result = new List<String>();
+    List<String> result = <String>[];
     int startIndex = 0;
     int previousIndex = 0;
     // 'pattern' may not be implemented correctly and therefore we cannot
@@ -1329,7 +1330,7 @@
   }
 
   List<String> groups(List<int> groups) {
-    List<String> result = new List<String>();
+    List<String> result = <String>[];
     for (int g in groups) {
       result.add(group(g));
     }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart
index 040ca66..b27f5e0 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart
@@ -43,7 +43,7 @@
   void remove(_Timer timer) {
     _used--;
     if (isEmpty) {
-      _list[0] = null;
+      _list[0] = _Timer._sentinelTimer;
       timer._indexOrNext = null;
       return;
     }
@@ -57,7 +57,7 @@
         _bubbleDown(last);
       }
     }
-    _list[_used] = null;
+    _list[_used] = _Timer._sentinelTimer;
     timer._indexOrNext = null;
   }
 
@@ -273,7 +273,7 @@
   // Handle the notification of a zero timer. Make sure to also execute non-zero
   // timers with a lower expiration time.
   static List _queueFromZeroEvent() {
-    var pendingTimers = [];
+    var pendingTimers = <dynamic>[];
     final firstTimer = _firstZeroTimer;
     if (firstTimer != null) {
       // Collect pending timers from the timer heap that have an expiration prior
@@ -324,7 +324,7 @@
   }
 
   static List _queueFromTimeoutEvent() {
-    var pendingTimers = new List();
+    var pendingTimers = [];
     final firstTimer = _firstZeroTimer;
     if (firstTimer != null) {
       // Collect pending timers from the timer heap that have an expiration
diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart
index c243a86..5e8b987 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart
@@ -8,16 +8,13 @@
 class Timer {
   @patch
   static Timer _createTimer(Duration duration, void callback()) {
-    // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
-    if (_TimerFactory._factory == null) {
-      _TimerFactory._factory = VMLibraryHooks.timerFactory;
-    }
-    if (_TimerFactory._factory == null) {
+    final factory = VMLibraryHooks.timerFactory;
+    if (factory == null) {
       throw new UnsupportedError("Timer interface not supported.");
     }
     int milliseconds = duration.inMilliseconds;
     if (milliseconds < 0) milliseconds = 0;
-    return _TimerFactory._factory(milliseconds, (_) {
+    return factory(milliseconds, (_) {
       callback();
     }, false);
   }
@@ -25,20 +22,12 @@
   @patch
   static Timer _createPeriodicTimer(
       Duration duration, void callback(Timer timer)) {
-    // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
-    _TimerFactory._factory ??= VMLibraryHooks.timerFactory;
-    if (_TimerFactory._factory == null) {
+    final factory = VMLibraryHooks.timerFactory;
+    if (factory == null) {
       throw new UnsupportedError("Timer interface not supported.");
     }
     int milliseconds = duration.inMilliseconds;
     if (milliseconds < 0) milliseconds = 0;
-    return _TimerFactory._factory(milliseconds, callback, true);
+    return factory(milliseconds, callback, true);
   }
 }
-
-typedef Timer _TimerFactoryClosure(
-    int milliseconds, void callback(Timer timer), bool repeating);
-
-class _TimerFactory {
-  static _TimerFactoryClosure _factory;
-}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
index df8fffc..1ed5de4 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
@@ -3474,8 +3474,13 @@
 class Float32x4 {
   @patch
   @pragma("vm:prefer-inline")
-  factory Float32x4(double x, double y, double z, double w) =>
-      _Float32x4FromDoubles(x, y, z, w);
+  factory Float32x4(double x, double y, double z, double w) {
+    _throwIfNull(x, 'x');
+    _throwIfNull(y, 'y');
+    _throwIfNull(z, 'z');
+    _throwIfNull(w, 'w');
+    return _Float32x4FromDoubles(x, y, z, w);
+  }
 
   @pragma("vm:exact-result-type", _Float32x4)
   static _Float32x4 _Float32x4FromDoubles(
@@ -3483,7 +3488,10 @@
 
   @patch
   @pragma("vm:prefer-inline")
-  factory Float32x4.splat(double v) => _Float32x4Splat(v);
+  factory Float32x4.splat(double v) {
+    _throwIfNull(v, 'v');
+    return _Float32x4Splat(v);
+  }
 
   @pragma("vm:exact-result-type", _Float32x4)
   static _Float32x4 _Float32x4Splat(double v) native "Float32x4_splat";
@@ -3547,14 +3555,42 @@
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
 
+  @pragma("vm:prefer-inline")
+  Float32x4 withX(double x) {
+    _throwIfNull(x, 'x');
+    return _withX(x);
+  }
+
   @pragma("vm:exact-result-type", _Float32x4)
-  Float32x4 withX(double x) native "Float32x4_setX";
+  Float32x4 _withX(double x) native "Float32x4_setX";
+
+  @pragma("vm:prefer-inline")
+  Float32x4 withY(double y) {
+    _throwIfNull(y, 'y');
+    return _withY(y);
+  }
+
   @pragma("vm:exact-result-type", _Float32x4)
-  Float32x4 withY(double y) native "Float32x4_setY";
+  Float32x4 _withY(double y) native "Float32x4_setY";
+
+  @pragma("vm:prefer-inline")
+  Float32x4 withZ(double z) {
+    _throwIfNull(z, 'z');
+    return _withZ(z);
+  }
+
   @pragma("vm:exact-result-type", _Float32x4)
-  Float32x4 withZ(double z) native "Float32x4_setZ";
+  Float32x4 _withZ(double z) native "Float32x4_setZ";
+
+  @pragma("vm:prefer-inline")
+  Float32x4 withW(double w) {
+    _throwIfNull(w, 'w');
+    return _withW(w);
+  }
+
   @pragma("vm:exact-result-type", _Float32x4)
-  Float32x4 withW(double w) native "Float32x4_setW";
+  Float32x4 _withW(double w) native "Float32x4_setW";
+
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 min(Float32x4 other) native "Float32x4_min";
   @pragma("vm:exact-result-type", _Float32x4)
@@ -3571,7 +3607,13 @@
 class Int32x4 {
   @patch
   @pragma("vm:prefer-inline")
-  factory Int32x4(int x, int y, int z, int w) => _Int32x4FromInts(x, y, z, w);
+  factory Int32x4(int x, int y, int z, int w) {
+    _throwIfNull(x, 'x');
+    _throwIfNull(y, 'y');
+    _throwIfNull(z, 'z');
+    _throwIfNull(w, 'w');
+    return _Int32x4FromInts(x, y, z, w);
+  }
 
   @pragma("vm:exact-result-type", _Int32x4)
   static _Int32x4 _Int32x4FromInts(int x, int y, int z, int w)
@@ -3579,8 +3621,13 @@
 
   @patch
   @pragma("vm:prefer-inline")
-  factory Int32x4.bool(bool x, bool y, bool z, bool w) =>
-      _Int32x4FromBools(x, y, z, w);
+  factory Int32x4.bool(bool x, bool y, bool z, bool w) {
+    _throwIfNull(x, 'x');
+    _throwIfNull(y, 'y');
+    _throwIfNull(z, 'z');
+    _throwIfNull(w, 'w');
+    return _Int32x4FromBools(x, y, z, w);
+  }
 
   @pragma("vm:exact-result-type", _Int32x4)
   static _Int32x4 _Int32x4FromBools(bool x, bool y, bool z, bool w)
@@ -3608,10 +3655,43 @@
   Int32x4 shuffle(int mask) native "Int32x4_shuffle";
   @pragma("vm:exact-result-type", _Int32x4)
   Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix";
-  Int32x4 withX(int x) native "Int32x4_setX";
-  Int32x4 withY(int y) native "Int32x4_setY";
-  Int32x4 withZ(int z) native "Int32x4_setZ";
-  Int32x4 withW(int w) native "Int32x4_setW";
+
+  @pragma("vm:prefer-inline")
+  Int32x4 withX(int x) {
+    _throwIfNull(x, 'x');
+    return _withX(x);
+  }
+
+  @pragma("vm:exact-result-type", _Int32x4)
+  Int32x4 _withX(int x) native "Int32x4_setX";
+
+  @pragma("vm:prefer-inline")
+  Int32x4 withY(int y) {
+    _throwIfNull(y, 'y');
+    return _withY(y);
+  }
+
+  @pragma("vm:exact-result-type", _Int32x4)
+  Int32x4 _withY(int y) native "Int32x4_setY";
+
+  @pragma("vm:prefer-inline")
+  Int32x4 withZ(int z) {
+    _throwIfNull(z, 'z');
+    return _withZ(z);
+  }
+
+  @pragma("vm:exact-result-type", _Int32x4)
+  Int32x4 _withZ(int z) native "Int32x4_setZ";
+
+  @pragma("vm:prefer-inline")
+  Int32x4 withW(int w) {
+    _throwIfNull(w, 'w');
+    return _withW(w);
+  }
+
+  @pragma("vm:exact-result-type", _Int32x4)
+  Int32x4 _withW(int w) native "Int32x4_setW";
+
   @pragma("vm:exact-result-type", bool)
   bool get flagX native "Int32x4_getFlagX";
   @pragma("vm:exact-result-type", bool)
@@ -3620,14 +3700,43 @@
   bool get flagZ native "Int32x4_getFlagZ";
   @pragma("vm:exact-result-type", bool)
   bool get flagW native "Int32x4_getFlagW";
+
+  @pragma("vm:prefer-inline", _Int32x4)
+  Int32x4 withFlagX(bool x) {
+    _throwIfNull(x, 'x');
+    return _withFlagX(x);
+  }
+
   @pragma("vm:exact-result-type", _Int32x4)
-  Int32x4 withFlagX(bool x) native "Int32x4_setFlagX";
+  Int32x4 _withFlagX(bool x) native "Int32x4_setFlagX";
+
+  @pragma("vm:prefer-inline", _Int32x4)
+  Int32x4 withFlagY(bool y) {
+    _throwIfNull(y, 'y');
+    return _withFlagY(y);
+  }
+
   @pragma("vm:exact-result-type", _Int32x4)
-  Int32x4 withFlagY(bool y) native "Int32x4_setFlagY";
+  Int32x4 _withFlagY(bool y) native "Int32x4_setFlagY";
+
+  @pragma("vm:prefer-inline", _Int32x4)
+  Int32x4 withFlagZ(bool z) {
+    _throwIfNull(z, 'z');
+    return _withFlagZ(z);
+  }
+
   @pragma("vm:exact-result-type", _Int32x4)
-  Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ";
+  Int32x4 _withFlagZ(bool z) native "Int32x4_setFlagZ";
+
+  @pragma("vm:prefer-inline", _Int32x4)
+  Int32x4 withFlagW(bool w) {
+    _throwIfNull(w, 'w');
+    return _withFlagW(w);
+  }
+
   @pragma("vm:exact-result-type", _Int32x4)
-  Int32x4 withFlagW(bool w) native "Int32x4_setFlagW";
+  Int32x4 _withFlagW(bool w) native "Int32x4_setFlagW";
+
   @pragma("vm:exact-result-type", _Float32x4)
   Float32x4 select(Float32x4 trueValue, Float32x4 falseValue)
       native "Int32x4_select";
@@ -3637,7 +3746,11 @@
 class Float64x2 {
   @patch
   @pragma("vm:prefer-inline")
-  factory Float64x2(double x, double y) => _Float64x2FromDoubles(x, y);
+  factory Float64x2(double x, double y) {
+    _throwIfNull(x, 'x');
+    _throwIfNull(y, 'y');
+    return _Float64x2FromDoubles(x, y);
+  }
 
   @pragma("vm:exact-result-type", _Float64x2)
   static _Float64x2 _Float64x2FromDoubles(double x, double y)
@@ -3645,7 +3758,10 @@
 
   @patch
   @pragma("vm:prefer-inline")
-  factory Float64x2.splat(double v) => _Float64x2Splat(v);
+  factory Float64x2.splat(double v) {
+    _throwIfNull(v, 'v');
+    return _Float64x2Splat(v);
+  }
 
   @pragma("vm:exact-result-type", _Float64x2)
   static _Float64x2 _Float64x2Splat(double v) native "Float64x2_splat";
@@ -3678,10 +3794,25 @@
   @pragma("vm:exact-result-type", "dart:core#_Double")
   double get y native "Float64x2_getY";
   int get signMask native "Float64x2_getSignMask";
+
+  @pragma("vm:prefer-inline")
+  Float64x2 withX(double x) {
+    _throwIfNull(x, 'x');
+    return _withX(x);
+  }
+
   @pragma("vm:exact-result-type", _Float64x2)
-  Float64x2 withX(double x) native "Float64x2_setX";
+  Float64x2 _withX(double x) native "Float64x2_setX";
+
+  @pragma("vm:prefer-inline")
+  Float64x2 withY(double y) {
+    _throwIfNull(y, 'y');
+    return _withY(y);
+  }
+
   @pragma("vm:exact-result-type", _Float64x2)
-  Float64x2 withY(double y) native "Float64x2_setY";
+  Float64x2 _withY(double y) native "Float64x2_setY";
+
   @pragma("vm:exact-result-type", _Float64x2)
   Float64x2 min(Float64x2 other) native "Float64x2_min";
   @pragma("vm:exact-result-type", _Float64x2)
@@ -3696,7 +3827,7 @@
   int _position;
   E? _current;
 
-  _TypedListIterator(List array)
+  _TypedListIterator(List<E> array)
       : _array = array,
         _length = array.length,
         _position = -1 {
@@ -4637,6 +4768,13 @@
   return value & 0xFFFFFFFF;
 }
 
+@pragma("vm:prefer-inline")
+void _throwIfNull(val, String name) {
+  if (val == null) {
+    throw ArgumentError.notNull(name);
+  }
+}
+
 // In addition to explicitly checking the range, this method implicitly ensures
 // that all arguments are non-null (a no such method error gets thrown
 // otherwise).
diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart
index bbf2eab..a489a6a 100644
--- a/sdk_nnbd/lib/async/future.dart
+++ b/sdk_nnbd/lib/async/future.dart
@@ -431,7 +431,7 @@
       if (remaining == 0) {
         return new Future<List<T>>.value(const <Never>[]);
       }
-      values = new List<T?>(remaining);
+      values = new List<T?>.filled(remaining, null);
     } catch (e, st) {
       // The error must have been thrown while iterating over the futures
       // list, or while installing a callback handler on the future.
diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart
index 257551b..e655d31 100644
--- a/sdk_nnbd/lib/async/stream_impl.dart
+++ b/sdk_nnbd/lib/async/stream_impl.dart
@@ -982,6 +982,7 @@
   ///
   /// After calling [moveNext] and the returned future has completed
   /// with `false`, or after calling [cancel]: `null`.
+  @pragma("vm:entry-point")
   Object? _stateData;
 
   /// Whether the iterator is between calls to `moveNext`.
diff --git a/sdk_nnbd/lib/collection/list.dart b/sdk_nnbd/lib/collection/list.dart
index 6f106e2..1619fc3 100644
--- a/sdk_nnbd/lib/collection/list.dart
+++ b/sdk_nnbd/lib/collection/list.dart
@@ -13,7 +13,7 @@
 /// `operator[]=` and `length=`, which need to be implemented.
 ///
 /// *NOTICE*: Forwarding just these four operations to a normal growable [List]
-/// (as created by `new List()`) will give very bad performance for `add` and
+/// (as created by `[]`) will give very bad performance for `add` and
 /// `addAll` operations of `ListBase`. These operations are implemented by
 /// increasing the length of the list by one for each `add` operation, and
 /// repeatedly increasing the length of a growable list is not efficient.
@@ -43,7 +43,7 @@
 /// `length=` and `operator[]=`
 ///
 /// *NOTICE*: Forwarding just these four operations to a normal growable [List]
-/// (as created by `new List()`) will give very bad performance for `add` and
+/// (as created by `[]`) will give very bad performance for `add` and
 /// `addAll` operations of `ListBase`. These operations are implemented by
 /// increasing the length of the list by one for each `add` operation, and
 /// repeatedly increasing the length of a growable list is not efficient.
diff --git a/sdk_nnbd/lib/collection/queue.dart b/sdk_nnbd/lib/collection/queue.dart
index 864ebfc..217b2d3 100644
--- a/sdk_nnbd/lib/collection/queue.dart
+++ b/sdk_nnbd/lib/collection/queue.dart
@@ -538,7 +538,7 @@
   ListQueue([int? initialCapacity])
       : _head = 0,
         _tail = 0,
-        _table = List<E?>(_calculateCapacity(initialCapacity));
+        _table = List<E?>.filled(_calculateCapacity(initialCapacity), null);
 
   static int _calculateCapacity(int? initialCapacity) {
     if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) {
@@ -840,7 +840,7 @@
 
   /// Grow the table when full.
   void _grow() {
-    List<E?> newTable = List<E?>(_table.length * 2);
+    List<E?> newTable = List<E?>.filled(_table.length * 2, null);
     int split = _table.length - _head;
     newTable.setRange(0, split, _table, _head);
     newTable.setRange(split, split + _head, _table, 0);
@@ -871,7 +871,7 @@
     // expansion.
     newElementCount += newElementCount >> 1;
     int newCapacity = _nextPowerOf2(newElementCount);
-    List<E?> newTable = List<E?>(newCapacity);
+    List<E?> newTable = List<E?>.filled(newCapacity, null);
     _tail = _writeToList(newTable);
     _table = newTable;
     _head = 0;
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
index 7e08ccb..a75dbb5 100644
--- a/sdk_nnbd/lib/convert/json.dart
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -712,7 +712,7 @@
       writeString("{}");
       return true;
     }
-    var keyValueList = List<Object?>(map.length * 2);
+    var keyValueList = List<Object?>.filled(map.length * 2, null);
     var i = 0;
     var allStringKeys = true;
     map.forEach((key, value) {
@@ -772,7 +772,7 @@
       writeString("{}");
       return true;
     }
-    var keyValueList = List<Object?>(map.length * 2);
+    var keyValueList = List<Object?>.filled(map.length * 2, null);
     var i = 0;
     var allStringKeys = true;
     map.forEach((key, value) {
diff --git a/sdk_nnbd/lib/core/iterable.dart b/sdk_nnbd/lib/core/iterable.dart
index 539a993..839792e 100644
--- a/sdk_nnbd/lib/core/iterable.dart
+++ b/sdk_nnbd/lib/core/iterable.dart
@@ -13,8 +13,12 @@
  * and if the call returns `true`,
  * the iterator has now moved to the next element,
  * which is then available as [Iterator.current].
- * If the call returns `false`, there are no more elements,
- * and `iterator.current` returns `null`.
+ * If the call returns `false`, there are no more elements.
+ * The [Iterator.current] value must only be used when the most
+ * recent call to [Iterator.moveNext] has returned `true`.
+ * If it is used before calling [Iterator.moveNext] the first time
+ * on an iterator, or after a call has returned false or has thrown an error,
+ * reading [Iterator.current] may throw or may return an arbitrary value.
  *
  * You can create more than one iterator from the same `Iterable`.
  * Each time `iterator` is read, it returns a new iterator,
diff --git a/sdk_nnbd/lib/core/iterator.dart b/sdk_nnbd/lib/core/iterator.dart
index 799388d..f116c1b 100644
--- a/sdk_nnbd/lib/core/iterator.dart
+++ b/sdk_nnbd/lib/core/iterator.dart
@@ -35,21 +35,23 @@
  */
 abstract class Iterator<E> {
   /**
-   * Moves to the next element.
+   * Advances the iterator to the next element of the iteration.
    *
-   * Returns true when [current] can be used to access the next element.
-   * Returns false if no elements are left.
+   * Should be called before reading [current].
+   * It the call to `moveNext` returns `true`,
+   * then [current] will contain the next element of the iteration
+   * until `moveNext` is called again.
+   * If the call returns `false`, there are no further elements
+   * and [current] should not be used any more.
    *
-   * It is safe to invoke [moveNext] even when the iterator is already
-   * positioned after the last element.
-   * In this case [moveNext] returns false again and has no effect.
+   * It is safe to call [moveNext] after it has already returned `false`,
+   * but it must keep returning `false` and not have any other effect.
    *
-   * A call to [moveNext] may throw if iteration has been broken by
-   * changing the underlying collection, or for other reasons specific to
-   * a particular iterator.
-   * The iterator should not be used after [moveNext] throws.
-   * If it is used, the value of [current] and the behavior of
-   * calling [moveNext] again are unspecified.
+   * A call to `moveNext` may throw for various reasons,
+   * including a concurrent change to an underlying collection.
+   * If that happens, the iterator may be in an inconsistent
+   * state, and any further behavior of the iterator is unspecified,
+   * including the effect of reading [current].
    */
   bool moveNext();
 
diff --git a/sdk_nnbd/lib/core/list.dart b/sdk_nnbd/lib/core/list.dart
index c204b65..c934195 100644
--- a/sdk_nnbd/lib/core/list.dart
+++ b/sdk_nnbd/lib/core/list.dart
@@ -16,7 +16,7 @@
  *
  * * Growable list. Full implementation of the API defined in this class.
  *
- * The default growable list, as returned by `new List()` or `[]`, keeps
+ * The default growable list, as created by `[]`, keeps
  * an internal buffer, and grows that buffer when necessary. This guarantees
  * that a sequence of [add] operations will each execute in amortized constant
  * time. Setting the length directly may take time proportional to the new
@@ -84,6 +84,13 @@
    *
    * If the element type is not nullable, [length] must not be greater than
    * zero.
+   *
+   * This constructor cannot be used in null-safe code.
+   * Use [List.filled] to create a non-empty list.
+   * This requires a fill value to initialize the list elements with.
+   * To create an empty list, use `[]` for a growable list or
+   * `List.empty` for a fixed length list (or where growability is determined
+   * at run-time).
    */
   external factory List([int? length]);
 
diff --git a/sdk_nnbd/lib/developer/profiler.dart b/sdk_nnbd/lib/developer/profiler.dart
index b7472f1..ae03350 100644
--- a/sdk_nnbd/lib/developer/profiler.dart
+++ b/sdk_nnbd/lib/developer/profiler.dart
@@ -128,6 +128,7 @@
   }
 
   // ignore: unused_element, called from native code
+  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
   static String? _printMetric(String id) {
     var metric = _metrics[id];
     if (metric == null) {
diff --git a/sdk_nnbd/lib/internal/iterable.dart b/sdk_nnbd/lib/internal/iterable.dart
index 394dcaa..55134af 100644
--- a/sdk_nnbd/lib/internal/iterable.dart
+++ b/sdk_nnbd/lib/internal/iterable.dart
@@ -572,7 +572,7 @@
   }
 
   E get current {
-    if (_isFinished) throw IterableElementError.noElement();
+    if (_isFinished) return null as E;
     return _iterator.current;
   }
 }
diff --git a/sdk_nnbd/lib/internal/list.dart b/sdk_nnbd/lib/internal/list.dart
index f1d59ff..0a8b6a9 100644
--- a/sdk_nnbd/lib/internal/list.dart
+++ b/sdk_nnbd/lib/internal/list.dart
@@ -302,7 +302,7 @@
  * Converts a growable list to a fixed length list with the same elements.
  *
  * For internal use only.
- * Only works on growable lists as created by `[]` or `new List()`.
+ * Only works on growable lists like the one created by `[]`.
  * May throw on any other list.
  *
  * The operation is efficient. It doesn't copy the elements, but converts
diff --git a/sdk_nnbd/lib/io/file_impl.dart b/sdk_nnbd/lib/io/file_impl.dart
index 3d302cc..ea8fb3f 100644
--- a/sdk_nnbd/lib/io/file_impl.dart
+++ b/sdk_nnbd/lib/io/file_impl.dart
@@ -848,7 +848,7 @@
       return new Future.error(e);
     }
 
-    List request = new List(4);
+    List request = new List.filled(4, null);
     request[0] = null;
     request[1] = result.buffer;
     request[2] = result.start;
diff --git a/sdk_nnbd/lib/io/secure_socket.dart b/sdk_nnbd/lib/io/secure_socket.dart
index e9b5759..6d23b13 100644
--- a/sdk_nnbd/lib/io/secure_socket.dart
+++ b/sdk_nnbd/lib/io/secure_socket.dart
@@ -1034,7 +1034,7 @@
 
   Future<_FilterStatus> _pushAllFilterStages() {
     bool wasInHandshake = _status != connectedStatus;
-    List args = new List(2 + bufferCount * 2);
+    List args = new List.filled(2 + bufferCount * 2, null);
     args[0] = _secureFilter._pointer();
     args[1] = wasInHandshake;
     var bufs = _secureFilter.buffers;
diff --git a/sdk_nnbd/lib/js/_js.dart b/sdk_nnbd/lib/js/_js.dart
index d0d51f6..aef7ef9 100644
--- a/sdk_nnbd/lib/js/_js.dart
+++ b/sdk_nnbd/lib/js/_js.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.5
-
 /// Helper library used by `dart:js`.
 ///
 /// This library hides any logic that is specific to the web, and allows us to
diff --git a/sdk_nnbd/lib/js/_js_client.dart b/sdk_nnbd/lib/js/_js_client.dart
index e81821a..de25540 100644
--- a/sdk_nnbd/lib/js/_js_client.dart
+++ b/sdk_nnbd/lib/js/_js_client.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.5
-
 import 'dart:html' show Blob, Event, ImageData, Node, Window, WorkerGlobalScope;
 import 'dart:indexed_db' show KeyRange;
 import 'dart:_js_helper' show patch;
diff --git a/sdk_nnbd/lib/js/_js_server.dart b/sdk_nnbd/lib/js/_js_server.dart
index 8ca6a02..b941d77 100644
--- a/sdk_nnbd/lib/js/_js_server.dart
+++ b/sdk_nnbd/lib/js/_js_server.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.5
-
 import 'dart:_js_helper' show patch;
 
 @patch
diff --git a/sdk_nnbd/lib/mirrors/mirrors.dart b/sdk_nnbd/lib/mirrors/mirrors.dart
index d8ed89f..573548e 100644
--- a/sdk_nnbd/lib/mirrors/mirrors.dart
+++ b/sdk_nnbd/lib/mirrors/mirrors.dart
@@ -149,7 +149,7 @@
  * function can only be used to obtain  mirrors on objects of the current
  * isolate.
  */
-external InstanceMirror reflect(Object reflectee);
+external InstanceMirror reflect(dynamic reflectee);
 
 /**
  * Reflects a class declaration.
@@ -400,11 +400,7 @@
    * If the invocation throws an exception *e* (that it does not catch), this
    * method throws *e*.
    */
-  /*
-   * TODO(turnidge): Handle ambiguous names.
-   * TODO(turnidge): Handle optional & named arguments.
-   */
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
+  InstanceMirror invoke(Symbol memberName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);
 
   /**
@@ -468,8 +464,7 @@
    * If the invocation throws an exception *e* (that it does not catch) this
    * method throws *e*.
    */
-  /* TODO(turnidge): Handle ambiguous names.*/
-  InstanceMirror setField(Symbol fieldName, Object value);
+  InstanceMirror setField(Symbol fieldName, dynamic value);
 
   /**
    * Performs [invocation] on the reflectee of this [ObjectMirror].
@@ -528,7 +523,7 @@
    * If you access [reflectee] when [hasReflectee] is false, an
    * exception is thrown.
    */
-  get reflectee;
+  dynamic get reflectee;
 
   /**
    * Whether this mirror is equal to [other].
@@ -596,7 +591,7 @@
    * If the invocation throws an exception *e* (that it does not catch), this
    * method throws *e*.
    */
-  InstanceMirror apply(List positionalArguments,
+  InstanceMirror apply(List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);
 }
 
@@ -844,11 +839,6 @@
    */
   ClassMirror get mixin;
 
-  // TODO(ahe): What about:
-  // /// Finds the instance member named [name] declared or inherited in the
-  // /// reflected class.
-  // DeclarationMirror instanceLookup(Symbol name);
-
   /**
    * Invokes the named constructor and returns a mirror on the result.
    *
@@ -877,7 +867,8 @@
    * * If evaluating the expression throws an exception *e* (that it does not
    *   catch), this method throws *e*.
    */
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
+  InstanceMirror newInstance(
+      Symbol constructorName, List<dynamic> positionalArguments,
       [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);
 
   /**
diff --git a/sdk_nnbd/lib/typed_data/typed_data.dart b/sdk_nnbd/lib/typed_data/typed_data.dart
index 66410cb..8852ab8 100644
--- a/sdk_nnbd/lib/typed_data/typed_data.dart
+++ b/sdk_nnbd/lib/typed_data/typed_data.dart
@@ -12,7 +12,7 @@
 /// {@category Core}
 library dart.typed_data;
 
-import "dart:_internal" show UnmodifiableListBase;
+import "dart:_internal" show Since, UnmodifiableListBase;
 
 part "unmodifiable_typed_data.dart";
 
@@ -440,15 +440,28 @@
  * with ordinary [List] implementations.
  * `ByteData` can save space, by eliminating the need for object headers,
  * and time, by eliminating the need for data copies.
+ *
+ * If data comes in as bytes, they can be converted to `ByteData` by
+ * sharing the same buffer.
+ * ```dart
+ * Uint8List bytes = ...;
+ * var blob = ByteData.sublistView(bytes);
+ * if (blob.getUint32(0, Endian.little) == 0x04034b50) { // Zip file marker
+ *   ...
+ * }
+ *
+ * ```
+ *
  * Finally, `ByteData` may be used to intentionally reinterpret the bytes
  * representing one arithmetic type as another.
  * For example this code fragment determine what 32-bit signed integer
- * is represented by the bytes of a 32-bit floating point number:
- *
- *     var buffer = new Uint8List(8).buffer;
- *     var bdata = new ByteData.view(buffer);
- *     bdata.setFloat32(0, 3.04);
- *     int huh = bdata.getInt32(0);
+ * is represented by the bytes of a 32-bit floating point number
+ * (both stored as big endian):
+ * ```dart
+ * var bdata = new ByteData(8);
+ * bdata.setFloat32(0, 3.04);
+ * int huh = bdata.getInt32(0); // 0x40428f5c
+ * ```
  */
 abstract class ByteData implements TypedData {
   /**
@@ -471,6 +484,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `ByteData.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * ByteData.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [ByteData.sublistView]
+   * which includes this computation:
+   * ```dart
+   * ByteData.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory ByteData.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -478,6 +508,35 @@
   }
 
   /**
+   * Creates a [ByteData] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory ByteData.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null)
+      throw "unreachable"; // TODO(38725): Remove when promotion works.
+    return data.buffer.asByteData(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns the (possibly negative) integer represented by the byte at the
    * specified [byteOffset] in this object, in two's complement binary
    * representation.
@@ -741,6 +800,8 @@
   /**
    * Creates an [Int8List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Int8List(int length);
 
@@ -750,6 +811,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Int8List.fromList(List<int> elements);
 
@@ -766,6 +830,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int8List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int8List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int8List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Int8List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int8List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -773,6 +854,34 @@
   }
 
   /**
+   * Creates an [Int8List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Int8List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    return data.buffer.asInt8List(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int8List` containing the elements of this list at
@@ -814,6 +923,8 @@
   /**
    * Creates a [Uint8List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Uint8List(int length);
 
@@ -823,6 +934,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Uint8List.fromList(List<int> elements);
 
@@ -839,6 +953,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint8List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint8List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint8List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Uint8List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint8List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -846,6 +977,34 @@
   }
 
   /**
+   * Creates a [Uint8List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Uint8List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    return data.buffer.asUint8List(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a concatenation of this list and [other].
    *
    * If [other] is also a typed-data list, then the return list will be a
@@ -896,6 +1055,8 @@
   /**
    * Creates a [Uint8ClampedList] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
    */
   external factory Uint8ClampedList(int length);
 
@@ -905,6 +1066,9 @@
    *
    * Values are clamped to fit in the list when they are copied,
    * the same way storing values clamps them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
+   * bytes.
    */
   external factory Uint8ClampedList.fromList(List<int> elements);
 
@@ -922,6 +1086,23 @@
    * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
    * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
    * the length of [buffer].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint8ClampedList.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint8ClampedList.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint8ClampedList.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Uint8ClampedList.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint8ClampedList.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -929,6 +1110,35 @@
   }
 
   /**
+   * Creates a [Uint8ClampedList] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   */
+  @Since("2.8")
+  factory Uint8ClampedList.sublistView(TypedData data,
+      [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    return data.buffer.asUint8ClampedList(
+        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint8ClampedList` containing the elements of this
@@ -971,6 +1181,9 @@
   /**
    * Creates an [Int16List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 2 bytes.
    */
   external factory Int16List(int length);
 
@@ -980,6 +1193,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 2 bytes.
    */
   external factory Int16List.fromList(List<int> elements);
 
@@ -999,6 +1215,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int16List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int16List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int16List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Int16List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int16List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1006,6 +1239,42 @@
   }
 
   /**
+   * Creates an [Int16List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of two.
+   */
+  @Since("2.8")
+  factory Int16List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt16List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int16List` containing the elements of this
@@ -1048,6 +1317,9 @@
   /**
    * Creates a [Uint16List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 2 bytes.
    */
   external factory Uint16List(int length);
 
@@ -1057,6 +1329,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 2 bytes.
    */
   external factory Uint16List.fromList(List<int> elements);
 
@@ -1077,6 +1352,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint16List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint16List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint16List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Uint16List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint16List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1084,6 +1376,42 @@
   }
 
   /**
+   * Creates a [Uint16List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of two.
+   */
+  @Since("2.8")
+  factory Uint16List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint16List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint16List` containing the elements of this
@@ -1126,6 +1454,9 @@
   /**
    * Creates an [Int32List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Int32List(int length);
 
@@ -1135,6 +1466,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Int32List.fromList(List<int> elements);
 
@@ -1154,6 +1488,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int32List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Int32List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1161,6 +1512,42 @@
   }
 
   /**
+   * Creates an [Int32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Int32List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int32List` containing the elements of this
@@ -1203,6 +1590,9 @@
   /**
    * Creates a [Uint32List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Uint32List(int length);
 
@@ -1212,6 +1602,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Uint32List.fromList(List<int> elements);
 
@@ -1232,6 +1625,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint32List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Uint32List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1239,6 +1649,42 @@
   }
 
   /**
+   * Creates a [Uint32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Uint32List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint32List` containing the elements of this
@@ -1281,6 +1727,9 @@
   /**
    * Creates an [Int64List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Int64List(int length);
 
@@ -1290,6 +1739,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Int64List.fromList(List<int> elements);
 
@@ -1309,6 +1761,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int64List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Int64List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1316,6 +1785,42 @@
   }
 
   /**
+   * Creates an [Int64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Int64List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is an `Int64List` containing the elements of this
@@ -1358,6 +1863,9 @@
   /**
    * Creates a [Uint64List] of the specified length (in elements), all
    * of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Uint64List(int length);
 
@@ -1367,6 +1875,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Uint64List.fromList(List<int> elements);
 
@@ -1387,6 +1898,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Uint64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Uint64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Uint64List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Uint64List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Uint64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1394,6 +1922,42 @@
   }
 
   /**
+   * Creates a [Uint64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Uint64List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asUint64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Uint64List` containing the elements of this
@@ -1437,6 +2001,9 @@
   /**
    * Creates a [Float32List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 4 bytes.
    */
   external factory Float32List(int length);
 
@@ -1446,6 +2013,9 @@
    *
    * Values are truncated to fit in the list when they are copied,
    * the same way storing values truncates them.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 4 bytes.
    */
   external factory Float32List.fromList(List<double> elements);
 
@@ -1465,6 +2035,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float32List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float32List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float32List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Float32List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float32List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1472,6 +2059,42 @@
   }
 
   /**
+   * Creates an [Float32List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of four.
+   */
+  @Since("2.8")
+  factory Float32List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat32List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float32List` containing the elements of this
@@ -1511,12 +2134,18 @@
   /**
    * Creates a [Float64List] of the specified length (in elements), all of
    * whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 8 bytes.
    */
   external factory Float64List(int length);
 
   /**
    * Creates a [Float64List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 8 bytes.
    */
   external factory Float64List.fromList(List<double> elements);
 
@@ -1536,6 +2165,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float64List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float64List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float64List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Float64List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float64List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1543,6 +2189,42 @@
   }
 
   /**
+   * Creates a [Float64List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of eight.
+   */
+  @Since("2.8")
+  factory Float64List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat64List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float64List` containing the elements of this
@@ -1581,12 +2263,18 @@
   /**
    * Creates a [Float32x4List] of the specified length (in elements),
    * all of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Float32x4List(int length);
 
   /**
    * Creates a [Float32x4List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Float32x4List.fromList(List<Float32x4> elements);
 
@@ -1606,6 +2294,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float32x4List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float32x4List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float32x4List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Float32x4List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float32x4List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1613,6 +2318,42 @@
   }
 
   /**
+   * Creates a [Float32x4List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Float32x4List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat32x4List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns the concatenation of this list and [other].
    *
    * If [other] is also a [Float32x4List], the result is a new [Float32x4List],
@@ -1659,12 +2400,18 @@
   /**
    * Creates a [Int32x4List] of the specified length (in elements),
    * all of whose elements are initially zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Int32x4List(int length);
 
   /**
    * Creates a [Int32x4List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Int32x4List.fromList(List<Int32x4> elements);
 
@@ -1684,6 +2431,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Int32x4List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Int32x4List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Int32x4List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Int32x4List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Int32x4List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1691,6 +2455,42 @@
   }
 
   /**
+   * Creates an [Int32x4List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Int32x4List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asInt32x4List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns the concatenation of this list and [other].
    *
    * If [other] is also a [Int32x4List], the result is a new [Int32x4List],
@@ -1737,12 +2537,18 @@
   /**
    * Creates a [Float64x2List] of the specified length (in elements),
    * all of whose elements have all lanes set to zero.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * [length] times 16 bytes.
    */
   external factory Float64x2List(int length);
 
   /**
    * Creates a [Float64x2List] with the same length as the [elements] list
    * and copies over the elements.
+   *
+   * The list is backed by a [ByteBuffer] containing precisely
+   * `elements.length` times 16 bytes.
    */
   external factory Float64x2List.fromList(List<Float64x2> elements);
 
@@ -1770,6 +2576,23 @@
    *
    * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
    * [bytesPerElement].
+   *
+   * Note that when creating a view from a [TypedData] list or byte data,
+   * that list or byte data may itself be a view on a larger buffer
+   * with a [TypedData.offsetInBytes] greater than zero.
+   * Merely doing `Float64x2List.view(other.buffer, 0, count)` may not
+   * point to the bytes you intended. Instead you may need to do:
+   * ```dart
+   * Float64x2List.view(other.buffer, other.offsetInBytes, count)
+   * ```
+   * Alternatively, use [Float64x2List.sublistView]
+   * which includes this computation:
+   * ```dart
+   * Float64x2List.sublistView(other, 0, count);
+   * ```
+   * (The third argument is an end index rather than a length, so if
+   * you start from a position greater than zero, you need not
+   * reduce the count correspondingly).
    */
   factory Float64x2List.view(ByteBuffer buffer,
       [int offsetInBytes = 0, int? length]) {
@@ -1777,6 +2600,42 @@
   }
 
   /**
+   * Creates an [Float64x2List] view on a range of elements of [data].
+   *
+   * Creates a view on the range of `data.buffer` which corresponds
+   * to the elements of [data] from [start] until [end].
+   * If [data] is a typed data list, like [Uint16List], then the view is on
+   * the bytes of the elements with indices from [start] until [end].
+   * If [data] is a [ByteData], it's treated like a list of bytes.
+   *
+   * If provided, [start] and [end] must satisfy
+   *
+   * 0 &le; `start` &le; `end` &le; *elementCount*
+   *
+   * where *elementCount* is the number of elements in [data], which
+   * is the same as the [List.length] of a typed data list.
+   *
+   * If omitted, [start] defaults to zero and [end] to *elementCount*.
+   *
+   * The start and end indices of the range of bytes being viewed must be
+   * multiples of sixteen.
+   */
+  @Since("2.8")
+  factory Float64x2List.sublistView(TypedData data, [int start = 0, int? end]) {
+    int elementSize = data.elementSizeInBytes;
+    end = RangeError.checkValidRange(
+        start, end, data.lengthInBytes ~/ elementSize);
+    if (end == null) throw "unreachable"; // TODO(38725)
+    int byteLength = (end - start) * elementSize;
+    if (byteLength % bytesPerElement != 0) {
+      throw ArgumentError("The number of bytes to view must be a multiple of " +
+          "$bytesPerElement");
+    }
+    return data.buffer.asFloat64x2List(data.offsetInBytes + start * elementSize,
+        byteLength ~/ bytesPerElement);
+  }
+
+  /**
    * Returns a new list containing the elements between [start] and [end].
    *
    * The new list is a `Float64x2List` containing the elements of this
diff --git a/tests/compiler/dart2js/analyses/dart2js_allowed.json b/tests/compiler/dart2js/analyses/dart2js_allowed.json
index d97b7b7..8881b99 100644
--- a/tests/compiler/dart2js/analyses/dart2js_allowed.json
+++ b/tests/compiler/dart2js/analyses/dart2js_allowed.json
@@ -149,9 +149,6 @@
   "pkg/compiler/lib/src/serialization/binary_sink.dart": {
     "Dynamic access of 'index'.": 1
   },
-  "pkg/compiler/lib/src/native/behavior.dart": {
-    "Dynamic invocation of 'add'.": 1
-  },
   "pkg/compiler/lib/src/util/enumset.dart": {
     "Dynamic access of 'index'.": 4
   },
@@ -240,10 +237,6 @@
     "Dynamic access of 'named'.": 2,
     "Dynamic invocation of '[]'.": 2
   },
-  "pkg/compiler/lib/src/universe/function_set.dart": {
-    "Dynamic access of 'selector'.": 1,
-    "Dynamic access of 'receiver'.": 1
-  },
   "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": {
     "Dynamic access of 'superclass'.": 1,
     "Dynamic access of 'needsTearOff'.": 1
@@ -264,4 +257,4 @@
   "pkg/compiler/lib/src/ssa/value_set.dart": {
     "Dynamic invocation of 'add'.": 2
   }
-}
\ No newline at end of file
+}
diff --git a/tests/compiler/dart2js_extra/40296_test.dart b/tests/compiler/dart2js_extra/40296_test.dart
new file mode 100644
index 0000000..989b6f7
--- /dev/null
+++ b/tests/compiler/dart2js_extra/40296_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, 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.
+
+@JS()
+library test;
+
+import 'dart:async';
+import 'dart:_interceptors';
+import 'dart:js' as js;
+import 'package:expect/expect.dart';
+import 'package:js/js.dart';
+
+const String JS_CODE = """
+function A() {
+  this.x = 1;
+}
+self.foo = new A();
+""";
+
+@JS('A')
+@anonymous
+class Foo {}
+
+@JS('foo')
+external dynamic get foo;
+
+main() {
+  js.context.callMethod('eval', [JS_CODE]);
+  Expect.isTrue(foo is FutureOr<Foo>);
+  Expect.isTrue(foo is JSObject);
+}
diff --git a/tests/ffi/callback_tests_utils.dart b/tests/ffi/callback_tests_utils.dart
new file mode 100644
index 0000000..ac5fdcb
--- /dev/null
+++ b/tests/ffi/callback_tests_utils.dart
@@ -0,0 +1,34 @@
+// 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:ffi';
+
+import 'dylib_utils.dart';
+
+import "package:expect/expect.dart";
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+typedef NativeCallbackTest = Int32 Function(Pointer);
+typedef NativeCallbackTestFn = int Function(Pointer);
+
+class CallbackTest {
+  final String name;
+  final Pointer callback;
+  final bool skip;
+
+  CallbackTest(this.name, this.callback, {bool skipIf: false})
+      : skip = skipIf {}
+
+  void run() {
+    if (skip) return;
+
+    final NativeCallbackTestFn tester = ffiTestFunctions
+        .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
+    final int testCode = tester(callback);
+    if (testCode != 0) {
+      Expect.fail("Test $name failed.");
+    }
+  }
+}
diff --git a/tests/ffi/function_callbacks_many_test.dart b/tests/ffi/function_callbacks_many_test.dart
index d187093..c8fb519 100644
--- a/tests/ffi/function_callbacks_many_test.dart
+++ b/tests/ffi/function_callbacks_many_test.dart
@@ -16,33 +16,7 @@
 
 import 'dart:ffi';
 
-import "package:expect/expect.dart";
-
-import 'dylib_utils.dart';
-
-typedef NativeCallbackTest = Int32 Function(Pointer);
-typedef NativeCallbackTestFn = int Function(Pointer);
-
-final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions");
-
-class Test {
-  final String name;
-  final Pointer callback;
-  final bool skip;
-
-  Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {}
-
-  void run() {
-    if (skip) return;
-
-    final NativeCallbackTestFn tester = testLibrary
-        .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
-    final int testCode = tester(callback);
-    if (testCode != 0) {
-      Expect.fail("Test $name failed.");
-    }
-  }
-}
+import 'callback_tests_utils.dart';
 
 typedef SimpleAdditionType = Int32 Function(Int32, Int32);
 int simpleAddition(int x, int y) => x + y;
@@ -1064,6 +1038,6 @@
   pointers.add(Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 999));
 
   for (final pointer in pointers) {
-    Test("SimpleAddition", pointer).run();
+    CallbackTest("SimpleAddition", pointer).run();
   }
 }
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart
index 33a9fc1..24ca064 100644
--- a/tests/ffi/function_callbacks_test.dart
+++ b/tests/ffi/function_callbacks_test.dart
@@ -16,33 +16,7 @@
 
 import 'dart:ffi';
 
-import "package:expect/expect.dart";
-
-import 'dylib_utils.dart';
-
-typedef NativeCallbackTest = Int32 Function(Pointer);
-typedef NativeCallbackTestFn = int Function(Pointer);
-
-final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions");
-
-class Test {
-  final String name;
-  final Pointer callback;
-  final bool skip;
-
-  Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {}
-
-  void run() {
-    if (skip) return;
-
-    final NativeCallbackTestFn tester = testLibrary
-        .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
-    final int testCode = tester(callback);
-    if (testCode != 0) {
-      Expect.fail("Test $name failed.");
-    }
-  }
-}
+import 'callback_tests_utils.dart';
 
 typedef SimpleAdditionType = Int32 Function(Int32, Int32);
 int simpleAddition(int x, int y) {
@@ -212,34 +186,36 @@
   return 0xabcff;
 }
 
-final List<Test> testcases = [
-  Test("SimpleAddition",
+final testcases = [
+  CallbackTest("SimpleAddition",
       Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
-  Test("IntComputation",
+  CallbackTest("IntComputation",
       Pointer.fromFunction<IntComputationType>(intComputation, 0)),
-  Test("UintComputation",
+  CallbackTest("UintComputation",
       Pointer.fromFunction<UintComputationType>(uintComputation, 0)),
-  Test("SimpleMultiply",
+  CallbackTest("SimpleMultiply",
       Pointer.fromFunction<SimpleMultiplyType>(simpleMultiply, 0.0)),
-  Test("SimpleMultiplyFloat",
+  CallbackTest("SimpleMultiplyFloat",
       Pointer.fromFunction<SimpleMultiplyFloatType>(simpleMultiplyFloat, 0.0)),
-  Test("ManyInts", Pointer.fromFunction<ManyIntsType>(manyInts, 0)),
-  Test("ManyDoubles", Pointer.fromFunction<ManyDoublesType>(manyDoubles, 0.0)),
-  Test("ManyArgs", Pointer.fromFunction<ManyArgsType>(manyArgs, 0.0)),
-  Test("Store", Pointer.fromFunction<StoreType>(store)),
-  Test("NullPointers", Pointer.fromFunction<NullPointersType>(nullPointers)),
-  Test("ReturnVoid", Pointer.fromFunction<ReturnVoid>(returnVoid)),
-  Test("ThrowExceptionDouble",
+  CallbackTest("ManyInts", Pointer.fromFunction<ManyIntsType>(manyInts, 0)),
+  CallbackTest(
+      "ManyDoubles", Pointer.fromFunction<ManyDoublesType>(manyDoubles, 0.0)),
+  CallbackTest("ManyArgs", Pointer.fromFunction<ManyArgsType>(manyArgs, 0.0)),
+  CallbackTest("Store", Pointer.fromFunction<StoreType>(store)),
+  CallbackTest(
+      "NullPointers", Pointer.fromFunction<NullPointersType>(nullPointers)),
+  CallbackTest("ReturnVoid", Pointer.fromFunction<ReturnVoid>(returnVoid)),
+  CallbackTest("ThrowExceptionDouble",
       Pointer.fromFunction<ThrowExceptionDouble>(throwExceptionDouble, 42.0)),
-  Test("ThrowExceptionPointer",
+  CallbackTest("ThrowExceptionPointer",
       Pointer.fromFunction<ThrowExceptionPointer>(throwExceptionPointer)),
-  Test("ThrowException",
+  CallbackTest("ThrowException",
       Pointer.fromFunction<ThrowExceptionInt>(throwExceptionInt, 42)),
-  Test("TakeMaxUint8x10",
+  CallbackTest("TakeMaxUint8x10",
       Pointer.fromFunction<TakeMaxUint8x10Type>(takeMaxUint8x10, 0)),
-  Test("ReturnMaxUint8",
+  CallbackTest("ReturnMaxUint8",
       Pointer.fromFunction<ReturnMaxUint8Type>(returnMaxUint8, 0)),
-  Test("ReturnMaxUint8",
+  CallbackTest("ReturnMaxUint8",
       Pointer.fromFunction<ReturnMaxUint8Type>(returnMaxUint8v2, 0)),
 ];
 
diff --git a/tests/ffi/function_callbacks_very_many_test.dart b/tests/ffi/function_callbacks_very_many_test.dart
new file mode 100644
index 0000000..383b482
--- /dev/null
+++ b/tests/ffi/function_callbacks_very_many_test.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program for testing dart:ffi function pointers with callbacks.
+//
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--enable-testing-pragmas
+// VMOptions=--enable-testing-pragmas --stacktrace-every=100
+// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code
+// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
+// VMOptions=--use-slow-path --enable-testing-pragmas
+// VMOptions=--use-slow-path --enable-testing-pragmas --stacktrace-every=100
+// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code
+// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+import 'callback_tests_utils.dart';
+
+final testcases = [
+  CallbackTest("SumVeryManySmallInts",
+      Pointer.fromFunction<NativeVeryManyIntsOp>(sumVeryManySmallInts, 0)),
+  CallbackTest(
+      "SumVeryManyFloatsDoubles",
+      Pointer.fromFunction<NativeVeryManyFloatsDoublesOp>(
+          sumVeryManyDoubles, 0.0)),
+];
+
+void main() {
+  for (int i = 0; i < 100; ++i) {
+    testcases.forEach((t) => t.run());
+  }
+}
+
+int sumVeryManySmallInts(
+    int _1,
+    int _2,
+    int _3,
+    int _4,
+    int _5,
+    int _6,
+    int _7,
+    int _8,
+    int _9,
+    int _10,
+    int _11,
+    int _12,
+    int _13,
+    int _14,
+    int _15,
+    int _16,
+    int _17,
+    int _18,
+    int _19,
+    int _20,
+    int _21,
+    int _22,
+    int _23,
+    int _24,
+    int _25,
+    int _26,
+    int _27,
+    int _28,
+    int _29,
+    int _30,
+    int _31,
+    int _32,
+    int _33,
+    int _34,
+    int _35,
+    int _36,
+    int _37,
+    int _38,
+    int _39,
+    int _40) {
+  print("sumVeryManySmallInts(" +
+      "$_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10, " +
+      "$_11, $_12, $_13, $_14, $_15, $_16, $_17, $_18, $_19, $_20, " +
+      "$_21, $_22, $_23, $_24, $_25, $_26, $_27, $_28, $_29, $_30, " +
+      "$_31, $_32, $_33, $_34, $_35, $_36, $_37, $_38, $_39, $_40)");
+  return _1 +
+      _2 +
+      _3 +
+      _4 +
+      _5 +
+      _6 +
+      _7 +
+      _8 +
+      _9 +
+      _10 +
+      _11 +
+      _12 +
+      _13 +
+      _14 +
+      _15 +
+      _16 +
+      _17 +
+      _18 +
+      _19 +
+      _20 +
+      _21 +
+      _22 +
+      _23 +
+      _24 +
+      _25 +
+      _26 +
+      _27 +
+      _28 +
+      _29 +
+      _30 +
+      _31 +
+      _32 +
+      _33 +
+      _34 +
+      _35 +
+      _36 +
+      _37 +
+      _38 +
+      _39 +
+      _40;
+}
+
+double sumVeryManyDoubles(
+    double _1,
+    double _2,
+    double _3,
+    double _4,
+    double _5,
+    double _6,
+    double _7,
+    double _8,
+    double _9,
+    double _10,
+    double _11,
+    double _12,
+    double _13,
+    double _14,
+    double _15,
+    double _16,
+    double _17,
+    double _18,
+    double _19,
+    double _20,
+    double _21,
+    double _22,
+    double _23,
+    double _24,
+    double _25,
+    double _26,
+    double _27,
+    double _28,
+    double _29,
+    double _30,
+    double _31,
+    double _32,
+    double _33,
+    double _34,
+    double _35,
+    double _36,
+    double _37,
+    double _38,
+    double _39,
+    double _40) {
+  print("sumVeryManyDoubles(" +
+      "$_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10, " +
+      "$_11, $_12, $_13, $_14, $_15, $_16, $_17, $_18, $_19, $_20, " +
+      "$_21, $_22, $_23, $_24, $_25, $_26, $_27, $_28, $_29, $_30, " +
+      "$_31, $_32, $_33, $_34, $_35, $_36, $_37, $_38, $_39, $_40)");
+  return _1 +
+      _2 +
+      _3 +
+      _4 +
+      _5 +
+      _6 +
+      _7 +
+      _8 +
+      _9 +
+      _10 +
+      _11 +
+      _12 +
+      _13 +
+      _14 +
+      _15 +
+      _16 +
+      _17 +
+      _18 +
+      _19 +
+      _20 +
+      _21 +
+      _22 +
+      _23 +
+      _24 +
+      _25 +
+      _26 +
+      _27 +
+      _28 +
+      _29 +
+      _30 +
+      _31 +
+      _32 +
+      _33 +
+      _34 +
+      _35 +
+      _36 +
+      _37 +
+      _38 +
+      _39 +
+      _40;
+}
+
+typedef NativeVeryManyIntsOp = Int16 Function(
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16);
+
+typedef NativeVeryManyFloatsDoublesOp = Double Function(
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double);
diff --git a/tests/ffi/function_very_many_test.dart b/tests/ffi/function_very_many_test.dart
new file mode 100644
index 0000000..8056617
--- /dev/null
+++ b/tests/ffi/function_very_many_test.dart
@@ -0,0 +1,299 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing dart:ffi calls argument passing.
+//
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+// VMOptions=--write-protect-code --no-dual-map-code
+// VMOptions=--write-protect-code --no-dual-map-code --use-slow-path
+// VMOptions=--write-protect-code --no-dual-map-code --stacktrace-every=100
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+import 'dylib_utils.dart';
+
+import "package:expect/expect.dart";
+
+void main() {
+  for (int i = 0; i < 100; ++i) {
+    testSumVeryManySmallInts();
+    testSumVeryManyFloatsDoubles();
+  }
+}
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+VeryManyIntsOp sumVeryManySmallInts =
+    ffiTestFunctions.lookupFunction<NativeVeryManyIntsOp, VeryManyIntsOp>(
+        "SumVeryManySmallInts");
+// Very many small integers, tests alignment on stack.
+void testSumVeryManySmallInts() {
+  Expect.equals(
+      40 * 41 / 2,
+      sumVeryManySmallInts(
+          1,
+          2,
+          3,
+          4,
+          5,
+          6,
+          7,
+          8,
+          9,
+          10,
+          11,
+          12,
+          13,
+          14,
+          15,
+          16,
+          17,
+          18,
+          19,
+          20,
+          21,
+          22,
+          23,
+          24,
+          25,
+          26,
+          27,
+          28,
+          29,
+          30,
+          31,
+          32,
+          33,
+          34,
+          35,
+          36,
+          37,
+          38,
+          39,
+          40));
+}
+
+VeryManyFloatsDoublesOp sumVeryManyFloatsDoubles = ffiTestFunctions
+    .lookupFunction<NativeVeryManyFloatsDoublesOp, VeryManyFloatsDoublesOp>(
+        "SumVeryManyFloatsDoubles");
+
+// Very many floating points, tests alignment on stack, and packing in
+// floating point registers in hardfp.
+void testSumVeryManyFloatsDoubles() {
+  Expect.approxEquals(
+      40.0 * 41.0 / 2.0,
+      sumVeryManyFloatsDoubles(
+          1.0,
+          2.0,
+          3.0,
+          4.0,
+          5.0,
+          6.0,
+          7.0,
+          8.0,
+          9.0,
+          10.0,
+          11.0,
+          12.0,
+          13.0,
+          14.0,
+          15.0,
+          16.0,
+          17.0,
+          18.0,
+          19.0,
+          20.0,
+          21.0,
+          22.0,
+          23.0,
+          24.0,
+          25.0,
+          26.0,
+          27.0,
+          28.0,
+          29.0,
+          30.0,
+          31.0,
+          32.0,
+          33.0,
+          34.0,
+          35.0,
+          36.0,
+          37.0,
+          38.0,
+          39.0,
+          40.0));
+}
+
+typedef NativeVeryManyIntsOp = Int16 Function(
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16,
+    Int8,
+    Int16);
+
+typedef VeryManyIntsOp = int Function(
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int,
+    int);
+
+typedef NativeVeryManyFloatsDoublesOp = Double Function(
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double,
+    Float,
+    Double);
+
+typedef VeryManyFloatsDoublesOp = double Function(
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double,
+    double);
diff --git a/tests/ffi/hardfp_test.dart b/tests/ffi/hardfp_test.dart
new file mode 100644
index 0000000..600e26b
--- /dev/null
+++ b/tests/ffi/hardfp_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing dart:ffi function pointers.
+//
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+// VMOptions=--write-protect-code --no-dual-map-code
+// VMOptions=--write-protect-code --no-dual-map-code --use-slow-path
+// VMOptions=--write-protect-code --no-dual-map-code --stacktrace-every=100
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'callback_tests_utils.dart';
+import 'dylib_utils.dart';
+
+void main() {
+  for (int i = 0; i < 100; ++i) {
+    testSumFloatsAndDoubles();
+    testSumFloatsAndDoublesCallback();
+  }
+}
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final sumFloatsAndDoubles = ffiTestFunctions.lookupFunction<
+    Double Function(Float, Double, Float),
+    double Function(double, double, double)>("SumFloatsAndDoubles");
+
+void testSumFloatsAndDoubles() {
+  Expect.approxEquals(6.0, sumFloatsAndDoubles(1.0, 2.0, 3.0));
+}
+
+void testSumFloatsAndDoublesCallback() {
+  CallbackTest(
+          "SumFloatsAndDoubles",
+          Pointer.fromFunction<Double Function(Float, Double, Float)>(
+              sumFloatsAndDoublesDart, 0.0))
+      .run();
+}
+
+double sumFloatsAndDoublesDart(double a, double b, double c) {
+  print("sumFloatsAndDoublesDart($a, $b, $c)");
+  return a + b + c;
+}
diff --git a/tests/ffi/vmspecific_function_callbacks_exit_test.dart b/tests/ffi/vmspecific_function_callbacks_exit_test.dart
index b28dea9..e7f33a2 100644
--- a/tests/ffi/vmspecific_function_callbacks_exit_test.dart
+++ b/tests/ffi/vmspecific_function_callbacks_exit_test.dart
@@ -10,41 +10,27 @@
 import 'dart:io';
 import 'dart:ffi';
 import 'dart:isolate';
+
 import "package:expect/expect.dart";
+
+import 'callback_tests_utils.dart';
 import 'dylib_utils.dart';
 
-typedef NativeCallbackTest = Int32 Function(Pointer);
-typedef NativeCallbackTestFn = int Function(Pointer);
-final DynamicLibrary testLibrary = dlopenPlatformSpecific("ffi_test_functions");
-
-class Test {
-  final String name;
-  final Pointer callback;
-  final bool skip;
-  Test(this.name, this.callback, {bool skipIf: false}) : skip = skipIf {}
-  void run() {
-    if (skip) return;
-    print("Test $name.");
-    final NativeCallbackTestFn tester = testLibrary
-        .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
-    final int testCode = tester(callback);
-    if (testCode != 0) {
-      Expect.fail("Test $name failed.");
-    }
-  }
-}
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
 
 typedef ReturnVoid = Void Function();
 void returnVoid() {}
 testCallbackWrongThread() {
   print("Test CallbackWrongThread.");
-  Test("CallbackWrongThread", Pointer.fromFunction<ReturnVoid>(returnVoid))
+  CallbackTest(
+          "CallbackWrongThread", Pointer.fromFunction<ReturnVoid>(returnVoid))
       .run();
 }
 
 testCallbackOutsideIsolate() {
   print("Test CallbackOutsideIsolate.");
-  Test("CallbackOutsideIsolate", Pointer.fromFunction<ReturnVoid>(returnVoid))
+  CallbackTest("CallbackOutsideIsolate",
+          Pointer.fromFunction<ReturnVoid>(returnVoid))
       .run();
 }
 
diff --git a/tests/ffi/vmspecific_function_callbacks_test.dart b/tests/ffi/vmspecific_function_callbacks_test.dart
index 53c0119..99a036b 100644
--- a/tests/ffi/vmspecific_function_callbacks_test.dart
+++ b/tests/ffi/vmspecific_function_callbacks_test.dart
@@ -20,7 +20,12 @@
 import 'dart:ffi';
 
 import 'ffi_test_helpers.dart';
-import 'function_callbacks_test.dart' show Test, testLibrary, ReturnVoid;
+import 'callback_tests_utils.dart';
+import 'dylib_utils.dart';
+
+typedef ReturnVoid = Void Function();
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
 
 void testGC() {
   triggerGc();
@@ -35,9 +40,9 @@
       "WaitForHelper")(helper);
 }
 
-final List<Test> testcases = [
-  Test("GC", Pointer.fromFunction<ReturnVoid>(testGC)),
-  Test("UnprotectCode",
+final testcases = [
+  CallbackTest("GC", Pointer.fromFunction<ReturnVoid>(testGC)),
+  CallbackTest("UnprotectCode",
       Pointer.fromFunction<WaitForHelperNative>(waitForHelper)),
 ];
 
diff --git a/tests/language/nnbd/subtyping/mixed_bottom_type_lib.dart b/tests/language/nnbd/subtyping/mixed_bottom_type_lib.dart
new file mode 100644
index 0000000..b39f800
--- /dev/null
+++ b/tests/language/nnbd/subtyping/mixed_bottom_type_lib.dart
@@ -0,0 +1,7 @@
+// 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.
+
+// Note: this library is opted-in to null safety, so the String parameter is
+// non-nullable.
+void stringFunction(String x) {}
diff --git a/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart b/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart
new file mode 100644
index 0000000..5044d65
--- /dev/null
+++ b/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// @dart = 2.6
+
+// Requirements=nnbd-strong
+
+import 'package:expect/expect.dart';
+import 'mixed_bottom_type_lib.dart';
+
+main() {
+  // The subtype check `void Function(String) <: void Function(Null)` should be
+  // false in strong mode semantics since `Null </: String`.
+  Expect.isFalse(stringFunction is void Function(Null));
+}
diff --git a/tests/language/nnbd/subtyping/mixed_bottom_type_weak_test.dart b/tests/language/nnbd/subtyping/mixed_bottom_type_weak_test.dart
new file mode 100644
index 0000000..a1034d5
--- /dev/null
+++ b/tests/language/nnbd/subtyping/mixed_bottom_type_weak_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// @dart = 2.6
+
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+import 'mixed_bottom_type_lib.dart';
+
+main() {
+  // The subtype check `void Function(String) <: void Function(Null)` should be
+  // true in weak mode semantics since `Null` is considered a bottom type in
+  // legacy subtyping rules.
+  Expect.isTrue(stringFunction is void Function(Null));
+}
diff --git a/tests/lib_2/profiler/metrics_num_test.dart b/tests/lib/developer/metrics_num_test.dart
similarity index 100%
copy from tests/lib_2/profiler/metrics_num_test.dart
copy to tests/lib/developer/metrics_num_test.dart
diff --git a/tests/lib/developer/metrics_test.dart b/tests/lib/developer/metrics_test.dart
new file mode 100644
index 0000000..c836e96
--- /dev/null
+++ b/tests/lib/developer/metrics_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2014, 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:developer';
+import 'package:expect/expect.dart';
+
+testGauge1() {
+  var gauge = new Gauge('test', 'alpha bravo', 0.0, 100.0);
+  Expect.equals(0.0, gauge.min);
+  Expect.equals(0.0, gauge.value);
+  Expect.equals(100.0, gauge.max);
+  Expect.equals('test', gauge.name);
+  Expect.equals('alpha bravo', gauge.description);
+  gauge.value = 44.0;
+  Expect.equals(44.0, gauge.value);
+  // Test setting below min.
+  gauge.value = -1.0;
+  Expect.equals(0.0, gauge.value);
+  // Test setting above max.
+  gauge.value = 101.0;
+  Expect.equals(100.0, gauge.value);
+}
+
+testGauge2() {
+  var gauge = new Gauge('test', 'alpha bravo', 1.0, 2.0);
+  Expect.equals(1.0, gauge.min);
+  Expect.equals(2.0, gauge.max);
+  Expect.equals(gauge.min, gauge.value);
+  Expect.equals('test', gauge.name);
+  Expect.equals('alpha bravo', gauge.description);
+
+  Expect.throws(() {
+    // min argument > max argument .
+    gauge = new Gauge('test', 'alpha bravo', 2.0, 1.0);
+  });
+
+  Expect.throws(() {
+    // min argument  == max argument .
+    gauge = new Gauge('test', 'alpha bravo', 1.0, 1.0);
+  });
+
+  Expect.throws(() {
+    // min argument is null
+    gauge = new Gauge('test', 'alpha bravo', null as dynamic, 1.0);
+  });
+
+  Expect.throws(() {
+    // min argument is not a double
+    gauge = new Gauge('test', 'alpha bravo', 'string' as dynamic, 1.0);
+  });
+
+  Expect.throws(() {
+    // max argument is null
+    gauge = new Gauge('test', 'alpha bravo', 1.0, null as dynamic);
+  });
+}
+
+testCounter() {
+  var counter = new Counter('test', 'alpha bravo');
+  Expect.equals(0.0, counter.value);
+  Expect.equals('test', counter.name);
+  Expect.equals('alpha bravo', counter.description);
+  counter.value = 1.0;
+  Expect.equals(1.0, counter.value);
+}
+
+class CustomCounter extends Counter {
+  CustomCounter(name, description) : super(name, description);
+  // User provided getter.
+  double get value => 77.0;
+}
+
+testCustomCounter() {
+  var counter = new CustomCounter('test', 'alpha bravo');
+  Expect.equals(77.0, counter.value);
+  Expect.equals('test', counter.name);
+  Expect.equals('alpha bravo', counter.description);
+  // Should have no effect.
+  counter.value = 1.0;
+  Expect.equals(77.0, counter.value);
+}
+
+testMetricNameCollision() {
+  var counter = new Counter('a.b.c', 'alpha bravo charlie');
+  var counter2 = new Counter('a.b.c', 'alpha bravo charlie collider');
+  Metrics.register(counter);
+  Expect.throws(() {
+    Metrics.register(counter2);
+  });
+  Metrics.deregister(counter);
+  Metrics.register(counter);
+  var counter3 = new Counter('a.b.c.d', '');
+  Metrics.register(counter3);
+}
+
+testBadName() {
+  Expect.throws(() {
+    var counter = new Counter('a.b/c', 'description');
+  });
+  Expect.throws(() {
+    var counter = new Counter('vm', 'description');
+  });
+}
+
+main() {
+  testGauge1();
+  testGauge2();
+  testCounter();
+  testCustomCounter();
+  testMetricNameCollision();
+  testBadName();
+}
diff --git a/tests/lib_2/profiler/user_tags_test.dart b/tests/lib/developer/user_tags_test.dart
similarity index 100%
copy from tests/lib_2/profiler/user_tags_test.dart
copy to tests/lib/developer/user_tags_test.dart
diff --git a/tests/lib/lib_dart2js.status b/tests/lib/lib_dart2js.status
index cc91517..3119691 100644
--- a/tests/lib/lib_dart2js.status
+++ b/tests/lib/lib_dart2js.status
@@ -5,6 +5,7 @@
 [ $compiler == dart2js ]
 convert/chunked_conversion_utf88_test: Slow
 convert/utf85_test: Slow
+developer/metrics_num_test: Skip # Because of an int / double type test.
 developer/timeline_test: Skip # Not supported
 html/async_test: SkipByDesign
 html/custom/document_register_basic_test: Slow
@@ -22,7 +23,9 @@
 html/xhr_test: Slow
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-profiler/metrics_num_test: Skip # Because of an int / double type test.
+typed_data/int64_list_load_store_test: SkipByDesign # dart2js does not support Int64List
+typed_data/typed_data_hierarchy_int64_test: SkipByDesign # dart2js does not support Int64List
+typed_data/unmodifiable_typed_data_test: SkipByDesign # dart2js does not support Int64List
 wasm/*: SkipByDesign # dart:wasm not currently supported on web.
 
 [ $compiler != dart2js ]
@@ -95,4 +98,3 @@
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
-
diff --git a/tests/lib/lib_dartdevc.status b/tests/lib/lib_dartdevc.status
index b3c2a53..2b4741b 100644
--- a/tests/lib/lib_dartdevc.status
+++ b/tests/lib/lib_dartdevc.status
@@ -22,6 +22,7 @@
 convert/json_utf8_chunk_test: Slow
 convert/streamed_conversion_utf8_decode_test: Slow # Issue 29922
 convert/utf85_test: Slow
+developer/metrics_num_test: Skip # Because of an int / double type test.
 html/callback_list_test: Skip # Test requires user interaction to accept permissions.
 html/custom/attribute_changed_callback_test: Skip # Issue 31577
 html/custom/constructor_calls_created_synchronously_test: Skip # Issue 31577
@@ -46,4 +47,6 @@
 html/notification_permission_test: Skip # Issue 32002
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-profiler/metrics_num_test: Skip # Because of an int / double type test.
+typed_data/int64_list_load_store_test: SkipByDesign # dartdevk/c does not support Int64List
+typed_data/typed_data_hierarchy_int64_test: SkipByDesign # dartdevk/c does not support Int64List
+typed_data/unmodifiable_typed_data_test: SkipByDesign # dartdevk/c does not support Int64List
diff --git a/tests/lib/mirrors/abstract_class_test.dart b/tests/lib/mirrors/abstract_class_test.dart
new file mode 100644
index 0000000..285d032
--- /dev/null
+++ b/tests/lib/mirrors/abstract_class_test.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2014, 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 test.abstract_class_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+void main() {
+  testSimple();
+  testFunctionType();
+  testFakeFunction();
+  testGeneric();
+  testAnonMixinApplication();
+  testNamedMixinApplication();
+}
+
+abstract class Foo {
+  foo();
+}
+
+class Bar extends Foo {
+  foo() {}
+}
+
+testSimple() {
+  Expect.isTrue(reflectClass(Foo).isAbstract);
+  Expect.isFalse(reflectClass(Bar).isAbstract);
+  Expect.isTrue(reflect(new Bar()).type.superclass!.isAbstract);
+  Expect.isFalse(reflect(new Bar()).type.isAbstract);
+}
+
+void baz() {}
+
+testFunctionType() {
+  Expect.isFalse(reflect(baz).type.isAbstract);
+}
+
+abstract class FunctionFoo implements Function {
+  call();
+}
+
+class FunctionBar extends FunctionFoo {
+  call() {}
+}
+
+testFakeFunction() {
+  Expect.isTrue(reflectClass(FunctionFoo).isAbstract);
+  Expect.isFalse(reflectClass(FunctionBar).isAbstract);
+  Expect.isTrue(reflect(new FunctionBar()).type.superclass!.isAbstract);
+  Expect.isFalse(reflect(new FunctionBar()).type.isAbstract);
+}
+
+abstract class GenericFoo<T> {
+  T genericFoo();
+}
+
+class GenericBar<T> extends GenericFoo<T> {
+  T genericFoo() {}
+}
+
+testGeneric() {
+  // Unbound.
+  Expect.isTrue(reflectClass(GenericFoo).isAbstract);
+  Expect.isFalse(reflectClass(GenericBar).isAbstract);
+  // Bound.
+  Expect.isTrue(reflect(new GenericBar<int>()).type.superclass!.isAbstract);
+  Expect.isFalse(reflect(new GenericBar<int>()).type.isAbstract);
+}
+
+class S {}
+
+abstract class M {
+  mixinFoo();
+}
+
+abstract class MA extends S with M {}
+
+class SubMA extends MA {
+  mixinFoo() {}
+}
+
+class ConcreteMA extends S with M {
+  mixinFoo() {}
+}
+
+class M2 {
+  mixin2Foo() {}
+}
+
+abstract class MA2 extends S with M2 {
+  mixinBar();
+}
+
+class SubMA2 extends MA2 {
+  mixinBar() {}
+}
+
+class ConcreteMA2 extends S with M2 {
+  mixin2Foo() {}
+}
+
+testAnonMixinApplication() {
+  // Application is abstract.
+  {
+    // Mixin is abstract.
+    Expect.isFalse(reflectClass(SubMA).isAbstract);
+    Expect.isTrue(reflectClass(SubMA).superclass!.isAbstract);
+    Expect.isTrue(reflectClass(SubMA).superclass!.superclass!.isAbstract);
+    Expect.isTrue(reflectClass(MA).isAbstract);
+    Expect.isTrue(reflectClass(MA).superclass!.isAbstract);
+
+    // Mixin is concrete.
+    Expect.isFalse(reflectClass(SubMA2).isAbstract);
+    Expect.isTrue(reflectClass(SubMA2).superclass!.isAbstract);
+    Expect.isTrue(reflectClass(SubMA2).superclass!.superclass!.isAbstract);
+    Expect.isTrue(reflectClass(MA2).isAbstract);
+    Expect.isTrue(reflectClass(MA2).superclass!.isAbstract);
+  }
+
+  // Application is concrete.
+  {
+    // Mixin is abstract.
+    Expect.isFalse(reflectClass(ConcreteMA).isAbstract);
+    Expect.isTrue(reflectClass(ConcreteMA).superclass!.isAbstract);
+    Expect.isFalse(reflectClass(ConcreteMA).superclass!.superclass!.isAbstract);
+
+    // Mixin is concrete.
+    Expect.isFalse(reflectClass(ConcreteMA2).isAbstract);
+    Expect.isTrue(reflectClass(ConcreteMA2).superclass!.isAbstract);
+    Expect.isFalse(
+        reflectClass(ConcreteMA2).superclass!.superclass!.isAbstract);
+  }
+}
+
+abstract class NamedMA = S with M;
+
+class SubNamedMA extends NamedMA {
+  mixinFoo() {}
+}
+
+abstract class NamedMA2 = S with M2;
+
+class SubNamedMA2 extends NamedMA2 {
+  mixinFoo() {}
+}
+
+class ConcreteNamedMA2 = S with M2;
+
+testNamedMixinApplication() {
+  // Application is abstract.
+  {
+    // Mixin is abstract.
+    Expect.isFalse(reflectClass(SubNamedMA).isAbstract);
+    Expect.isTrue(reflectClass(SubNamedMA).superclass!.isAbstract);
+    Expect.isFalse(reflectClass(SubNamedMA).superclass!.superclass!.isAbstract);
+    Expect.isTrue(reflectClass(NamedMA).isAbstract);
+    Expect.isFalse(reflectClass(NamedMA).superclass!.isAbstract);
+
+    // Mixin is concrete.
+    Expect.isFalse(reflectClass(SubNamedMA2).isAbstract);
+    Expect.isTrue(reflectClass(SubNamedMA2).superclass!.isAbstract);
+    Expect.isFalse(
+        reflectClass(SubNamedMA2).superclass!.superclass!.isAbstract);
+    Expect.isTrue(reflectClass(NamedMA2).isAbstract);
+    Expect.isFalse(reflectClass(NamedMA2).superclass!.isAbstract);
+  }
+
+  // Application is concrete.
+  {
+    // Mixin is concrete.
+    Expect.isFalse(reflectClass(ConcreteNamedMA2).isAbstract);
+    Expect.isFalse(reflectClass(ConcreteNamedMA2).superclass!.isAbstract);
+  }
+}
diff --git a/tests/lib/mirrors/abstract_test.dart b/tests/lib/mirrors/abstract_test.dart
new file mode 100644
index 0000000..aad20b2
--- /dev/null
+++ b/tests/lib/mirrors/abstract_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test abstract classes are retained.
+
+library test.abstract_test;
+
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+abstract class Foo {}
+
+void main() {
+  expect(
+      'Class(s(Foo) in s(test.abstract_test), top-level)', reflectClass(Foo));
+}
diff --git a/tests/lib/mirrors/accessor_cache_overflow_test.dart b/tests/lib/mirrors/accessor_cache_overflow_test.dart
new file mode 100644
index 0000000..5703ea1
--- /dev/null
+++ b/tests/lib/mirrors/accessor_cache_overflow_test.dart
@@ -0,0 +1,308 @@
+// Copyright (c) 2014, 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.
+
+// This test runs invokes getField and setField enough times to get cached
+// closures generated and with enough different field names to trip the path
+// that flushes the closure cache.
+
+library test.hot_get_field;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+const int optimizationThreshold = 20;
+
+main() {
+  var digits = [
+    '0',
+    '1',
+    '2',
+    '3',
+    '4',
+    '5',
+    '6',
+    '7',
+    '8',
+    '9',
+    'A',
+    'B',
+    'C',
+    'D',
+    'E',
+    'F'
+  ];
+  var symbols = new List();
+  for (var high in digits) {
+    for (var low in digits) {
+      symbols.add(MirrorSystem.getSymbol("v$high$low"));
+    }
+  }
+
+  var im = reflect(new C());
+  for (var i = 0; i < optimizationThreshold * 2; i++) {
+    for (var fieldName in symbols) {
+      im.getField(fieldName);
+      im.setField(fieldName, 'foo');
+    }
+  }
+}
+
+class C {
+  var v00;
+  var v01;
+  var v02;
+  var v03;
+  var v04;
+  var v05;
+  var v06;
+  var v07;
+  var v08;
+  var v09;
+  var v0A;
+  var v0B;
+  var v0C;
+  var v0D;
+  var v0E;
+  var v0F;
+  var v10;
+  var v11;
+  var v12;
+  var v13;
+  var v14;
+  var v15;
+  var v16;
+  var v17;
+  var v18;
+  var v19;
+  var v1A;
+  var v1B;
+  var v1C;
+  var v1D;
+  var v1E;
+  var v1F;
+  var v20;
+  var v21;
+  var v22;
+  var v23;
+  var v24;
+  var v25;
+  var v26;
+  var v27;
+  var v28;
+  var v29;
+  var v2A;
+  var v2B;
+  var v2C;
+  var v2D;
+  var v2E;
+  var v2F;
+  var v30;
+  var v31;
+  var v32;
+  var v33;
+  var v34;
+  var v35;
+  var v36;
+  var v37;
+  var v38;
+  var v39;
+  var v3A;
+  var v3B;
+  var v3C;
+  var v3D;
+  var v3E;
+  var v3F;
+  var v40;
+  var v41;
+  var v42;
+  var v43;
+  var v44;
+  var v45;
+  var v46;
+  var v47;
+  var v48;
+  var v49;
+  var v4A;
+  var v4B;
+  var v4C;
+  var v4D;
+  var v4E;
+  var v4F;
+  var v50;
+  var v51;
+  var v52;
+  var v53;
+  var v54;
+  var v55;
+  var v56;
+  var v57;
+  var v58;
+  var v59;
+  var v5A;
+  var v5B;
+  var v5C;
+  var v5D;
+  var v5E;
+  var v5F;
+  var v60;
+  var v61;
+  var v62;
+  var v63;
+  var v64;
+  var v65;
+  var v66;
+  var v67;
+  var v68;
+  var v69;
+  var v6A;
+  var v6B;
+  var v6C;
+  var v6D;
+  var v6E;
+  var v6F;
+  var v70;
+  var v71;
+  var v72;
+  var v73;
+  var v74;
+  var v75;
+  var v76;
+  var v77;
+  var v78;
+  var v79;
+  var v7A;
+  var v7B;
+  var v7C;
+  var v7D;
+  var v7E;
+  var v7F;
+  var v80;
+  var v81;
+  var v82;
+  var v83;
+  var v84;
+  var v85;
+  var v86;
+  var v87;
+  var v88;
+  var v89;
+  var v8A;
+  var v8B;
+  var v8C;
+  var v8D;
+  var v8E;
+  var v8F;
+  var v90;
+  var v91;
+  var v92;
+  var v93;
+  var v94;
+  var v95;
+  var v96;
+  var v97;
+  var v98;
+  var v99;
+  var v9A;
+  var v9B;
+  var v9C;
+  var v9D;
+  var v9E;
+  var v9F;
+  var vA0;
+  var vA1;
+  var vA2;
+  var vA3;
+  var vA4;
+  var vA5;
+  var vA6;
+  var vA7;
+  var vA8;
+  var vA9;
+  var vAA;
+  var vAB;
+  var vAC;
+  var vAD;
+  var vAE;
+  var vAF;
+  var vB0;
+  var vB1;
+  var vB2;
+  var vB3;
+  var vB4;
+  var vB5;
+  var vB6;
+  var vB7;
+  var vB8;
+  var vB9;
+  var vBA;
+  var vBB;
+  var vBC;
+  var vBD;
+  var vBE;
+  var vBF;
+  var vC0;
+  var vC1;
+  var vC2;
+  var vC3;
+  var vC4;
+  var vC5;
+  var vC6;
+  var vC7;
+  var vC8;
+  var vC9;
+  var vCA;
+  var vCB;
+  var vCC;
+  var vCD;
+  var vCE;
+  var vCF;
+  var vD0;
+  var vD1;
+  var vD2;
+  var vD3;
+  var vD4;
+  var vD5;
+  var vD6;
+  var vD7;
+  var vD8;
+  var vD9;
+  var vDA;
+  var vDB;
+  var vDC;
+  var vDD;
+  var vDE;
+  var vDF;
+  var vE0;
+  var vE1;
+  var vE2;
+  var vE3;
+  var vE4;
+  var vE5;
+  var vE6;
+  var vE7;
+  var vE8;
+  var vE9;
+  var vEA;
+  var vEB;
+  var vEC;
+  var vED;
+  var vEE;
+  var vEF;
+  var vF0;
+  var vF1;
+  var vF2;
+  var vF3;
+  var vF4;
+  var vF5;
+  var vF6;
+  var vF7;
+  var vF8;
+  var vF9;
+  var vFA;
+  var vFB;
+  var vFC;
+  var vFD;
+  var vFE;
+  var vFF;
+}
diff --git a/tests/lib/mirrors/apply3_test.dart b/tests/lib/mirrors/apply3_test.dart
new file mode 100644
index 0000000..d96fa0d
--- /dev/null
+++ b/tests/lib/mirrors/apply3_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test [Function.apply] on user-defined classes that implement [noSuchMethod].
+
+import "package:expect/expect.dart";
+import 'dart:mirrors';
+
+class F {
+  call([p1]) => "call";
+  noSuchMethod(Invocation invocation) => "NSM";
+}
+
+class G {
+  call() => '42';
+  noSuchMethod(Invocation invocation) => invocation;
+}
+
+class H {
+  call(required, {a}) => required + a;
+}
+
+main() {
+  Expect.equals('call', Function.apply(new F(), []));
+  Expect.equals('call', Function.apply(new F(), [1]));
+  Expect.equals('NSM', Function.apply(new F(), [1, 2]));
+  Expect.equals('NSM', Function.apply(new F(), [1, 2, 3]));
+
+  var symbol = const Symbol('a');
+  var requiredParameters = [1];
+  var optionalParameters = new Map<Symbol, int>()..[symbol] = 42;
+  Invocation i =
+      Function.apply(new G(), requiredParameters, optionalParameters);
+
+  Expect.equals(const Symbol('call'), i.memberName);
+  Expect.listEquals(requiredParameters, i.positionalArguments);
+  Expect.mapEquals(optionalParameters, i.namedArguments);
+  Expect.isTrue(i.isMethod);
+  Expect.isFalse(i.isGetter);
+  Expect.isFalse(i.isSetter);
+  Expect.isFalse(i.isAccessor);
+
+  // Check that changing the passed list and map for parameters does
+  // not affect [i].
+  requiredParameters[0] = 42;
+  optionalParameters[symbol] = 12;
+  Expect.listEquals([1], i.positionalArguments);
+  Expect.mapEquals(new Map()..[symbol] = 42, i.namedArguments);
+
+  // Check that using [i] for invocation yields the same [Invocation]
+  // object.
+  var mirror = reflect(new G());
+  Invocation other = mirror.delegate(i);
+  Expect.equals(i.memberName, other.memberName);
+  Expect.listEquals(i.positionalArguments, other.positionalArguments);
+  Expect.mapEquals(i.namedArguments, other.namedArguments);
+  Expect.equals(i.isMethod, other.isMethod);
+  Expect.equals(i.isGetter, other.isGetter);
+  Expect.equals(i.isSetter, other.isSetter);
+  Expect.equals(i.isAccessor, other.isAccessor);
+
+  // Test that [i] can be used to hit an existing method.
+  Expect.equals(43, new H().call(1, a: 42));
+  Expect.equals(43, Function.apply(new H(), [1], new Map()..[symbol] = 42));
+  mirror = reflect(new H());
+  Expect.equals(43, mirror.delegate(i));
+  Expect.equals(43, mirror.delegate(other));
+}
diff --git a/tests/lib/mirrors/array_tracing2_test.dart b/tests/lib/mirrors/array_tracing2_test.dart
new file mode 100644
index 0000000..39411a1
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing2_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+class A {
+  var field;
+}
+
+main() {
+  var a = new A();
+  var mirror = reflect(a);
+  var array = [42];
+  a.field = array;
+  var field = mirror.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/array_tracing3_test.dart b/tests/lib/mirrors/array_tracing3_test.dart
new file mode 100644
index 0000000..092feac
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing3_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+class A {
+  static var field;
+}
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror a = reflectClass(A);
+  var array = [42];
+  A.field = array;
+  var field = a.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/array_tracing_test.dart b/tests/lib/mirrors/array_tracing_test.dart
new file mode 100644
index 0000000..092feac
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+class A {
+  static var field;
+}
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror a = reflectClass(A);
+  var array = [42];
+  A.field = array;
+  var field = a.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/bad_argument_types_test.dart b/tests/lib/mirrors/bad_argument_types_test.dart
new file mode 100644
index 0000000..6544df8
--- /dev/null
+++ b/tests/lib/mirrors/bad_argument_types_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+int foobar = 1;
+
+set foobaz(int x) {
+  foobar = x;
+}
+
+void foo(Map<String, String> m) {
+  print(m);
+  print(m['bar']);
+}
+
+void bar<T extends num>(T a) {
+  print(a);
+}
+
+class Foo {
+  Map<String, String>? bork;
+  static Map<String, String>? bark;
+  static set woof(Map<String, String> x) {
+    bark = x;
+  }
+
+  Foo(Map<String, String> m) {
+    print(m);
+  }
+
+  Foo.a();
+
+  static void baz(Map<String, String> m, {String? bar}) {
+    print('baz');
+    print(m['bar']);
+    print(bar);
+  }
+
+  void bar(Map<String, String> m) {
+    print('bar');
+    print(m.runtimeType);
+  }
+}
+
+class FooBar<T extends num> {
+  T bar;
+  FooBar(this.bar) {
+    print(bar);
+  }
+
+  set barz(T x) {
+    bar = x;
+  }
+
+  factory FooBar.baz(T bar) {
+    print(bar);
+    return FooBar(bar);
+  }
+
+  void foobar<S>(T a, S b) {
+    print(a);
+    print(b);
+  }
+}
+
+void badClassStaticInvoke() {
+  Map<String, String> map = Map<String, String>();
+  map['bar'] = 'Hello world!';
+  final cm = reflectClass(Foo);
+  Expect.throwsTypeError(() => cm.invoke(#baz, [
+        map
+      ], {
+        #bar: {'boo': 'bah'}
+      }));
+}
+
+void badStaticInvoke() {
+  final im = reflect(foo) as ClosureMirror;
+  Expect.throwsTypeError(() => im.apply(['Hello world!']));
+}
+
+void badInstanceInvoke() {
+  final fooCls = Foo.a();
+  final im = reflect(fooCls);
+  Expect.throwsTypeError(() => im.invoke(#bar, ['Hello World!']));
+}
+
+void badConstructorInvoke() {
+  final cm = reflectClass(Foo);
+  Expect.throwsTypeError(() => cm.newInstance(Symbol(''), ['Hello World!']));
+}
+
+void badSetterInvoke() {
+  final fooCls = Foo.a();
+  final im = reflect(fooCls);
+  Expect.throwsTypeError(() => im.setField(#bork, 'Hello World!'));
+}
+
+void badStaticSetterInvoke() {
+  final cm = reflectClass(Foo);
+  Expect.throwsTypeError(() => cm.setField(#bark, 'Hello World!'));
+  Expect.throwsTypeError(() => cm.setField(#woof, 'Hello World!'));
+}
+
+void badGenericConstructorInvoke() {
+  final cm = reflectType(FooBar, [int]) as ClassMirror;
+  Expect.throwsTypeError(() => cm.newInstance(Symbol(''), ['Hello World!']));
+}
+
+void badGenericClassStaticInvoke() {
+  final cm = reflectType(FooBar, [int]) as ClassMirror;
+  final im = cm.newInstance(Symbol(''), [1]);
+  Expect.throwsTypeError(() => im.invoke(#foobar, ['Hello', 'World']));
+}
+
+void badGenericFactoryInvoke() {
+  final cm = reflectType(FooBar, [int]) as ClassMirror;
+  Expect.throwsTypeError(() => cm.newInstance(Symbol('baz'), ['Hello World!']));
+}
+
+void badGenericStaticInvoke() {
+  final im = reflect(bar) as ClosureMirror;
+  Expect.throwsTypeError(() => im.apply(['Hello world!']));
+}
+
+void badGenericSetterInvoke() {
+  final cm = reflectType(FooBar, [int]) as ClassMirror;
+  final im = cm.newInstance(Symbol(''), [0]);
+  Expect.throwsTypeError(() => im.setField(#bar, 'Hello world!'));
+  Expect.throwsTypeError(() => im.setField(#barz, 'Hello world!'));
+}
+
+void badLibrarySetterInvoke() {
+  final lm = currentMirrorSystem().findLibrary(Symbol(''));
+  Expect.throwsTypeError(() => lm.setField(#foobar, 'Foobaz'));
+  Expect.throwsTypeError(() => lm.setField(#foobaz, 'Foobaz'));
+}
+
+void main() {
+  badClassStaticInvoke();
+  badStaticInvoke();
+  badInstanceInvoke();
+  badConstructorInvoke();
+  badSetterInvoke();
+  badStaticSetterInvoke();
+  badGenericConstructorInvoke();
+  badGenericClassStaticInvoke();
+  badGenericFactoryInvoke();
+  badGenericStaticInvoke();
+  badGenericSetterInvoke();
+  badLibrarySetterInvoke();
+}
diff --git a/tests/lib/mirrors/basic_types_in_dart_core_test.dart b/tests/lib/mirrors/basic_types_in_dart_core_test.dart
new file mode 100644
index 0000000..50e9203
--- /dev/null
+++ b/tests/lib/mirrors/basic_types_in_dart_core_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.basic_types_in_dart_core;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+main() {
+  LibraryMirror dartcore = currentMirrorSystem().findLibrary(#dart.core);
+  ClassMirror cm;
+  TypeMirror tm;
+
+  cm = dartcore.declarations[#int] as ClassMirror;
+  Expect.equals(reflectClass(int), cm);
+  Expect.equals(#int, cm.simpleName);
+
+  cm = dartcore.declarations[#double] as ClassMirror;
+  Expect.equals(reflectClass(double), cm);
+  Expect.equals(#double, cm.simpleName);
+
+  cm = dartcore.declarations[#num] as ClassMirror;
+  Expect.equals(reflectClass(num), cm);
+  Expect.equals(#num, cm.simpleName);
+
+  cm = dartcore.declarations[#bool] as ClassMirror;
+  Expect.equals(reflectClass(bool), cm);
+  Expect.equals(#bool, cm.simpleName);
+
+  cm = dartcore.declarations[#String] as ClassMirror;
+  Expect.equals(reflectClass(String), cm);
+  Expect.equals(#String, cm.simpleName);
+
+  cm = dartcore.declarations[#List] as ClassMirror;
+  Expect.equals(reflectClass(List), cm);
+  Expect.equals(#List, cm.simpleName);
+
+  cm = dartcore.declarations[#Null] as ClassMirror;
+  Expect.equals(reflectClass(Null), cm);
+  Expect.equals(#Null, cm.simpleName);
+
+  cm = dartcore.declarations[#Object] as ClassMirror;
+  Expect.equals(reflectClass(Object), cm);
+  Expect.equals(#Object, cm.simpleName);
+
+  tm = dartcore.declarations[#dynamic] as TypeMirror;
+  Expect.isNull(tm);
+
+  tm = dartcore.declarations[const Symbol('void')] as TypeMirror;
+  Expect.isNull(tm);
+}
diff --git a/tests/lib/mirrors/circular_factory_redirection_test.dart b/tests/lib/mirrors/circular_factory_redirection_test.dart
new file mode 100644
index 0000000..560ed6e
--- /dev/null
+++ b/tests/lib/mirrors/circular_factory_redirection_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class A {
+  A();
+  A.circular() = B.circular; // //# 01: compile-time error
+  const A.circular2() = B.circular2; // //# 02: compile-time error
+}
+
+class B {
+  B();
+  B.circular() = C.circular; // //# 01: continued
+  const B.circular2() = C.circular2; // //# 02: continued
+}
+
+class C {
+  C();
+  C.circular() = A.circular; // //# 01: continued
+  const C.circular2() = A.circular2; // //# 02: continued
+}
+
+main() {
+  ClassMirror cm = reflectClass(A);
+
+  new A.circular(); // //# 01: continued
+  new A.circular2(); // //# 02: continued
+
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(#circular, []),
+      'Should disallow circular redirection (non-const)');
+
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(#circular2, []),
+      'Should disallow circular redirection (const)');
+}
diff --git a/tests/lib/mirrors/class_declarations_test.dart b/tests/lib/mirrors/class_declarations_test.dart
new file mode 100644
index 0000000..83f8964
--- /dev/null
+++ b/tests/lib/mirrors/class_declarations_test.dart
@@ -0,0 +1,368 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model.dart' as declarations_model;
+
+Set<DeclarationMirror> inheritedDeclarations(ClassMirror? cm) {
+  var decls = new Set<DeclarationMirror>();
+  while (cm != null) {
+    decls.addAll(cm.declarations.values);
+    cm = cm.superclass;
+  }
+  return decls;
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+
+  Expect.setEquals([
+    'Variable(s(_instanceVariable) in s(Class), private)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Variable(s(staticVariable) in s(Class), static)'
+  ], cm.declarations.values.where((dm) => dm is VariableMirror).map(stringify),
+      'variables');
+
+  Expect.setEquals(
+      [
+        'Method(s(_instanceGetter) in s(Class), private, getter)',
+        'Method(s(_staticGetter) in s(Class), private, static, getter)',
+        'Method(s(instanceGetter) in s(Class), getter)',
+        'Method(s(staticGetter) in s(Class), static, getter)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isGetter)
+          .map(stringify),
+      'getters');
+
+  Expect.setEquals(
+      [
+        'Method(s(_instanceSetter=) in s(Class), private, setter)',
+        'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+        'Method(s(instanceSetter=) in s(Class), setter)',
+        'Method(s(staticSetter=) in s(Class), static, setter)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isSetter)
+          .map(stringify),
+      'setters');
+
+  // dart2js stops testing here.
+  return; //# 01: ok
+
+  Expect.setEquals(
+      [
+        'Method(s(+) in s(Class))',
+        'Method(s(_instanceMethod) in s(Class), private)',
+        'Method(s(_staticMethod) in s(Class), private, static)',
+        'Method(s(abstractMethod) in s(Class), abstract)',
+        'Method(s(instanceMethod) in s(Class))',
+        'Method(s(staticMethod) in s(Class), static)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isRegularMethod)
+          .map(stringify),
+      'regular methods');
+
+  Expect.setEquals(
+      [
+        'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+        'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+        'Method(s(Class._redirectingConstructor)'
+            ' in s(Class), private, constructor)',
+        'Method(s(Class._redirectingFactory)'
+            ' in s(Class), private, static, constructor)',
+        'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+        'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+        'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+        'Method(s(Class.redirectingFactory) in s(Class), static, constructor)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isConstructor)
+          .map(stringify),
+      'constructors and factories');
+
+  Expect.setEquals(
+      [
+        'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+        'Method(s(Class._redirectingFactory)'
+            ' in s(Class), private, static, constructor)',
+        'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+        'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+        'Method(s(_staticGetter) in s(Class), private, static, getter)',
+        'Method(s(_staticMethod) in s(Class), private, static)',
+        'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+        'Variable(s(_staticVariable) in s(Class), private, static)',
+        'Method(s(staticGetter) in s(Class), static, getter)',
+        'Method(s(staticMethod) in s(Class), static)',
+        'Method(s(staticSetter=) in s(Class), static, setter)',
+        'Variable(s(staticVariable) in s(Class), static)'
+      ],
+      cm.declarations.values
+          .where((dm) => (dm as dynamic).isStatic)
+          .map(stringify),
+      'statics');
+
+  Expect.setEquals(
+      [
+        'Method(s(+) in s(Class))',
+        'TypeVariable(s(C) in s(Class),'
+            ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+        'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+        'Method(s(Class._redirectingConstructor)'
+            ' in s(Class), private, constructor)',
+        'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+        'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+        'Method(s(_instanceGetter) in s(Class), private, getter)',
+        'Method(s(_instanceMethod) in s(Class), private)',
+        'Method(s(_instanceSetter=) in s(Class), private, setter)',
+        'Variable(s(_instanceVariable) in s(Class), private)',
+        'Method(s(abstractMethod) in s(Class), abstract)',
+        'Method(s(instanceGetter) in s(Class), getter)',
+        'Method(s(instanceMethod) in s(Class))',
+        'Method(s(instanceSetter=) in s(Class), setter)',
+        'Variable(s(instanceVariable) in s(Class))'
+      ],
+      cm.declarations.values
+          .where((dm) => !(dm as dynamic).isStatic)
+          .map(stringify),
+      'non-statics');
+
+  Expect.setEquals(
+      [
+        'Method(s(+) in s(Class))',
+        'TypeVariable(s(C) in s(Class),'
+            ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+        'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+        'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+        'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+        'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+        'Method(s(abstractMethod) in s(Class), abstract)',
+        'Method(s(instanceGetter) in s(Class), getter)',
+        'Method(s(instanceMethod) in s(Class))',
+        'Method(s(instanceSetter=) in s(Class), setter)',
+        'Variable(s(instanceVariable) in s(Class))',
+        'Method(s(staticGetter) in s(Class), static, getter)',
+        'Method(s(staticMethod) in s(Class), static)',
+        'Method(s(staticSetter=) in s(Class), static, setter)',
+        'Variable(s(staticVariable) in s(Class), static)'
+      ],
+      cm.declarations.values
+          .where((dm) => !(dm as dynamic).isPrivate)
+          .map(stringify),
+      'public');
+
+  Expect.setEquals([
+    'Method(s(*) in s(Mixin))',
+    'Method(s(+) in s(Class))',
+    'Method(s(-) in s(Superclass))',
+    'Method(s(==) in s(Object))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(Object) in s(Object), constructor)',
+    'TypeVariable(s(S) in s(Superclass),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Superclass.inheritedGenerativeConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedNormalFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(Superclass.inheritedRedirectingConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedRedirectingFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(hashCode) in s(Object), getter)',
+    'Method(s(inheritedInstanceGetter) in s(Superclass), getter)',
+    'Method(s(inheritedInstanceMethod) in s(Superclass))',
+    'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)',
+    'Variable(s(inheritedInstanceVariable) in s(Superclass))',
+    'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)',
+    'Method(s(inheritedStaticMethod) in s(Superclass), static)',
+    'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)',
+    'Variable(s(inheritedStaticVariable) in s(Superclass), static)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(mixinInstanceGetter) in s(Mixin), getter)',
+    'Method(s(mixinInstanceMethod) in s(Mixin))',
+    'Method(s(mixinInstanceSetter=) in s(Mixin), setter)',
+    'Variable(s(mixinInstanceVariable) in s(Mixin))',
+    'Method(s(noSuchMethod) in s(Object))',
+    'Method(s(runtimeType) in s(Object), getter)',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)',
+    'Method(s(toString) in s(Object))',
+    'Variable(s(mixinStaticVariable) in s(Mixin), static)',
+    'Method(s(mixinStaticGetter) in s(Mixin), static, getter)',
+    'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)',
+    'Method(s(mixinStaticMethod) in s(Mixin), static)'
+  ], inheritedDeclarations(cm).where((dm) => !dm.isPrivate).map(stringify),
+      'transitive public');
+  // The public members of Object should be the same in all implementations, so
+  // we don't exclude Object here.
+
+  Expect.setEquals([
+    'Method(s(+) in s(Class))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+    'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+    'Method(s(Class._redirectingConstructor)'
+        ' in s(Class), private, constructor)',
+    'Method(s(Class._redirectingFactory)'
+        ' in s(Class), private, static, constructor)',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(_instanceGetter) in s(Class), private, getter)',
+    'Method(s(_instanceMethod) in s(Class), private)',
+    'Method(s(_instanceSetter=) in s(Class), private, setter)',
+    'Variable(s(_instanceVariable) in s(Class), private)',
+    'Method(s(_staticGetter) in s(Class), private, static, getter)',
+    'Method(s(_staticMethod) in s(Class), private, static)',
+    'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)'
+  ], cm.declarations.values.map(stringify), 'declarations');
+
+  Expect.setEquals(
+      [
+        'Method(s(*) in s(Mixin))',
+        'Method(s(+) in s(Class))',
+        'Method(s(-) in s(Superclass))',
+        'TypeVariable(s(C) in s(Class),'
+            ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+        'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+        'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+        'Method(s(Class._redirectingConstructor)'
+            ' in s(Class), private, constructor)',
+        'Method(s(Class._redirectingFactory)'
+            ' in s(Class), private, static, constructor)',
+        'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+        'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+        'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+        'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+        'TypeVariable(s(S) in s(Superclass),'
+            ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+        'Method(s(Superclass._inheritedGenerativeConstructor)'
+            ' in s(Superclass), private, constructor)',
+        'Method(s(Superclass._inheritedNormalFactory)'
+            ' in s(Superclass), private, static, constructor)',
+        'Method(s(Superclass._inheritedRedirectingConstructor)'
+            ' in s(Superclass), private, constructor)',
+        'Method(s(Superclass._inheritedRedirectingFactory)'
+            ' in s(Superclass), private, static, constructor)',
+        'Method(s(Superclass.inheritedGenerativeConstructor)'
+            ' in s(Superclass), constructor)',
+        'Method(s(Superclass.inheritedNormalFactory)'
+            ' in s(Superclass), static, constructor)',
+        'Method(s(Superclass.inheritedRedirectingConstructor)'
+            ' in s(Superclass), constructor)',
+        'Method(s(Superclass.inheritedRedirectingFactory)'
+            ' in s(Superclass), static, constructor)',
+        'Method(s(_inheritedInstanceGetter) in s(Superclass), private, getter)',
+        'Method(s(_inheritedInstanceMethod) in s(Superclass), private)',
+        'Method(s(_inheritedInstanceSetter=) in s(Superclass), private, setter)',
+        'Variable(s(_inheritedInstanceVariable) in s(Superclass), private)',
+        'Method(s(_inheritedStaticGetter)'
+            ' in s(Superclass), private, static, getter)',
+        'Method(s(_inheritedStaticMethod) in s(Superclass), private, static)',
+        'Method(s(_inheritedStaticSetter=)'
+            ' in s(Superclass), private, static, setter)',
+        'Variable(s(_inheritedStaticVariable) in s(Superclass), private, static)',
+        'Method(s(_instanceGetter) in s(Class), private, getter)',
+        'Method(s(_instanceMethod) in s(Class), private)',
+        'Method(s(_instanceSetter=) in s(Class), private, setter)',
+        'Variable(s(_instanceVariable) in s(Class), private)',
+        'Method(s(_mixinInstanceGetter) in s(Mixin), private, getter)',
+        'Method(s(_mixinInstanceMethod) in s(Mixin), private)',
+        'Method(s(_mixinInstanceSetter=) in s(Mixin), private, setter)',
+        'Variable(s(_mixinInstanceVariable) in s(Mixin), private)',
+        'Method(s(_staticGetter) in s(Class), private, static, getter)',
+        'Method(s(_staticMethod) in s(Class), private, static)',
+        'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+        'Variable(s(_staticVariable) in s(Class), private, static)',
+        'Method(s(abstractMethod) in s(Class), abstract)',
+        'Method(s(inheritedInstanceGetter) in s(Superclass), getter)',
+        'Method(s(inheritedInstanceMethod) in s(Superclass))',
+        'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)',
+        'Variable(s(inheritedInstanceVariable) in s(Superclass))',
+        'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)',
+        'Method(s(inheritedStaticMethod) in s(Superclass), static)',
+        'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)',
+        'Variable(s(inheritedStaticVariable) in s(Superclass), static)',
+        'Method(s(instanceGetter) in s(Class), getter)',
+        'Method(s(instanceMethod) in s(Class))',
+        'Method(s(instanceSetter=) in s(Class), setter)',
+        'Variable(s(instanceVariable) in s(Class))',
+        'Method(s(mixinInstanceGetter) in s(Mixin), getter)',
+        'Method(s(mixinInstanceMethod) in s(Mixin))',
+        'Method(s(mixinInstanceSetter=) in s(Mixin), setter)',
+        'Variable(s(mixinInstanceVariable) in s(Mixin))',
+        'Method(s(staticGetter) in s(Class), static, getter)',
+        'Method(s(staticMethod) in s(Class), static)',
+        'Method(s(staticSetter=) in s(Class), static, setter)',
+        'Variable(s(staticVariable) in s(Class), static)',
+        'Method(s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin._inheritedGenerativeConstructor)'
+            ' in s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin), private, constructor)',
+        'Method(s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin._inheritedRedirectingConstructor)'
+            ' in s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin), private, constructor)',
+        'Method(s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)'
+            ' in s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin), constructor)',
+        'Method(s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
+            ' in s(test.declarations_model.Superclass'
+            ' with test.declarations_model.Mixin), constructor)',
+        'Variable(s(mixinStaticVariable) in s(Mixin), static)',
+        'Variable(s(_mixinStaticVariable) in s(Mixin), private, static)',
+        'Method(s(mixinStaticGetter) in s(Mixin), static, getter)',
+        'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)',
+        'Method(s(mixinStaticMethod) in s(Mixin), static)',
+        'Method(s(_mixinStaticGetter) in s(Mixin), private, static, getter)',
+        'Method(s(_mixinStaticSetter=) in s(Mixin), private, static, setter)',
+        'Method(s(_mixinStaticMethod) in s(Mixin), private, static)'
+      ],
+      inheritedDeclarations(cm)
+          .difference(reflectClass(Object).declarations.values.toSet())
+          .map(stringify),
+      'transitive less Object');
+  // The private members of Object may vary across implementations, so we
+  // exclude the declarations of Object in this test case.
+}
diff --git a/tests/lib/mirrors/class_mirror_location_other.dart b/tests/lib/mirrors/class_mirror_location_other.dart
new file mode 100644
index 0000000..eb94d21
--- /dev/null
+++ b/tests/lib/mirrors/class_mirror_location_other.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of test.class_location;
+
+class ClassInOtherFile {}
+
+  class SpaceIndentedInOtherFile {}
+
+	class TabIndentedInOtherFile {}
diff --git a/tests/lib/mirrors/class_mirror_location_test.dart b/tests/lib/mirrors/class_mirror_location_test.dart
new file mode 100644
index 0000000..0af1f59
--- /dev/null
+++ b/tests/lib/mirrors/class_mirror_location_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library test.class_location;
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+part 'class_mirror_location_other.dart';
+
+class ClassInMainFile {}
+  class SpaceIndentedInMainFile {}
+	class TabIndentedInMainFile {}
+
+abstract class AbstractClass {}
+typedef bool Predicate(num n);
+
+class M {}
+class S {}
+class MA extends S with M {}
+class MA2 = S with M;
+
+const metadata = 'metadata';
+
+@metadata
+class WithMetadata {}
+
+enum Enum { RED, GREEN, BLUE }
+
+@metadata
+enum AnnotatedEnum { SALT, PEPPER }
+
+// We only check for a suffix of the uri because the test might be run from
+// any number of absolute paths.
+expectLocation(
+    DeclarationMirror mirror, String uriSuffix, int line, int column) {
+  final location = mirror.location!;
+  final uri = location.sourceUri;
+  Expect.isTrue(
+      uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri");
+  Expect.equals(line, location.line, "line");
+  Expect.equals(column, location.column, "column");
+}
+
+main() {
+  String mainSuffix = 'class_mirror_location_test.dart';
+  String otherSuffix = 'class_mirror_location_other.dart';
+
+  // This file.
+  expectLocation(reflectClass(ClassInMainFile), mainSuffix, 12, 1);
+  expectLocation(reflectClass(SpaceIndentedInMainFile), mainSuffix, 13, 3);
+  expectLocation(reflectClass(TabIndentedInMainFile), mainSuffix, 14, 2);
+  expectLocation(reflectClass(AbstractClass), mainSuffix, 16, 1);
+  expectLocation(reflectType(Predicate), mainSuffix, 17, 1);
+  expectLocation(reflectClass(MA), mainSuffix, 21, 1);
+  expectLocation(reflectClass(MA2), mainSuffix, 22, 1);
+  expectLocation(reflectClass(WithMetadata), mainSuffix, 26, 1);
+  expectLocation(reflectClass(Enum), mainSuffix, 29, 1);
+  expectLocation(reflectClass(AnnotatedEnum), mainSuffix, 31, 1);
+
+  // Another part.
+  expectLocation(reflectClass(ClassInOtherFile), otherSuffix, 7, 1);
+  expectLocation(reflectClass(SpaceIndentedInOtherFile), otherSuffix, 9, 3);
+  expectLocation(reflectClass(TabIndentedInOtherFile), otherSuffix, 11, 2);
+
+  // Synthetic classes.
+  Expect.isNull(reflectClass(MA).superclass!.location);
+  Expect.isNull((reflect(main) as ClosureMirror).type.location);
+}
diff --git a/tests/lib/mirrors/class_mirror_type_variables_data.dart b/tests/lib/mirrors/class_mirror_type_variables_data.dart
new file mode 100644
index 0000000..0090241
--- /dev/null
+++ b/tests/lib/mirrors/class_mirror_type_variables_data.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library class_mirror_type_variables_data;
+
+class NoTypeParams {}
+
+class A<T, S extends String> {}
+
+class B<Z extends B<Z>> {}
+
+class C<Z extends B<Z>> {}
+
+class D<R, S, T> {
+  R foo(R r) => r;
+  S bar(S s) => s;
+  T baz(T t) => t;
+}
+
+class Helper<S> {}
+
+class E<R extends Map<R, Helper<String>>> {}
+
+class F<Z extends Helper<F<Z>>> {}
diff --git a/tests/lib/mirrors/class_mirror_type_variables_expect.dart b/tests/lib/mirrors/class_mirror_type_variables_expect.dart
new file mode 100644
index 0000000..adee190
--- /dev/null
+++ b/tests/lib/mirrors/class_mirror_type_variables_expect.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test expectations for 'class_mirror_type_variables_data.dart'.
+
+library class_mirror_type_variables_expect;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+/// The interface of [Env] is shared between the runtime and the source mirrors
+/// test.
+abstract class Env {
+  ClassMirror getA();
+  ClassMirror getB();
+  ClassMirror getC();
+  ClassMirror getD();
+  ClassMirror getE();
+  ClassMirror getF();
+  ClassMirror getNoTypeParams();
+  ClassMirror getObject();
+  ClassMirror getString();
+  ClassMirror getHelperOfString();
+}
+
+void test(Env env) {
+  testNoTypeParams(env);
+  testA(env);
+  testBAndC(env);
+  testD(env);
+  testE(env);
+  testF(env);
+}
+
+testNoTypeParams(Env env) {
+  ClassMirror cm = env.getNoTypeParams();
+  Expect.equals(cm.typeVariables.length, 0);
+}
+
+void testA(Env env) {
+  ClassMirror a = env.getA();
+  Expect.equals(2, a.typeVariables.length);
+
+  TypeVariableMirror aT = a.typeVariables[0];
+  TypeVariableMirror aS = a.typeVariables[1];
+  ClassMirror aTBound = aT.upperBound as ClassMirror;
+  ClassMirror aSBound = aS.upperBound as ClassMirror;
+
+  Expect.isTrue(aTBound.isOriginalDeclaration);
+  Expect.isTrue(aSBound.isOriginalDeclaration);
+
+  Expect.equals(env.getObject(), aTBound);
+  Expect.equals(env.getString(), aSBound);
+}
+
+void testBAndC(Env env) {
+  ClassMirror b = env.getB();
+  ClassMirror c = env.getC();
+
+  Expect.equals(1, b.typeVariables.length);
+  Expect.equals(1, c.typeVariables.length);
+
+  TypeVariableMirror bZ = b.typeVariables[0];
+  TypeVariableMirror cZ = c.typeVariables[0];
+  ClassMirror bZBound = bZ.upperBound as ClassMirror;
+  ClassMirror cZBound = cZ.upperBound as ClassMirror;
+
+  Expect.isFalse(bZBound.isOriginalDeclaration);
+  Expect.isFalse(cZBound.isOriginalDeclaration);
+
+  Expect.notEquals(bZBound, cZBound);
+  Expect.equals(b, bZBound.originalDeclaration);
+  Expect.equals(b, cZBound.originalDeclaration);
+
+  TypeMirror bZBoundTypeArgument = bZBound.typeArguments.single;
+  TypeMirror cZBoundTypeArgument = cZBound.typeArguments.single;
+  TypeVariableMirror bZBoundTypeVariable = bZBound.typeVariables.single;
+  TypeVariableMirror cZBoundTypeVariable = cZBound.typeVariables.single;
+
+  Expect.equals(b, bZ.owner);
+  Expect.equals(c, cZ.owner);
+  Expect.equals(b, bZBoundTypeVariable.owner);
+  Expect.equals(b, cZBoundTypeVariable.owner);
+  Expect.equals(b, bZBoundTypeArgument.owner);
+  Expect.equals(c, cZBoundTypeArgument.owner);
+
+  Expect.notEquals(bZ, cZ);
+  Expect.equals(bZ, bZBoundTypeArgument);
+  Expect.equals(cZ, cZBoundTypeArgument);
+  Expect.equals(bZ, bZBoundTypeVariable);
+  Expect.equals(bZ, cZBoundTypeVariable);
+}
+
+testD(Env env) {
+  ClassMirror cm = env.getD();
+  Expect.equals(3, cm.typeVariables.length);
+  var values = cm.typeVariables;
+  values.forEach((e) {
+    Expect.equals(true, e is TypeVariableMirror);
+  });
+  Expect.equals(#R, values.elementAt(0).simpleName);
+  Expect.equals(#S, values.elementAt(1).simpleName);
+  Expect.equals(#T, values.elementAt(2).simpleName);
+}
+
+void testE(Env env) {
+  ClassMirror e = env.getE();
+  TypeVariableMirror eR = e.typeVariables.single;
+  ClassMirror mapRAndHelperOfString = eR.upperBound as ClassMirror;
+
+  Expect.isFalse(mapRAndHelperOfString.isOriginalDeclaration);
+  Expect.equals(eR, mapRAndHelperOfString.typeArguments.first);
+  Expect.equals(
+      env.getHelperOfString(), mapRAndHelperOfString.typeArguments.last);
+}
+
+void testF(Env env) {
+  ClassMirror f = env.getF();
+  TypeVariableMirror fZ = f.typeVariables[0];
+  ClassMirror fZBound = fZ.upperBound as ClassMirror;
+  ClassMirror fZBoundTypeArgument = fZBound.typeArguments.single as ClassMirror;
+
+  Expect.equals(1, f.typeVariables.length);
+  Expect.isFalse(fZBound.isOriginalDeclaration);
+  Expect.isFalse(fZBoundTypeArgument.isOriginalDeclaration);
+  Expect.equals(f, fZBoundTypeArgument.originalDeclaration);
+  Expect.equals(fZ, fZBoundTypeArgument.typeArguments.single);
+}
diff --git a/tests/lib/mirrors/class_mirror_type_variables_test.dart b/tests/lib/mirrors/class_mirror_type_variables_test.dart
new file mode 100644
index 0000000..8918de7
--- /dev/null
+++ b/tests/lib/mirrors/class_mirror_type_variables_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+import "class_mirror_type_variables_data.dart";
+import "class_mirror_type_variables_expect.dart";
+
+class RuntimeEnv implements Env {
+  ClassMirror getA() => reflectClass(A);
+  ClassMirror getB() => reflectClass(B);
+  ClassMirror getC() => reflectClass(C);
+  ClassMirror getD() => reflectClass(D);
+  ClassMirror getE() => reflectClass(E);
+  ClassMirror getF() => reflectClass(F);
+  ClassMirror getNoTypeParams() => reflectClass(NoTypeParams);
+  ClassMirror getObject() => reflectClass(Object);
+  ClassMirror getString() => reflectClass(String);
+  ClassMirror getHelperOfString() => reflect(new Helper<String>()).type;
+}
+
+main() {
+  test(new RuntimeEnv());
+}
diff --git a/tests/lib/mirrors/closure_mirror_import1.dart b/tests/lib/mirrors/closure_mirror_import1.dart
new file mode 100644
index 0000000..c0e41da
--- /dev/null
+++ b/tests/lib/mirrors/closure_mirror_import1.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library closure_mirror_import1;
+
+export "closure_mirror_import2.dart" show firstGlobalVariableInImport2;
+
+var globalVariableInImport1 = "globalVariableInImport1";
+
+globalFunctionInImport1() => "globalFunctionInImport1";
+
+class StaticClass {
+  static var staticField = "staticField";
+
+  static staticFunctionInStaticClass() => "staticFunctionInStaticClass";
+}
diff --git a/tests/lib/mirrors/closure_mirror_import2.dart b/tests/lib/mirrors/closure_mirror_import2.dart
new file mode 100644
index 0000000..9d09d36
--- /dev/null
+++ b/tests/lib/mirrors/closure_mirror_import2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library closure_mirror_import2;
+
+var firstGlobalVariableInImport2 = "firstGlobalVariableInImport2";
+var secondGlobalVariableInImport2 = "secondGlobalVariableInImport2";
diff --git a/tests/lib/mirrors/closures_test.dart b/tests/lib/mirrors/closures_test.dart
new file mode 100644
index 0000000..a1e2e93
--- /dev/null
+++ b/tests/lib/mirrors/closures_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+testIntercepted() {
+  var instance = [];
+  var closureMirror = reflect(instance.toString) as ClosureMirror;
+  var methodMirror = closureMirror.function;
+  Expect.equals(#toString, methodMirror.simpleName);
+  Expect.equals('[]', closureMirror.apply([]).reflectee);
+}
+
+testNonIntercepted() {
+  var closure = new Map().containsKey;
+  var closureMirror = reflect(closure) as ClosureMirror;
+  var methodMirror = closureMirror.function;
+  Expect.equals(#containsKey, methodMirror.simpleName);
+  Expect.isFalse(closureMirror.apply([7]).reflectee);
+}
+
+main() {
+  testIntercepted();
+  testNonIntercepted();
+}
diff --git a/tests/lib/mirrors/closurization_equivalence_test.dart b/tests/lib/mirrors/closurization_equivalence_test.dart
new file mode 100644
index 0000000..e1cdbed
--- /dev/null
+++ b/tests/lib/mirrors/closurization_equivalence_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+topLevelMethod() {}
+
+class C {
+  static staticMethod() {}
+  instanceMethod() {}
+}
+
+main() {
+  LibraryMirror thisLibrary = reflectClass(C).owner as LibraryMirror;
+  Expect.equals(thisLibrary.declarations[#topLevelMethod],
+      (reflect(topLevelMethod) as ClosureMirror).function, "topLevel");
+
+  Expect.equals(reflectClass(C).declarations[#staticMethod],
+      (reflect(C.staticMethod) as ClosureMirror).function, "static");
+
+  Expect.equals(reflectClass(C).declarations[#instanceMethod],
+      (reflect(new C().instanceMethod) as ClosureMirror).function, "instance");
+}
diff --git a/tests/lib/mirrors/const_evaluation_test.dart b/tests/lib/mirrors/const_evaluation_test.dart
new file mode 100644
index 0000000..be27133
--- /dev/null
+++ b/tests/lib/mirrors/const_evaluation_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, 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.
+
+// Check that compile-time evaluation of constants is consistent with runtime
+// evaluation.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+const top_const = identical(-0.0, 0);
+
+@top_const
+class C {}
+
+void main() {
+  var local_var = identical(-0.0, 0);
+  var metadata = reflectClass(C).metadata[0].reflectee;
+  Expect.equals(top_const, metadata);
+  Expect.equals(local_var, metadata);
+}
diff --git a/tests/lib/mirrors/constructor_kinds_test.dart b/tests/lib/mirrors/constructor_kinds_test.dart
new file mode 100644
index 0000000..185e7d0
--- /dev/null
+++ b/tests/lib/mirrors/constructor_kinds_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.constructor_kinds_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class ClassWithDefaultConstructor {}
+
+class Class {
+  Class.generativeConstructor();
+  Class.redirectingGenerativeConstructor() : this.generativeConstructor();
+  factory Class.factoryConstructor() => new Class.generativeConstructor();
+  factory Class.redirectingFactoryConstructor() = Class.factoryConstructor;
+
+  const Class.constGenerativeConstructor();
+  const Class.constRedirectingGenerativeConstructor()
+      : this.constGenerativeConstructor();
+  // Not legal.
+  // const factory Class.constFactoryConstructor() => ...
+  const factory Class.constRedirectingFactoryConstructor() =
+      Class.constGenerativeConstructor;
+}
+
+main() {
+  ClassMirror cm;
+  MethodMirror mm;
+
+  // Multitest with and without constructor calls. On the VM, we want to check
+  // that constructor properties are correctly set even if the constructor
+  // hasn't been fully compiled. On dart2js, we want to check that constructors
+  // are retain even if there are no base-level calls.
+  new ClassWithDefaultConstructor(); // //# 01: ok
+  new Class.generativeConstructor(); // //# 01: ok
+  new Class.redirectingGenerativeConstructor(); // //# 01: ok
+  new Class.factoryConstructor(); // //# 01: ok
+  new Class.redirectingFactoryConstructor(); // //# 01: ok
+  const Class.constGenerativeConstructor(); // //# 01: ok
+  const Class.constRedirectingGenerativeConstructor(); // //# 01: ok
+  const Class.constRedirectingFactoryConstructor(); // //# 01: ok
+
+  cm = reflectClass(ClassWithDefaultConstructor);
+  mm = cm.declarations.values
+      .where((d) => d is MethodMirror && d.isConstructor)
+      .single as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  cm = reflectClass(Class);
+
+  mm = cm.declarations[#Class.generativeConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.redirectingGenerativeConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.factoryConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.redirectingFactoryConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.constGenerativeConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.constRedirectingGenerativeConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+
+  // Not legal.
+  // mm = cm.declarations[#Class.constFactoryConstructor] as MethodMirror;
+  // Expect.isTrue(mm.isConstructor);
+  // Expect.isFalse(mm.isGenerativeConstructor);
+  // Expect.isTrue(mm.isFactoryConstructor);
+  // Expect.isFalse(mm.isRedirectingConstructor);
+  // Expect.isTrue(mm.isConstConstructor);
+
+  mm = cm.declarations[#Class.constRedirectingFactoryConstructor] as MethodMirror;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+}
diff --git a/tests/lib/mirrors/constructor_optional_args_test.dart b/tests/lib/mirrors/constructor_optional_args_test.dart
new file mode 100644
index 0000000..5592fd2
--- /dev/null
+++ b/tests/lib/mirrors/constructor_optional_args_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.constructor_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class A {
+  factory A([x, y]) = B;
+  factory A.more([x, y]) = B.more;
+  factory A.oneMore(x, [y]) = B.more;
+}
+
+class B implements A {
+  final _x, _y, _z;
+
+  B([x = 'x', y = 'y'])
+      : _x = x,
+        _y = y,
+        _z = null;
+
+  B.more([x = 'x', y = 'y', z = 'z'])
+      : _x = x,
+        _y = y,
+        _z = z;
+
+  toString() => 'B(x=$_x, y=$_y, z=$_z)';
+}
+
+main() {
+  var d1 = new A(1);
+  Expect.equals('B(x=1, y=y, z=null)', '$d1', 'direct 1');
+
+  var d2 = new A.more(1);
+  Expect.equals('B(x=1, y=y, z=z)', '$d2', 'direct 2');
+
+  ClassMirror cm = reflectClass(A);
+
+  var v1 = cm.newInstance(Symbol.empty, []).reflectee;
+  var v2 = cm.newInstance(Symbol.empty, [1]).reflectee;
+  var v3 = cm.newInstance(Symbol.empty, [2, 3]).reflectee;
+
+  Expect.equals('B(x=x, y=y, z=null)', '$v1', 'unnamed 1');
+  Expect.equals('B(x=1, y=y, z=null)', '$v2', 'unnamed 2');
+  Expect.equals('B(x=2, y=3, z=null)', '$v3', 'unnamed 3');
+
+  var m1 = cm.newInstance(const Symbol('more'), []).reflectee;
+  var m2 = cm.newInstance(const Symbol('more'), [1]).reflectee;
+  var m3 = cm.newInstance(const Symbol('more'), [2, 3]).reflectee;
+
+  Expect.equals('B(x=x, y=y, z=z)', '$m1', 'more 1');
+  Expect.equals('B(x=1, y=y, z=z)', '$m2', 'more 2');
+  Expect.equals('B(x=2, y=3, z=z)', '$m3', 'more 3');
+
+  var o1 = cm.newInstance(const Symbol('oneMore'), [1]).reflectee;
+  var o2 = cm.newInstance(const Symbol('oneMore'), [2, 3]).reflectee;
+
+  Expect.equals('B(x=1, y=y, z=z)', '$o1', 'oneMore one arg');
+  Expect.equals('B(x=2, y=3, z=z)', '$o2', 'oneMore two args');
+}
diff --git a/tests/lib/mirrors/constructor_private_name_test.dart b/tests/lib/mirrors/constructor_private_name_test.dart
new file mode 100644
index 0000000..c0db651
--- /dev/null
+++ b/tests/lib/mirrors/constructor_private_name_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.constructors_test;
+
+// Regression test for C1 bug.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Foo {
+  Foo._private();
+}
+
+class _Foo {
+  _Foo._private();
+}
+
+main() {
+  ClassMirror fooMirror = reflectClass(Foo);
+  Symbol constructorName =
+      (fooMirror.declarations[#Foo._private] as MethodMirror).constructorName;
+  fooMirror.newInstance(constructorName, []);
+
+  ClassMirror _fooMirror = reflectClass(_Foo);
+  constructorName =
+      (_fooMirror.declarations[#_Foo._private] as MethodMirror).constructorName;
+  _fooMirror.newInstance(constructorName, []);
+}
diff --git a/tests/lib/mirrors/constructors_test.dart b/tests/lib/mirrors/constructors_test.dart
new file mode 100644
index 0000000..9bdbc7f
--- /dev/null
+++ b/tests/lib/mirrors/constructors_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.constructors_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+
+constructorsOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isConstructor) result[k] = v;
+  });
+  return result;
+}
+
+class Foo {}
+
+class Bar {
+  Bar();
+}
+
+class Baz {
+  Baz.named();
+}
+
+class Biz {
+  Biz();
+  Biz.named();
+}
+
+main() {
+  ClassMirror fooMirror = reflectClass(Foo);
+  Map<Symbol, MethodMirror> fooConstructors = constructorsOf(fooMirror);
+  ClassMirror barMirror = reflectClass(Bar);
+  Map<Symbol, MethodMirror> barConstructors = constructorsOf(barMirror);
+  ClassMirror bazMirror = reflectClass(Baz);
+  Map<Symbol, MethodMirror> bazConstructors = constructorsOf(bazMirror);
+  ClassMirror bizMirror = reflectClass(Biz);
+  Map<Symbol, MethodMirror> bizConstructors = constructorsOf(bizMirror);
+
+  expect('{Foo: Method(s(Foo) in s(Foo), constructor)}', fooConstructors);
+  expect('{Bar: Method(s(Bar) in s(Bar), constructor)}', barConstructors);
+  expect('{Baz.named: Method(s(Baz.named) in s(Baz), constructor)}',
+      bazConstructors);
+  expect(
+      '{Biz: Method(s(Biz) in s(Biz), constructor),'
+      ' Biz.named: Method(s(Biz.named) in s(Biz), constructor)}',
+      bizConstructors);
+  print(bizConstructors);
+
+  expect('[]', fooConstructors.values.single.parameters);
+  expect('[]', barConstructors.values.single.parameters);
+  expect('[]', bazConstructors.values.single.parameters);
+  for (var constructor in bizConstructors.values) {
+    expect('[]', constructor.parameters);
+  }
+
+  expect(
+      '[s()]', fooConstructors.values.map((m) => m.constructorName).toList());
+  expect(
+      '[s()]', barConstructors.values.map((m) => m.constructorName).toList());
+  expect('[s(named)]',
+      bazConstructors.values.map((m) => m.constructorName).toList());
+  expect(
+      '[s(), s(named)]',
+      bizConstructors.values.map((m) => m.constructorName).toList()
+        ..sort(compareSymbols));
+}
diff --git a/tests/lib/mirrors/dart2js_mirrors_test.dart b/tests/lib/mirrors/dart2js_mirrors_test.dart
new file mode 100644
index 0000000..65c32e3
--- /dev/null
+++ b/tests/lib/mirrors/dart2js_mirrors_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test should be removed when dart2js can pass all mirror tests.
+// TODO(ahe): Remove this test.
+
+import 'mirrors_test.dart' as test;
+
+main() {
+  test.isDart2js = true;
+  test.main();
+}
diff --git a/tests/lib/mirrors/declarations_model.dart b/tests/lib/mirrors/declarations_model.dart
new file mode 100644
index 0000000..f25523f
--- /dev/null
+++ b/tests/lib/mirrors/declarations_model.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_model;
+
+var libraryVariable;
+get libraryGetter => null;
+set librarySetter(x) => x;
+libraryMethod() => null;
+
+var _libraryVariable;
+get _libraryGetter => null;
+set _librarySetter(x) => x;
+_libraryMethod() => null;
+
+typedef bool Predicate(dynamic);
+
+abstract class Interface<I> {
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter;
+  set interfaceInstanceSetter(x);
+  interfaceInstanceMethod();
+
+  var _interfaceInstanceVariable;
+  get _interfaceInstanceGetter;
+  set _interfaceInstanceSetter(x);
+  _interfaceInstanceMethod();
+
+  static var interfaceStaticVariable;
+  static get interfaceStaticGetter => null;
+  static set interfaceStaticSetter(x) => x;
+  static interfaceStaticMethod() => null;
+
+  static var _interfaceStaticVariable;
+  static get _interfaceStaticGetter => null;
+  static set _interfaceStaticSetter(x) => x;
+  static _interfaceStaticMethod() => null;
+}
+
+class Mixin<M> {
+  operator *(x) => null;
+
+  var mixinInstanceVariable;
+  get mixinInstanceGetter => null;
+  set mixinInstanceSetter(x) => x;
+  mixinInstanceMethod() => null;
+
+  var _mixinInstanceVariable;
+  get _mixinInstanceGetter => null;
+  set _mixinInstanceSetter(x) => x;
+  _mixinInstanceMethod() => null;
+
+  static var mixinStaticVariable;
+  static get mixinStaticGetter => null;
+  static set mixinStaticSetter(x) => x;
+  static mixinStaticMethod() => null;
+
+  static var _mixinStaticVariable;
+  static get _mixinStaticGetter => null;
+  static set _mixinStaticSetter(x) => x;
+  static _mixinStaticMethod() => null;
+}
+
+class Superclass<S> {
+  operator -(x) => null;
+
+  var inheritedInstanceVariable;
+  get inheritedInstanceGetter => null;
+  set inheritedInstanceSetter(x) => x;
+  inheritedInstanceMethod() => null;
+
+  var _inheritedInstanceVariable;
+  get _inheritedInstanceGetter => null;
+  set _inheritedInstanceSetter(x) => x;
+  _inheritedInstanceMethod() => null;
+
+  static var inheritedStaticVariable;
+  static get inheritedStaticGetter => null;
+  static set inheritedStaticSetter(x) => x;
+  static inheritedStaticMethod() => null;
+
+  static var _inheritedStaticVariable;
+  static get _inheritedStaticGetter => null;
+  static set _inheritedStaticSetter(x) => x;
+  static _inheritedStaticMethod() => null;
+
+  Superclass.inheritedGenerativeConstructor(this.inheritedInstanceVariable);
+  Superclass.inheritedRedirectingConstructor(x)
+      : this.inheritedGenerativeConstructor(x * 2);
+  factory Superclass.inheritedNormalFactory(y) =>
+      new Superclass.inheritedRedirectingConstructor(y * 3);
+  factory Superclass.inheritedRedirectingFactory(z) =
+      Superclass<S>.inheritedNormalFactory;
+
+  Superclass._inheritedGenerativeConstructor(this._inheritedInstanceVariable);
+  Superclass._inheritedRedirectingConstructor(x)
+      : this._inheritedGenerativeConstructor(x * 2);
+  factory Superclass._inheritedNormalFactory(y) =>
+      new Superclass._inheritedRedirectingConstructor(y * 3);
+  factory Superclass._inheritedRedirectingFactory(z) =
+      Superclass<S>._inheritedNormalFactory;
+}
+
+abstract class Class<C> extends Superclass<C>
+    with Mixin<C>
+    implements Interface<C> {
+  operator +(x) => null;
+
+  abstractMethod();
+
+  var instanceVariable;
+  get instanceGetter => null;
+  set instanceSetter(x) => x;
+  instanceMethod() => null;
+
+  var _instanceVariable;
+  get _instanceGetter => null;
+  set _instanceSetter(x) => x;
+  _instanceMethod() => null;
+
+  static var staticVariable;
+  static get staticGetter => null;
+  static set staticSetter(x) => x;
+  static staticMethod() => null;
+
+  static var _staticVariable;
+  static get _staticGetter => null;
+  static set _staticSetter(x) => x;
+  static _staticMethod() => null;
+
+  Class.generativeConstructor(this.instanceVariable)
+      : super.inheritedGenerativeConstructor(0);
+  Class.redirectingConstructor(x) : this.generativeConstructor(x * 2);
+  factory Class.normalFactory(y) => new ConcreteClass(y * 3);
+  factory Class.redirectingFactory(z) = Class<C>.normalFactory;
+
+  Class._generativeConstructor(this._instanceVariable)
+      : super._inheritedGenerativeConstructor(0);
+  Class._redirectingConstructor(x) : this._generativeConstructor(x * 2);
+  factory Class._normalFactory(y) => new ConcreteClass(y * 3);
+  factory Class._redirectingFactory(z) = Class<C>._normalFactory;
+}
+
+// This is just here as a target of Class's factories to appease the analyzer.
+class ConcreteClass<CC> extends Class<CC> {
+  abstractMethod() {}
+
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter => null;
+  set interfaceInstanceSetter(x) => null;
+  interfaceInstanceMethod() => null;
+
+  var _interfaceInstanceVariable;
+  get _interfaceInstanceGetter => null;
+  set _interfaceInstanceSetter(x) => null;
+  _interfaceInstanceMethod() => null;
+
+  ConcreteClass(x) : super.generativeConstructor(x);
+}
+
+class _PrivateClass {}
diff --git a/tests/lib/mirrors/declarations_model_easier.dart b/tests/lib/mirrors/declarations_model_easier.dart
new file mode 100644
index 0000000..665b691
--- /dev/null
+++ b/tests/lib/mirrors/declarations_model_easier.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_model;
+
+var libraryVariable;
+get libraryGetter => null;
+set librarySetter(x) => x;
+libraryMethod() => null;
+
+typedef bool Predicate(dynamic);
+
+abstract class Interface<I> {
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter;
+  set interfaceInstanceSetter(x);
+  interfaceInstanceMethod();
+
+  static var interfaceStaticVariable;
+  static get interfaceStaticGetter => null;
+  static set interfaceStaticSetter(x) => x;
+  static interfaceStaticMethod() => null;
+}
+
+class Superclass<S> {
+  operator -(x) => null;
+
+  var inheritedInstanceVariable;
+  get inheritedInstanceGetter => null;
+  set inheritedInstanceSetter(x) => x;
+  inheritedInstanceMethod() => null;
+
+  static var inheritedStaticVariable;
+  static get inheritedStaticGetter => null;
+  static set inheritedStaticSetter(x) => x;
+  static inheritedStaticMethod() => null;
+
+  Superclass.inheritedGenerativeConstructor(this.inheritedInstanceVariable);
+  Superclass.inheritedRedirectingConstructor(x)
+      : this.inheritedGenerativeConstructor(x * 2);
+  factory Superclass.inheritedNormalFactory(y) =>
+      new Superclass.inheritedRedirectingConstructor(y * 3);
+  factory Superclass.inheritedRedirectingFactory(z) =
+      Superclass<S>.inheritedNormalFactory;
+}
+
+abstract class Class<C> extends Superclass<C> implements Interface<C> {
+  operator +(x) => null;
+
+  abstractMethod();
+
+  var instanceVariable;
+  get instanceGetter => null;
+  set instanceSetter(x) => x;
+  instanceMethod() => null;
+
+  static var staticVariable;
+  static get staticGetter => null;
+  static set staticSetter(x) => x;
+  static staticMethod() => null;
+
+  Class.generativeConstructor(this.instanceVariable)
+      : super.inheritedGenerativeConstructor(0);
+  Class.redirectingConstructor(x) : this.generativeConstructor(x * 2);
+  factory Class.normalFactory(y) => new ConcreteClass(y * 3);
+  factory Class.redirectingFactory(z) = Class<C>.normalFactory;
+}
+
+// This is just here as a target of Class's factories to appease the analyzer.
+class ConcreteClass<CC> extends Class<CC> {
+  abstractMethod() {}
+
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter => null;
+  set interfaceInstanceSetter(x) => null;
+  interfaceInstanceMethod() => null;
+
+  ConcreteClass(x) : super.generativeConstructor(x);
+}
diff --git a/tests/lib/mirrors/declarations_type_test.dart b/tests/lib/mirrors/declarations_type_test.dart
new file mode 100644
index 0000000..836ce85
--- /dev/null
+++ b/tests/lib/mirrors/declarations_type_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for Issue 14972.
+
+library test.declarations_type;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {}
+
+main() {
+  var classDeclarations = reflectClass(C).declarations;
+  Expect.isTrue(classDeclarations is Map<Symbol, DeclarationMirror>);
+  Expect.isTrue(classDeclarations.values is Iterable<DeclarationMirror>);
+  Expect.isTrue(classDeclarations.values.where((x) => true)
+      is Iterable<DeclarationMirror>);
+  Expect.isFalse(classDeclarations is Map<Symbol, MethodMirror>);
+  Expect.isFalse(classDeclarations.values is Iterable<MethodMirror>);
+  Expect.isFalse(
+      classDeclarations.values.where((x) => true) is Iterable<MethodMirror>);
+
+  var libraryDeclarations =
+      (reflectClass(C).owner as LibraryMirror).declarations;
+  Expect.isTrue(libraryDeclarations is Map<Symbol, DeclarationMirror>);
+  Expect.isTrue(libraryDeclarations.values is Iterable<DeclarationMirror>);
+  Expect.isTrue(libraryDeclarations.values.where((x) => true)
+      is Iterable<DeclarationMirror>);
+  Expect.isFalse(libraryDeclarations is Map<Symbol, ClassMirror>);
+  Expect.isFalse(libraryDeclarations.values is Iterable<ClassMirror>);
+  Expect.isFalse(
+      libraryDeclarations.values.where((x) => true) is Iterable<ClassMirror>);
+}
diff --git a/tests/lib/mirrors/deferred_constraints_constants_lib.dart b/tests/lib/mirrors/deferred_constraints_constants_lib.dart
new file mode 100644
index 0000000..cdeec47
--- /dev/null
+++ b/tests/lib/mirrors/deferred_constraints_constants_lib.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  static int staticMethod() => 42;
+}
+
+class G<T> {}
+
+class Const {
+  const Const();
+  const Const.namedConstructor();
+  static const instance = const Const();
+}
+
+const constantInstance = const Const();
diff --git a/tests/lib/mirrors/deferred_constraints_constants_test.dart b/tests/lib/mirrors/deferred_constraints_constants_test.dart
new file mode 100644
index 0000000..053bb81
--- /dev/null
+++ b/tests/lib/mirrors/deferred_constraints_constants_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:mirrors';
+
+import "deferred_constraints_constants_lib.dart" deferred as lib;
+
+const myConst1 =
+  lib.constantInstance; //# reference1: compile-time error
+  /* //                   //# reference1: continued
+    499;
+  */ //                   //# reference1: continued
+const myConst2 =
+  lib.Const.instance; //# reference2: compile-time error
+  /* //                 //# reference2: continued
+    499;
+  */ //                 //# reference2: continued
+
+void f1(
+    {a:
+  const lib.Const() //# default_argument1: compile-time error
+  /* //                  //# default_argument1: continued
+        499
+  */ //                  //# default_argument1: continued
+    }) {}
+
+void f2(
+    {a:
+  lib.constantInstance //# default_argument2: compile-time error
+  /* //                        //# default_argument2: continued
+        499
+  */ //                        //# default_argument2: continued
+    }) {}
+
+@lib.Const() //# metadata1: compile-time error
+class H1 {}
+
+@lib.Const.instance //# metadata2: compile-time error
+class H2 {}
+
+@lib.Const.namedConstructor() //# metadata3: compile-time error
+class H3 {}
+
+void main() {
+  var a1 = myConst1;
+  var a2 = myConst2;
+
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    var instance = lib.constantInstance;
+    var c1 = const lib.Const(); //# constructor1: compile-time error
+    var c2 = const lib.Const.namedConstructor(); //# constructor2: compile-time error
+    f1();
+    f2();
+    var constInstance = lib.constantInstance; //# reference_after_load: ok
+    var h1 = new H1();
+    var h2 = new H2();
+    var h3 = new H3();
+
+    // Need to access the metadata to trigger the expected compilation error.
+    reflectClass(H1).metadata; //# metadata1: continued
+    reflectClass(H2).metadata; //# metadata2: continued
+    reflectClass(H3).metadata; //# metadata3: continued
+
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart b/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart
new file mode 100644
index 0000000..715628f
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart
@@ -0,0 +1,31 @@
+library lib;
+
+import "deferred_mirrors_metadata_test.dart";
+import "dart:mirrors";
+
+class H {
+  const H();
+}
+
+class F {
+  @H()
+  int f = 0;
+}
+
+@C()
+class E {
+  @D()
+  dynamic f;
+}
+
+String foo() {
+  String c = reflectClass(E).metadata[0].invoke(#toString, []).reflectee;
+  String d = reflectClass(E)
+      .declarations[#f]!
+      .metadata[0]
+      .invoke(#toString, []).reflectee;
+  InstanceMirror i = currentMirrorSystem().findLibrary(#main).metadata[0];
+  String a = i.invoke(#toString, []).reflectee;
+  String b = i.getField(#b).invoke(#toString, []).reflectee;
+  return a + b + c + d;
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_metadata_test.dart b/tests/lib/mirrors/deferred_mirrors_metadata_test.dart
new file mode 100644
index 0000000..02b007d
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_metadata_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2014, 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.
+
+@A(const B())
+library main;
+
+@B()
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import "dart:math";
+
+import 'deferred_mirrors_metadata_lib.dart' deferred as lib1;
+
+class A {
+  final B b;
+  const A(this.b);
+  String toString() => "A";
+}
+
+class B {
+  const B();
+  String toString() => "B";
+}
+
+class C {
+  const C();
+  String toString() => "C";
+}
+
+class D {
+  const D();
+  String toString() => "D";
+}
+
+void main() {
+  asyncStart();
+  lib1.loadLibrary().then((_) {
+    Expect.equals("ABCD", lib1.foo());
+    new C();
+    new D();
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart b/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart
new file mode 100644
index 0000000..e48c4cc
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, 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 lib;
+
+import "dart:mirrors";
+
+class MetaTarget {
+  const MetaTarget();
+}
+
+@MetaTarget()
+class A {
+  String toString() => "A";
+}
+
+String foo() {
+  final a =
+      currentMirrorSystem().findLibrary(#lib).declarations[#A] as ClassMirror;
+  return a.newInstance(Symbol.empty, []).invoke(#toString, []).reflectee;
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart b/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart
new file mode 100644
index 0000000..f0091c8
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that metaTargets can be reached via the mirrorSystem.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import "deferred_mirrors_metatarget_lib.dart" deferred as lib;
+
+void main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals("A", lib.foo());
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_update_lib.dart b/tests/lib/mirrors/deferred_mirrors_update_lib.dart
new file mode 100644
index 0000000..02b1f3b
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_update_lib.dart
@@ -0,0 +1,10 @@
+library lib;
+
+import "dart:mirrors";
+
+class C {}
+
+foo() {
+  var a = new C();
+  print(reflectClass(C).owner);
+}
diff --git a/tests/lib/mirrors/deferred_mirrors_update_test.dart b/tests/lib/mirrors/deferred_mirrors_update_test.dart
new file mode 100644
index 0000000..bf1fbbc
--- /dev/null
+++ b/tests/lib/mirrors/deferred_mirrors_update_test.dart
@@ -0,0 +1,16 @@
+library main;
+
+// Test that the library-mirrors are updated after loading a deferred library.
+
+import "dart:mirrors";
+
+import "deferred_mirrors_update_lib.dart" deferred as l;
+
+class D {}
+
+void main() {
+  print(reflectClass(D).owner);
+  l.loadLibrary().then((_) {
+    l.foo();
+  });
+}
diff --git a/tests/lib/mirrors/deferred_type_other.dart b/tests/lib/mirrors/deferred_type_other.dart
new file mode 100644
index 0000000..58e7417
--- /dev/null
+++ b/tests/lib/mirrors/deferred_type_other.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library deferred_type_other;
+
+class DeferredType {}
diff --git a/tests/lib/mirrors/deferred_type_test.dart b/tests/lib/mirrors/deferred_type_test.dart
new file mode 100644
index 0000000..338680d
--- /dev/null
+++ b/tests/lib/mirrors/deferred_type_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library deferred_type;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import 'deferred_type_other.dart' deferred as other;
+
+bad(other.DeferredType x) {}
+
+main() {
+  print((reflect(bad) as ClosureMirror).function.parameters[0].type);
+  throw "Should have died sooner. other.DeferredType is not loaded";
+}
diff --git a/tests/lib/mirrors/delegate_call_through_getter_test.dart b/tests/lib/mirrors/delegate_call_through_getter_test.dart
new file mode 100644
index 0000000..85040ae
--- /dev/null
+++ b/tests/lib/mirrors/delegate_call_through_getter_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_call_through_getter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  get fakeFunctionCall => new FakeFunctionCall();
+  get fakeFunctionNSM => new FakeFunctionNSM();
+  get closure => (x, y) => '2 $this $x $y';
+  get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w';
+  get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w';
+  get notAClosure => 'Not a closure';
+  noSuchMethod(msg) => 'DNU';
+
+  toString() => 'C';
+}
+
+class Forwarder {
+  dynamic noSuchMethod(Invocation msg) => reflect(new C()).delegate(msg);
+}
+
+main() {
+  dynamic f = new Forwarder();
+
+  Expect.equals('1 5 6', f.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', f.fakeFunctionNSM(7, 8));
+  Expect.equals('2 C 9 10', f.closure(9, 10));
+  Expect.equals('3 C 11 12 13 null', f.closureOpt(11, 12, 13));
+  Expect.equals('4 C 14 15 null 16', f.closureNamed(14, 15, w: 16));
+  Expect.equals('DNU', f.doesNotExist(17, 18));
+  Expect.throwsNoSuchMethodError(() => f.closure('wrong arity'));
+  Expect.throwsNoSuchMethodError(() => f.notAClosure());
+}
diff --git a/tests/lib/mirrors/delegate_class_test.dart b/tests/lib/mirrors/delegate_class_test.dart
new file mode 100644
index 0000000..83ee8f0
--- /dev/null
+++ b/tests/lib/mirrors/delegate_class_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.delegate_class;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class C {
+  static method(a, b, c) => "$a-$b-$c";
+  static methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+  static methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
+  static get getter => 'g';
+  static set setter(x) {
+    field = x * 2;
+  }
+
+  static var field;
+}
+
+class Proxy {
+  var targetMirror;
+  Proxy(this.targetMirror);
+  noSuchMethod(invocation) => targetMirror.delegate(invocation);
+}
+
+main() {
+  dynamic proxy = new Proxy(reflectClass(C));
+  var result;
+
+  Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z'));
+
+  Expect.equals('X-B-null', proxy.methodWithNamed('X'));
+  Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z'));
+
+  Expect.equals('X-null-C', proxy.methodWithOpt('X'));
+  Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z'));
+
+  Expect.equals('g', proxy.getter);
+
+  Expect.equals(5, proxy.setter = 5);
+  Expect.equals(10, proxy.field);
+
+  Expect.equals(5, proxy.field = 5);
+  Expect.equals(5, proxy.field);
+}
diff --git a/tests/lib/mirrors/delegate_function_invocation_test.dart b/tests/lib/mirrors/delegate_function_invocation_test.dart
new file mode 100644
index 0000000..5fe88f4
--- /dev/null
+++ b/tests/lib/mirrors/delegate_function_invocation_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2014, 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 test.delgate_function_invocation;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Proxy {
+  var targetMirror;
+  Proxy(target) : this.targetMirror = reflect(target);
+  noSuchMethod(invocation) => targetMirror.delegate(invocation);
+}
+
+testClosure() {
+  dynamic proxy = new Proxy(() => 42);
+  Expect.equals(42, proxy());
+  Expect.equals(42, proxy.call());
+}
+
+class FakeFunction {
+  call() => 43;
+}
+
+testFakeFunction() {
+  dynamic proxy = new Proxy(new FakeFunction());
+  Expect.equals(43, proxy());
+  Expect.equals(43, proxy.call());
+}
+
+topLevelFunction() => 44;
+
+testTopLevelTearOff() {
+  dynamic proxy = new Proxy(topLevelFunction);
+  Expect.equals(44, proxy());
+  Expect.equals(44, proxy.call());
+}
+
+class C {
+  method() => 45;
+}
+
+testInstanceTearOff() {
+  dynamic proxy = new Proxy(new C().method);
+  Expect.equals(45, proxy());
+  Expect.equals(45, proxy.call());
+}
+
+main() {
+  testClosure();
+  testFakeFunction();
+  testTopLevelTearOff();
+  testInstanceTearOff();
+}
diff --git a/tests/lib/mirrors/delegate_library_test.dart b/tests/lib/mirrors/delegate_library_test.dart
new file mode 100644
index 0000000..a4cf432
--- /dev/null
+++ b/tests/lib/mirrors/delegate_library_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.delegate_library;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+method(a, b, c) => "$a-$b-$c";
+methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
+get getter => 'g';
+set setter(x) {
+  field = x * 2;
+}
+
+var field;
+
+class Proxy {
+  var targetMirror;
+  Proxy(this.targetMirror);
+  noSuchMethod(invocation) => targetMirror.delegate(invocation);
+}
+
+main() {
+  dynamic proxy = new Proxy(reflectClass(Proxy).owner);
+  var result;
+
+  Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z'));
+
+  Expect.equals('X-B-null', proxy.methodWithNamed('X'));
+  Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z'));
+
+  Expect.equals('X-null-C', proxy.methodWithOpt('X'));
+  Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z'));
+
+  Expect.equals('g', proxy.getter);
+
+  Expect.equals(5, proxy.setter = 5);
+  Expect.equals(10, proxy.field);
+
+  Expect.equals(5, proxy.field = 5);
+  Expect.equals(5, proxy.field);
+}
diff --git a/tests/lib/mirrors/delegate_test.dart b/tests/lib/mirrors/delegate_test.dart
new file mode 100644
index 0000000..4c63f28
--- /dev/null
+++ b/tests/lib/mirrors/delegate_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_named_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class C {
+  method(a, b, c) => "$a-$b-$c";
+  methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c";
+  methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c";
+  get getter => 'g';
+  set setter(x) {
+    field = x * 2;
+  }
+
+  var field;
+}
+
+class Proxy {
+  var targetMirror;
+  Proxy(target) : this.targetMirror = reflect(target);
+  noSuchMethod(invocation) => targetMirror.delegate(invocation);
+}
+
+main() {
+  var c = new C();
+  dynamic proxy = new Proxy(c);
+  var result;
+
+  Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z'));
+
+  Expect.equals('X-B-null', proxy.methodWithNamed('X'));
+  Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z'));
+
+  Expect.equals('X-null-C', proxy.methodWithOpt('X'));
+  Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z'));
+
+  Expect.equals('g', proxy.getter);
+
+  Expect.equals(5, proxy.setter = 5);
+  Expect.equals(10, proxy.field);
+
+  Expect.equals(5, proxy.field = 5);
+  Expect.equals(5, proxy.field);
+}
diff --git a/tests/lib/mirrors/disable_tree_shaking_test.dart b/tests/lib/mirrors/disable_tree_shaking_test.dart
new file mode 100644
index 0000000..b34f352
--- /dev/null
+++ b/tests/lib/mirrors/disable_tree_shaking_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Ensure that reflection works on methods that would otherwise be
+// tree-shaken away.
+
+import "dart:mirrors";
+
+class Foo {
+  Foo();
+  foo() => 42;
+}
+
+main() {
+  // Do NOT instantiate Foo.
+  var m = reflectClass(Foo);
+  var instanceMirror = m.newInstance(new Symbol(''), []);
+  var result = instanceMirror.invoke(new Symbol('foo'), []).reflectee;
+  if (result != 42) {
+    throw 'Expected 42, but got $result';
+  }
+}
diff --git a/tests/lib/mirrors/dynamic_load_error.dart b/tests/lib/mirrors/dynamic_load_error.dart
new file mode 100644
index 0000000..f75aaf9
--- /dev/null
+++ b/tests/lib/mirrors/dynamic_load_error.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A top-level parse error:
+import import import import
diff --git a/tests/lib/mirrors/dynamic_load_success.dart b/tests/lib/mirrors/dynamic_load_success.dart
new file mode 100644
index 0000000..1645a92
--- /dev/null
+++ b/tests/lib/mirrors/dynamic_load_success.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dynamic_load_success;
+
+int _counter = 0;
+
+advanceCounter() => ++_counter;
diff --git a/tests/lib/mirrors/dynamic_load_test.dart b/tests/lib/mirrors/dynamic_load_test.dart
new file mode 100644
index 0000000..dddb1ac
--- /dev/null
+++ b/tests/lib/mirrors/dynamic_load_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() async {
+  IsolateMirror isolate = currentMirrorSystem().isolate;
+  print(isolate);
+
+  LibraryMirror success =
+      await isolate.loadUri(Uri.parse("dynamic_load_success.dart"));
+  print(success);
+  InstanceMirror result = success.invoke(#advanceCounter, []);
+  print(result);
+  Expect.equals(1, result.reflectee);
+  result = success.invoke(#advanceCounter, []);
+  print(result);
+  Expect.equals(2, result.reflectee);
+
+  LibraryMirror success2 =
+      await isolate.loadUri(Uri.parse("dynamic_load_success.dart"));
+  print(success2);
+  Expect.equals(success, success2);
+  result = success2.invoke(#advanceCounter, []);
+  print(result);
+  Expect.equals(3, result.reflectee); // Same library, same state.
+
+  LibraryMirror math = await isolate.loadUri(Uri.parse("dart:math"));
+  result = math.invoke(#max, [3, 4]);
+  print(result);
+  Expect.equals(4, result.reflectee);
+
+  Future<LibraryMirror> bad_load = isolate.loadUri(Uri.parse("DOES_NOT_EXIST"));
+  var error;
+  try {
+    await bad_load;
+  } catch (e) {
+    error = e;
+  }
+  print(error);
+  Expect.isTrue(error.toString().contains("Cannot open file") ||
+      error.toString().contains("file not found") ||
+      error.toString().contains("No such file or directory") ||
+      error.toString().contains("The system cannot find the file specified"));
+  Expect.isTrue(error.toString().contains("DOES_NOT_EXIST"));
+
+  Future<LibraryMirror> bad_load2 = isolate.loadUri(Uri.parse("dart:_builtin"));
+  var error2;
+  try {
+    await bad_load2;
+  } catch (e) {
+    error2 = e;
+  }
+  print(error2);
+  Expect.isTrue(error2.toString().contains("Cannot load"));
+  Expect.isTrue(error2.toString().contains("dart:_builtin"));
+
+  // Check error is not sticky.
+  LibraryMirror success3 =
+      await isolate.loadUri(Uri.parse("dynamic_load_success.dart"));
+  print(success3);
+  Expect.equals(success, success3);
+  result = success3.invoke(#advanceCounter, []);
+  print(result);
+  Expect.equals(4, result.reflectee); // Same library, same state.
+
+  Future<LibraryMirror> bad_load3 =
+      isolate.loadUri(Uri.parse("dynamic_load_error.dart"));
+  var error3;
+  try {
+    await bad_load3;
+  } catch (e) {
+    error3 = e;
+  }
+  print(error3);
+  Expect.isTrue(error3.toString().contains("library url expected") ||
+      error3.toString().contains("Error: Expected a String"));
+  Expect.isTrue(error3.toString().contains("dynamic_load_error.dart"));
+}
diff --git a/tests/lib/mirrors/empty.dart b/tests/lib/mirrors/empty.dart
new file mode 100644
index 0000000..e2f6f5e9
--- /dev/null
+++ b/tests/lib/mirrors/empty.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library has no functions.
+library empty;
diff --git a/tests/lib/mirrors/empty_test.dart b/tests/lib/mirrors/empty_test.dart
new file mode 100644
index 0000000..9e77634
--- /dev/null
+++ b/tests/lib/mirrors/empty_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'empty.dart';
+
+main() {
+  var empty = currentMirrorSystem().findLibrary(#empty);
+  print(empty.location); // Used to crash VM.
+}
diff --git a/tests/lib/mirrors/enum_mirror_test.dart b/tests/lib/mirrors/enum_mirror_test.dart
new file mode 100644
index 0000000..00de84b
--- /dev/null
+++ b/tests/lib/mirrors/enum_mirror_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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:mirrors';
+
+import 'package:expect/expect.dart';
+
+enum Foo { BAR, BAZ }
+
+main() {
+  Expect.equals('Foo.BAR', Foo.BAR.toString());
+  var name = reflect(Foo.BAR).invoke(#toString, []).reflectee;
+  Expect.equals('Foo.BAR', name);
+}
diff --git a/tests/lib/mirrors/enum_test.dart b/tests/lib/mirrors/enum_test.dart
new file mode 100644
index 0000000..318bfe6
--- /dev/null
+++ b/tests/lib/mirrors/enum_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.enums;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+class C {}
+
+enum Suite { CLUBS, DIAMONDS, SPADES, HEARTS }
+
+main() {
+  Expect.isFalse(reflectClass(C).isEnum);
+
+  Expect.isTrue(reflectClass(Suite).isEnum);
+  Expect.isFalse(reflectClass(Suite).isAbstract);
+  Expect.equals(
+      0,
+      reflectClass(Suite)
+          .declarations
+          .values
+          .where((d) => d is MethodMirror && d.isConstructor)
+          .length);
+
+  Expect.equals(
+      reflectClass(Suite),
+      (reflectClass(C).owner as LibraryMirror).declarations[#Suite],
+      "found in library");
+
+  Expect.equals(reflectClass(Suite), reflect(Suite.CLUBS).type);
+
+  Expect.equals(0, reflect(Suite.CLUBS).getField(#index).reflectee);
+  Expect.equals(1, reflect(Suite.DIAMONDS).getField(#index).reflectee);
+  Expect.equals(2, reflect(Suite.SPADES).getField(#index).reflectee);
+  Expect.equals(3, reflect(Suite.HEARTS).getField(#index).reflectee);
+
+  Expect.equals(
+      "Suite.CLUBS", reflect(Suite.CLUBS).invoke(#toString, []).reflectee);
+  Expect.equals("Suite.DIAMONDS",
+      reflect(Suite.DIAMONDS).invoke(#toString, []).reflectee);
+  Expect.equals(
+      "Suite.SPADES", reflect(Suite.SPADES).invoke(#toString, []).reflectee);
+  Expect.equals(
+      "Suite.HEARTS", reflect(Suite.HEARTS).invoke(#toString, []).reflectee);
+
+  Expect.setEquals(
+      [
+        'Variable(s(index) in s(Suite), final)',
+        'Variable(s(CLUBS) in s(Suite), static, final)',
+        'Variable(s(DIAMONDS) in s(Suite), static, final)',
+        'Variable(s(SPADES) in s(Suite), static, final)',
+        'Variable(s(HEARTS) in s(Suite), static, final)',
+        'Variable(s(values) in s(Suite), static, final)',
+        'Method(s(hashCode) in s(Suite), getter)',
+        'Method(s(toString) in s(Suite))'
+      ],
+      reflectClass(Suite)
+          .declarations
+          .values
+          .where((d) => !d.isPrivate)
+          .map(stringify));
+}
diff --git a/tests/lib/mirrors/equality_test.dart b/tests/lib/mirrors/equality_test.dart
new file mode 100644
index 0000000..56fd42d
--- /dev/null
+++ b/tests/lib/mirrors/equality_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This tests uses the multi-test "ok" feature:
+// none: Trimmed behaviour. Passing on the VM.
+// 01: Trimmed version for dart2js.
+// 02: Full version passing in the VM.
+//
+// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.
+
+library test.class_equality_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class B extends A<int> {}
+
+class BadEqualityHash {
+  int count = 0;
+  bool operator ==(other) => true;
+  int get hashCode => count++;
+}
+
+typedef bool Predicate(Object o);
+Predicate somePredicate = (Object o) => false;
+
+checkEquality(List<Map<String, Object?>> equivalenceClasses) {
+  for (var equivalenceClass in equivalenceClasses) {
+    equivalenceClass.forEach((name, member) {
+      equivalenceClass.forEach((otherName, otherMember) {
+        // Reflexivity, symmetry and transitivity.
+        Expect.equals(member, otherMember, "$name == $otherName");
+        Expect.equals(member.hashCode, otherMember.hashCode,
+            "$name.hashCode == $otherName.hashCode");
+      });
+      for (var otherEquivalenceClass in equivalenceClasses) {
+        if (otherEquivalenceClass == equivalenceClass) continue;
+        otherEquivalenceClass.forEach((otherName, otherMember) {
+          Expect.notEquals(
+              member, otherMember, "$name != $otherName"); // Exclusion.
+          // Hash codes may or may not be equal.
+        });
+      }
+    });
+  }
+}
+
+void subroutine() {}
+
+main() {
+  LibraryMirror thisLibrary = currentMirrorSystem()
+      .findLibrary(const Symbol('test.class_equality_test'));
+
+  var o1 = new Object();
+  var o2 = new Object();
+
+  var badEqualityHash1 = new BadEqualityHash();
+  var badEqualityHash2 = new BadEqualityHash();
+
+  checkEquality(<Map<String, Object?>>[
+    {'reflect(o1)': reflect(o1), 'reflect(o1), again': reflect(o1)},
+    {'reflect(o2)': reflect(o2), 'reflect(o2), again': reflect(o2)},
+    {
+      'reflect(badEqualityHash1)': reflect(badEqualityHash1),
+      'reflect(badEqualityHash1), again': reflect(badEqualityHash1)
+    },
+    {
+      'reflect(badEqualityHash2)': reflect(badEqualityHash2),
+      'reflect(badEqualityHash2), again': reflect(badEqualityHash2)
+    },
+    {'reflect(true)': reflect(true), 'reflect(true), again': reflect(true)},
+    {'reflect(false)': reflect(false), 'reflect(false), again': reflect(false)},
+    {'reflect(null)': reflect(null), 'reflect(null), again': reflect(null)},
+    {
+      'reflect(3.5+4.5)': reflect(3.5 + 4.5),
+      'reflect(6.5+1.5)': reflect(6.5 + 1.5)
+    },
+    {'reflect(3+4)': reflect(3 + 4), 'reflect(6+1)': reflect(6 + 1)},
+    {'reflect("foo")': reflect("foo"), 'reflect("foo"), again': reflect("foo")},
+    {
+      'currentMirrorSystem().voidType': currentMirrorSystem().voidType,
+      'thisLibrary.declarations[#subroutine].returnType':
+          (thisLibrary.declarations[#subroutine] as MethodMirror).returnType
+    },
+    {
+      'currentMirrorSystem().dynamicType': currentMirrorSystem().dynamicType,
+      'thisLibrary.declarations[#main].returnType':
+          (thisLibrary.declarations[#main] as MethodMirror).returnType
+    },
+    {
+      'reflectClass(A)': reflectClass(A),
+      'thisLibrary.declarations[#A]': thisLibrary.declarations[#A],
+      'reflect(new A<int>()).type.originalDeclaration':
+          reflect(new A<int>()).type.originalDeclaration
+    },
+    {
+      'reflectClass(B).superclass': reflectClass(B).superclass,
+      'reflect(new A<int>()).type': reflect(new A<int>()).type
+    },
+    {
+      'reflectClass(B)': reflectClass(B),
+      'thisLibrary.declarations[#B]': thisLibrary.declarations[#B],
+      'reflect(new B()).type': reflect(new B()).type
+    },
+    {
+      'reflectClass(BadEqualityHash).declarations[#==]':
+          reflectClass(BadEqualityHash).declarations[#==],
+      'reflect(new BadEqualityHash()).type.declarations[#==]':
+          reflect(new BadEqualityHash()).type.declarations[#==]
+    },
+    {
+      'reflectClass(BadEqualityHash).declarations[#==].parameters[0]':
+          (reflectClass(BadEqualityHash).declarations[#==] as MethodMirror)
+              .parameters[0],
+      'reflect(new BadEqualityHash()).type.declarations[#==].parameters[0]':
+          (reflect(new BadEqualityHash()).type.declarations[#==]
+                  as MethodMirror)
+              .parameters[0]
+    },
+    {
+      'reflectClass(BadEqualityHash).declarations[#count]':
+          reflectClass(BadEqualityHash).declarations[#count],
+      'reflect(new BadEqualityHash()).type.declarations[#count]':
+          reflect(new BadEqualityHash()).type.declarations[#count]
+    },
+    {
+      'reflectType(Predicate)': reflectType(Predicate),
+      'thisLibrary.declarations[#somePredicate].type':
+          (thisLibrary.declarations[#somePredicate] as VariableMirror).type
+    },
+    {
+      'reflectType(Predicate).referent':
+          (reflectType(Predicate) as TypedefMirror).referent,
+      'thisLibrary.declarations[#somePredicate].type.referent':
+          ((thisLibrary.declarations[#somePredicate] as VariableMirror).type
+                  as TypedefMirror)
+              .referent
+    },
+    {
+      'reflectClass(A).typeVariables.single':
+          reflectClass(A).typeVariables.single,
+      'reflect(new A<int>()).type.originalDeclaration.typeVariables.single':
+          reflect(new A<int>()).type.originalDeclaration.typeVariables.single
+    },
+    {'currentMirrorSystem()': currentMirrorSystem()},
+    {'currentMirrorSystem().isolate': currentMirrorSystem().isolate},
+    {
+      'thisLibrary': thisLibrary,
+      'reflectClass(A).owner': reflectClass(A).owner,
+      'reflectClass(B).owner': reflectClass(B).owner,
+      'reflect(new A()).type.owner': reflect(new A()).type.owner,
+      'reflect(new B()).type.owner': reflect(new B()).type.owner
+    },
+  ]);
+}
diff --git a/tests/lib/mirrors/fake_function_with_call_test.dart b/tests/lib/mirrors/fake_function_with_call_test.dart
new file mode 100644
index 0000000..43522bc
--- /dev/null
+++ b/tests/lib/mirrors/fake_function_with_call_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+membersOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && !v.isConstructor) result[k] = v;
+    if (v is VariableMirror) result[k] = v;
+  });
+  return result;
+}
+
+class WannabeFunction {
+  int call(int a, int b) => a + b;
+  method(x) => x * x;
+}
+
+main() {
+  Expect.isTrue(new WannabeFunction() is Function);
+
+  ClosureMirror cm = reflect(new WannabeFunction()) as ClosureMirror;
+  Expect.equals(7, cm.invoke(#call, [3, 4]).reflectee);
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#call, [3]), "Wrong arity");
+  Expect.equals(49, cm.invoke(#method, [7]).reflectee);
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#method, [3, 4]),
+      "Wrong arity");
+  Expect.equals(7, cm.apply([3, 4]).reflectee);
+  Expect.throwsNoSuchMethodError(() => cm.apply([3]), "Wrong arity");
+
+  MethodMirror mm = cm.function;
+  Expect.equals(#call, mm.simpleName);
+  Expect.equals(reflectClass(WannabeFunction), mm.owner);
+  Expect.isTrue(mm.isRegularMethod);
+  Expect.equals(#int, mm.returnType.simpleName);
+  Expect.equals(#int, mm.parameters[0].type.simpleName);
+  Expect.equals(#int, mm.parameters[1].type.simpleName);
+
+  ClassMirror km = cm.type;
+  Expect.equals(reflectClass(WannabeFunction), km);
+  Expect.equals(#WannabeFunction, km.simpleName);
+  Expect.equals(mm.hashCode, km.declarations[#call].hashCode);
+  Expect.setEquals([#call, #method], membersOf(km).keys);
+}
diff --git a/tests/lib/mirrors/fake_function_without_call_test.dart b/tests/lib/mirrors/fake_function_without_call_test.dart
new file mode 100644
index 0000000..3d80c03
--- /dev/null
+++ b/tests/lib/mirrors/fake_function_without_call_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class MultiArityFunction implements Function {
+  noSuchMethod(Invocation msg) {
+    if (msg.memberName != #call) return super.noSuchMethod(msg);
+    return msg.positionalArguments.join(",");
+  }
+}
+
+main() {
+  dynamic f = new MultiArityFunction();
+
+  Expect.isTrue(f is Function);
+  Expect.equals('a', f('a'));
+  Expect.equals('a,b', f('a', 'b'));
+  Expect.equals('a,b,c', f('a', 'b', 'c'));
+  Expect.equals('a', Function.apply(f, ['a']));
+  Expect.equals('a,b', Function.apply(f, ['a', 'b']));
+  Expect.equals('a,b,c', Function.apply(f, ['a', 'b', 'c']));
+  Expect.throwsNoSuchMethodError(() => f.foo('a', 'b', 'c'));
+
+  ClosureMirror cm = reflect(f) as ClosureMirror;
+  Expect.isTrue(cm is ClosureMirror);
+  Expect.equals('a', cm.apply(['a']).reflectee);
+  Expect.equals('a,b', cm.apply(['a', 'b']).reflectee);
+  Expect.equals('a,b,c', cm.apply(['a', 'b', 'c']).reflectee);
+
+  MethodMirror mm = cm.function;
+  Expect.isNull(mm);
+
+  ClassMirror km = cm.type;
+  Expect.equals(reflectClass(MultiArityFunction), km);
+}
diff --git a/tests/lib/mirrors/field_metadata2_test.dart b/tests/lib/mirrors/field_metadata2_test.dart
new file mode 100644
index 0000000..60e1b6c
--- /dev/null
+++ b/tests/lib/mirrors/field_metadata2_test.dart
@@ -0,0 +1,28 @@
+// compile options: --emit-metadata
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Run essentially the same test, but with emit-metadata compile option,
+// which allows us to reflect on the fields.
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'field_metadata_test.dart' as field_metadata_test;
+import 'field_metadata_test.dart' show Foo, Bar;
+
+void main() {
+  // Make sure the other test still works.
+  field_metadata_test.main();
+
+  // Check that we can now reflect on the annotations.
+  dynamic f = new Foo();
+  var members = reflect(f).type.declarations;
+  var x = members[#x] as VariableMirror;
+  var bar = x.metadata.first.reflectee as Bar;
+  Expect.equals(bar.name, 'bar');
+
+  var y = members[#y] as VariableMirror;
+  var baz = y.metadata.first.reflectee as Bar;
+  Expect.equals(baz.name, 'baz');
+}
diff --git a/tests/lib/mirrors/field_metadata_test.dart b/tests/lib/mirrors/field_metadata_test.dart
new file mode 100644
index 0000000..3abc991
--- /dev/null
+++ b/tests/lib/mirrors/field_metadata_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Bar {
+  final String name;
+
+  const Bar(this.name);
+}
+
+class Foo {
+  @Bar('bar')
+  int x = 40;
+
+  @Bar('baz')
+  final String y = 'hi';
+
+  @Bar('foo')
+  void set z(int val) {
+    x = val;
+  }
+}
+
+void main() {
+  dynamic f = new Foo();
+  f.x += 2;
+  Expect.equals(f.x, 42);
+  Expect.equals(f.y, 'hi');
+
+  f.z = 0;
+  Expect.equals(f.x, 0);
+
+  var members = reflect(f).type.declarations;
+  var x = members[#x] as VariableMirror;
+  var y = members[#y] as VariableMirror;
+  Expect.equals(x.type.simpleName, #int);
+  Expect.equals(y.type.simpleName, #String);
+}
diff --git a/tests/lib/mirrors/field_type_test.dart b/tests/lib/mirrors/field_type_test.dart
new file mode 100644
index 0000000..2957417
--- /dev/null
+++ b/tests/lib/mirrors/field_type_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library field_test;
+
+import 'dart:mirrors';
+import "package:expect/expect.dart";
+
+String toplevelVariable = "";
+
+class C {
+  final int i;
+  const C(this.i);
+}
+
+class A<T> {
+  static int staticField = 0;
+  @C(42)
+  @C(44)
+  String field = "";
+  var dynamicTypeField;
+  late T typeVariableField;
+  late H<int> parameterizedTypeField;
+}
+
+class H<T> {}
+
+testOriginalDeclaration() {
+  ClassMirror a = reflectClass(A);
+  VariableMirror staticField = a.declarations[#staticField] as VariableMirror;
+  VariableMirror field = a.declarations[#field] as VariableMirror;
+  VariableMirror dynamicTypeField =
+      a.declarations[#dynamicTypeField] as VariableMirror;
+  VariableMirror typeVariableField =
+      a.declarations[#typeVariableField] as VariableMirror;
+  VariableMirror parameterizedTypeField =
+      a.declarations[#parameterizedTypeField] as VariableMirror;
+
+  Expect.equals(reflectType(int), staticField.type);
+  Expect.equals(reflectClass(String), field.type);
+  Expect.equals(reflectType(dynamic), dynamicTypeField.type);
+  Expect.equals(a.typeVariables.single, typeVariableField.type);
+  Expect.equals(reflect(new H<int>()).type, parameterizedTypeField.type);
+
+  Expect.equals(2, field.metadata.length);
+  Expect.equals(reflect(const C(42)), field.metadata.first);
+  Expect.equals(reflect(const C(44)), field.metadata.last);
+}
+
+testInstance() {
+  ClassMirror aOfString = reflect(new A<String>()).type;
+  VariableMirror staticField =
+      aOfString.declarations[#staticField] as VariableMirror;
+  VariableMirror field = aOfString.declarations[#field] as VariableMirror;
+  VariableMirror dynamicTypeField =
+      aOfString.declarations[#dynamicTypeField] as VariableMirror;
+  VariableMirror typeVariableField =
+      aOfString.declarations[#typeVariableField] as VariableMirror;
+  VariableMirror parameterizedTypeField =
+      aOfString.declarations[#parameterizedTypeField] as VariableMirror;
+
+  Expect.equals(reflectType(int), staticField.type);
+  Expect.equals(reflectClass(String), field.type);
+  Expect.equals(reflectType(dynamic), dynamicTypeField.type);
+  Expect.equals(reflectClass(String), typeVariableField.type);
+  Expect.equals(reflect(new H<int>()).type, parameterizedTypeField.type);
+
+  Expect.equals(2, field.metadata.length);
+  Expect.equals(reflect(const C(42)), field.metadata.first);
+  Expect.equals(reflect(const C(44)), field.metadata.last);
+}
+
+testTopLevel() {
+  LibraryMirror currentLibrary = currentMirrorSystem().findLibrary(#field_test);
+  VariableMirror topLevel =
+      currentLibrary.declarations[#toplevelVariable] as VariableMirror;
+  Expect.equals(reflectClass(String), topLevel.type);
+}
+
+main() {
+  testOriginalDeclaration();
+  testInstance();
+  testTopLevel();
+}
diff --git a/tests/lib/mirrors/function_apply_mirrors_lib.dart b/tests/lib/mirrors/function_apply_mirrors_lib.dart
new file mode 100644
index 0000000..3c4c510
--- /dev/null
+++ b/tests/lib/mirrors/function_apply_mirrors_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library function_apply_mirrors_lib;
+
+import "dart:mirrors";
+
+bar() => reflect(499).reflectee;
diff --git a/tests/lib/mirrors/function_apply_mirrors_test.dart b/tests/lib/mirrors/function_apply_mirrors_test.dart
new file mode 100644
index 0000000..81d3b9e
--- /dev/null
+++ b/tests/lib/mirrors/function_apply_mirrors_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Only 'lib' imports mirrors.
+// Function.apply is resolved, before it is known that mirrors are used.
+// Dart2js has different implementations of Function.apply for different
+// emitters (like --fast-startup). Dart2js must not switch the resolved
+// Function.apply when it discovers the use of mirrors.
+// In particular it must not switch from the fast-startup emitter to the full
+// emitter without updating the Function.apply reference.
+import 'function_apply_mirrors_lib.dart' as lib;
+
+import "package:expect/expect.dart";
+
+int foo({x: 499, y: 42}) => x + y;
+
+main() {
+  Expect.equals(709, Function.apply(foo, [], {#y: 210}));
+  Expect.equals(499, lib.bar());
+}
diff --git a/tests/lib/mirrors/function_apply_test.dart b/tests/lib/mirrors/function_apply_test.dart
new file mode 100644
index 0000000..206d08b
--- /dev/null
+++ b/tests/lib/mirrors/function_apply_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class A {
+  call(int x) => 123 + x;
+  bar(int y) => 321 + y;
+}
+
+foo(int y) => 456 + y;
+
+main() {
+  // Static function.
+  ClosureMirror f1 = reflect(foo) as ClosureMirror;
+  Expect.equals(1456, f1.apply([1000]).reflectee);
+
+  // Local declaration.
+  chomp(int z) => z + 42;
+  ClosureMirror f2 = reflect(chomp) as ClosureMirror;
+  Expect.equals(1042, f2.apply([1000]).reflectee);
+
+  // Local expression.
+  ClosureMirror f3 = reflect((u) => u + 987) as ClosureMirror;
+  Expect.equals(1987, f3.apply([1000]).reflectee);
+
+  // Instance property extraction.
+  ClosureMirror f4 = reflect(new A().bar) as ClosureMirror;
+  Expect.equals(1321, f4.apply([1000]).reflectee);
+
+  // Instance implementing Function via call method.
+  ClosureMirror f5 = reflect(new A()) as ClosureMirror;
+  Expect.equals(1123, f5.apply([1000]).reflectee);
+}
diff --git a/tests/lib/mirrors/function_type_mirror_test.dart b/tests/lib/mirrors/function_type_mirror_test.dart
new file mode 100644
index 0000000..3b2a595
--- /dev/null
+++ b/tests/lib/mirrors/function_type_mirror_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+typedef void FooFunction(int a, double b);
+
+bar(int a) {}
+
+main() {
+  TypedefMirror tm = reflectType(FooFunction) as TypedefMirror;
+  FunctionTypeMirror ftm = tm.referent;
+  Expect.equals(const Symbol('void'), ftm.returnType.simpleName);
+  Expect.equals(#int, ftm.parameters[0].type.simpleName);
+  Expect.equals(#double, ftm.parameters[1].type.simpleName);
+  ClosureMirror cm = reflect(bar) as ClosureMirror;
+  ftm = cm.type as FunctionTypeMirror;
+  Expect.equals(#dynamic, ftm.returnType.simpleName);
+  Expect.equals(#int, ftm.parameters[0].type.simpleName);
+}
diff --git a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
new file mode 100644
index 0000000..46e731f
--- /dev/null
+++ b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_bounded_by_type_parameter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Super<T, R extends T> {}
+
+class Fixed extends Super<num, int> {}
+
+class Generic<X, Y> extends Super<X, Y> {} //# 02: compile-time error
+
+main() {
+  ClassMirror superDecl = reflectClass(Super);
+  ClassMirror superOfNumAndInt = reflectClass(Fixed).superclass!;
+  ClassMirror genericDecl = reflectClass(Generic); // //# 02: continued
+  ClassMirror superOfXAndY = genericDecl.superclass!; // //# 02: continued
+  ClassMirror genericOfNumAndDouble = reflect(new Generic<num, double>()).type; // //# 02: continued
+  ClassMirror superOfNumAndDouble = genericOfNumAndDouble.superclass!; // //# 02: continued
+
+  ClassMirror genericOfNumAndBool = reflect(new Generic<num, bool>()).type; // //# 02: compile-time error
+  ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass!; // //# 02: continued
+  Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfNumAndBool.isOriginalDeclaration); // //# 02: continued
+  typeParameters(genericOfNumAndBool, [#X, #Y]); // //# 02: continued
+  typeParameters(superOfNumAndBool, [#T, #R]); // //# 02: continued
+  typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]); // //# 02: continued
+  typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]); // //# 02: continued
+
+  Expect.isTrue(superDecl.isOriginalDeclaration);
+  Expect.isFalse(superOfNumAndInt.isOriginalDeclaration);
+  Expect.isTrue(genericDecl.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfXAndY.isOriginalDeclaration); //  //# 02: continued
+  Expect.isFalse(genericOfNumAndDouble.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfNumAndDouble.isOriginalDeclaration); // //# 02: continued
+
+  TypeVariableMirror tFromSuper = superDecl.typeVariables[0];
+  TypeVariableMirror rFromSuper = superDecl.typeVariables[1];
+  TypeVariableMirror xFromGeneric = genericDecl.typeVariables[0]; // //# 02: continued
+  TypeVariableMirror yFromGeneric = genericDecl.typeVariables[1]; // //# 02: continued
+
+  Expect.equals(reflectClass(Object), tFromSuper.upperBound);
+  Expect.equals(tFromSuper, rFromSuper.upperBound);
+  Expect.equals(reflectClass(Object), xFromGeneric.upperBound); // //# 02: continued
+  Expect.equals(reflectClass(Object), yFromGeneric.upperBound); // //# 02: continued
+
+  typeParameters(superDecl, [#T, #R]);
+  typeParameters(superOfNumAndInt, [#T, #R]);
+  typeParameters(genericDecl, [#X, #Y]); // //# 02: continued
+  typeParameters(superOfXAndY, [#T, #R]); // //# 02: continued
+  typeParameters(genericOfNumAndDouble, [#X, #Y]); // //# 02: continued
+  typeParameters(superOfNumAndDouble, [#T, #R]); // //# 02: continued
+
+  typeArguments(superDecl, []);
+  typeArguments(superOfNumAndInt, [reflectClass(num), reflectClass(int)]);
+  typeArguments(genericDecl, []); // //# 02: continued
+  typeArguments(superOfXAndY, [xFromGeneric, yFromGeneric]); // //# 02: continued
+  typeArguments(genericOfNumAndDouble, [reflectClass(num), reflectClass(double)]); // //# 02: continued
+  typeArguments(superOfNumAndDouble, [reflectClass(num), reflectClass(double)]); // //# 02: continued
+}
diff --git a/tests/lib/mirrors/generic_bounded_test.dart b/tests/lib/mirrors/generic_bounded_test.dart
new file mode 100644
index 0000000..01301fb
--- /dev/null
+++ b/tests/lib/mirrors/generic_bounded_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_bounded;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Super<T extends num> {}
+
+class Fixed extends Super<int> {}
+class Generic<R> extends Super<R> {} // //# 02: compile-time error
+class Malbounded extends Super<String> {} //# 01: compile-time error
+
+main() {
+  ClassMirror superDecl = reflectClass(Super);
+  ClassMirror superOfInt = reflectClass(Fixed).superclass!;
+  ClassMirror genericDecl = reflectClass(Generic); // //# 02: continued
+  ClassMirror superOfR = genericDecl.superclass!; // //# 02: continued
+  ClassMirror genericOfDouble = reflect(new Generic<double>()).type; // //# 02: continued
+  ClassMirror superOfDouble = genericOfDouble.superclass!; // //# 02: continued
+  ClassMirror genericOfBool = reflect(new Generic<bool>()).type; // //# 02: compile-time error
+  ClassMirror superOfBool = genericOfBool.superclass!; // //# 02: continued
+  Expect.isFalse(genericOfBool.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfBool.isOriginalDeclaration); // //# 02: continued
+  typeParameters(genericOfBool, [#R]); // //# 02: continued
+  typeParameters(superOfBool, [#T]); // //# 02: continued
+  typeArguments(genericOfBool, [reflectClass(bool)]); // //# 02: continued
+  typeArguments(superOfBool, [reflectClass(bool)]); // //# 02: continued
+
+  ClassMirror superOfString = reflectClass(Malbounded).superclass!; // //# 01: continued
+
+  Expect.isTrue(superDecl.isOriginalDeclaration);
+  Expect.isFalse(superOfInt.isOriginalDeclaration);
+  Expect.isTrue(genericDecl.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfR.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(genericOfDouble.isOriginalDeclaration); // //# 02: continued
+  Expect.isFalse(superOfDouble.isOriginalDeclaration); // //# 02: continued
+
+  Expect.isFalse(superOfString.isOriginalDeclaration); // //# 01: continued
+
+  TypeVariableMirror tFromSuper = superDecl.typeVariables.single;
+  TypeVariableMirror rFromGeneric = genericDecl.typeVariables.single; // //# 02: continued
+
+  Expect.equals(reflectClass(num), tFromSuper.upperBound);
+  Expect.equals(reflectClass(Object), rFromGeneric.upperBound); // //# 02: continued
+
+  typeParameters(superDecl, [#T]);
+  typeParameters(superOfInt, [#T]);
+  typeParameters(genericDecl, [#R]); // //# 02: continued
+  typeParameters(superOfR, [#T]); // //# 02: continued
+  typeParameters(genericOfDouble, [#R]); // //# 02: continued
+  typeParameters(superOfDouble, [#T]); // //# 02: continued
+  typeParameters(superOfString, [#T]); // //# 01: continued
+
+  typeArguments(superDecl, []);
+  typeArguments(superOfInt, [reflectClass(int)]);
+  typeArguments(genericDecl, []); // //# 02: continued
+  typeArguments(superOfR, [rFromGeneric]); // //# 02: continued
+  typeArguments(genericOfDouble, [reflectClass(double)]); // //# 02: continued
+  typeArguments(superOfDouble, [reflectClass(double)]); // //# 02: continued
+  typeArguments(superOfString, [reflectClass(String)]); // //# 01: continued
+}
diff --git a/tests/lib/mirrors/generic_class_declaration_test.dart b/tests/lib/mirrors/generic_class_declaration_test.dart
new file mode 100644
index 0000000..79ebee1
--- /dev/null
+++ b/tests/lib/mirrors/generic_class_declaration_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+
+class A<T> {
+  var instanceVariable;
+  get instanceGetter => null;
+  set instanceSetter(x) => x;
+  instanceMethod() => null;
+
+  var _instanceVariable;
+  get _instanceGetter => null;
+  set _instanceSetter(x) => x;
+  _instanceMethod() => null;
+
+  static var staticVariable;
+  static get staticGetter => null;
+  static set staticSetter(x) => x;
+  static staticMethod() => null;
+
+  static var _staticVariable;
+  static get _staticGetter => null;
+  static set _staticSetter(x) => x;
+  static _staticMethod() => null;
+}
+
+main() {
+  ClassMirror cm = reflect(new A<String>()).type;
+  Expect.setEquals([
+    'Variable(s(_instanceVariable) in s(A), private)',
+    'Variable(s(_staticVariable) in s(A), private, static)',
+    'Variable(s(instanceVariable) in s(A))',
+    'Variable(s(staticVariable) in s(A), static)'
+  ], cm.declarations.values.where((dm) => dm is VariableMirror).map(stringify),
+      'variables');
+
+  Expect.setEquals(
+      [
+        'Method(s(_instanceGetter) in s(A), private, getter)',
+        'Method(s(_staticGetter) in s(A), private, static, getter)',
+        'Method(s(instanceGetter) in s(A), getter)',
+        'Method(s(staticGetter) in s(A), static, getter)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isGetter)
+          .map(stringify),
+      'getters');
+
+  Expect.setEquals(
+      [
+        'Method(s(_instanceSetter=) in s(A), private, setter)',
+        'Method(s(_staticSetter=) in s(A), private, static, setter)',
+        'Method(s(instanceSetter=) in s(A), setter)',
+        'Method(s(staticSetter=) in s(A), static, setter)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isSetter)
+          .map(stringify),
+      'setters');
+
+  Expect.setEquals(
+      [
+        'Method(s(_instanceMethod) in s(A), private)',
+        'Method(s(_staticMethod) in s(A), private, static)',
+        'Method(s(instanceMethod) in s(A))',
+        'Method(s(staticMethod) in s(A), static)'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isRegularMethod)
+          .map(stringify),
+      'methods');
+
+  Expect.setEquals(
+      ['Method(s(A) in s(A), constructor)'],
+      cm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isConstructor)
+          .map(stringify),
+      'constructors');
+
+  Expect.setEquals(
+      [
+        'TypeVariable(s(T) in s(A), upperBound = Class(s(Object) in '
+            's(dart.core), top-level))'
+      ],
+      cm.declarations.values
+          .where((dm) => dm is TypeVariableMirror)
+          .map(stringify),
+      'type variables');
+}
diff --git a/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart b/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart
new file mode 100644
index 0000000..f3fdfe0
--- /dev/null
+++ b/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_f_bounded;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Collection<C> {}
+
+class Serializable<S> {}
+
+class OrderedCollection<V> extends Collection<V>
+    with Serializable<OrderedCollection<V>> {}
+
+class AbstractOrderedCollection<W> = Collection<W>
+    with Serializable<AbstractOrderedCollection<W>>;
+
+class CustomOrderedCollection<Z> extends AbstractOrderedCollection<Z> {}
+
+class OrderedIntegerCollection extends OrderedCollection<int> {}
+
+class CustomOrderedIntegerCollection extends CustomOrderedCollection<int> {}
+
+class Serializer<R extends Serializable<R>> {}
+
+class CollectionSerializer extends Serializer<Collection> {}
+
+class OrderedCollectionSerializer extends Serializer<OrderedCollection> {}
+
+main() {
+  ClassMirror collectionDecl = reflectClass(Collection);
+  ClassMirror serializableDecl = reflectClass(Serializable);
+  ClassMirror orderedCollectionDecl = reflectClass(OrderedCollection);
+  ClassMirror abstractOrderedCollectionDecl =
+      reflectClass(AbstractOrderedCollection);
+  ClassMirror customOrderedCollectionDecl =
+      reflectClass(CustomOrderedCollection);
+  ClassMirror orderedIntegerCollection = reflectClass(OrderedIntegerCollection);
+  ClassMirror customOrderedIntegerCollection =
+      reflectClass(CustomOrderedIntegerCollection);
+  ClassMirror serializerDecl = reflectClass(Serializer);
+  ClassMirror collectionSerializerDecl = reflectClass(CollectionSerializer);
+  ClassMirror orderedCollectionSerializerDecl =
+      reflectClass(OrderedCollectionSerializer);
+
+  ClassMirror orderedCollectionOfInt = orderedIntegerCollection.superclass!;
+  ClassMirror customOrderedCollectionOfInt =
+      customOrderedIntegerCollection.superclass!;
+  ClassMirror serializerOfCollection = collectionSerializerDecl.superclass!;
+  ClassMirror serializerOfOrderedCollection =
+      orderedCollectionSerializerDecl.superclass!;
+  ClassMirror collectionOfDynamic = reflect(new Collection()).type;
+  ClassMirror orderedCollectionOfDynamic =
+      reflect(new OrderedCollection()).type;
+  ClassMirror collectionWithSerializableOfOrderedCollection =
+      orderedCollectionDecl.superclass!;
+
+  Expect.isTrue(collectionDecl.isOriginalDeclaration);
+  Expect.isTrue(serializableDecl.isOriginalDeclaration);
+  Expect.isTrue(orderedCollectionDecl.isOriginalDeclaration);
+  Expect.isTrue(abstractOrderedCollectionDecl.isOriginalDeclaration);
+  Expect.isTrue(customOrderedCollectionDecl.isOriginalDeclaration);
+  Expect.isTrue(orderedIntegerCollection.isOriginalDeclaration);
+  Expect.isTrue(customOrderedIntegerCollection.isOriginalDeclaration);
+  Expect.isTrue(serializerDecl.isOriginalDeclaration);
+  Expect.isTrue(collectionSerializerDecl.isOriginalDeclaration);
+  Expect.isTrue(orderedCollectionSerializerDecl.isOriginalDeclaration);
+
+  Expect.isFalse(orderedCollectionOfInt.isOriginalDeclaration);
+  Expect.isFalse(customOrderedCollectionOfInt.isOriginalDeclaration);
+  Expect.isFalse(serializerOfCollection.isOriginalDeclaration);
+  Expect.isFalse(serializerOfOrderedCollection.isOriginalDeclaration);
+  Expect.isFalse(collectionOfDynamic.isOriginalDeclaration);
+  Expect.isFalse(
+      collectionWithSerializableOfOrderedCollection.isOriginalDeclaration);
+
+  TypeVariableMirror rFromSerializer = serializerDecl.typeVariables.single;
+  ClassMirror serializableOfR = rFromSerializer.upperBound as ClassMirror;
+  Expect.isFalse(serializableOfR.isOriginalDeclaration);
+  Expect.equals(serializableDecl, serializableOfR.originalDeclaration);
+  Expect.equals(rFromSerializer, serializableOfR.typeArguments.single);
+
+  typeParameters(collectionDecl, [#C]);
+  typeParameters(serializableDecl, [#S]);
+  typeParameters(orderedCollectionDecl, [#V]);
+  typeParameters(abstractOrderedCollectionDecl, [#W]);
+  typeParameters(customOrderedCollectionDecl, [#Z]);
+  typeParameters(orderedIntegerCollection, []);
+  typeParameters(customOrderedIntegerCollection, []);
+  typeParameters(serializerDecl, [#R]);
+  typeParameters(collectionSerializerDecl, []);
+  typeParameters(orderedCollectionSerializerDecl, []);
+
+  typeParameters(orderedCollectionOfInt, [#V]);
+  typeParameters(customOrderedCollectionOfInt, [#Z]);
+  typeParameters(serializerOfCollection, [#R]);
+  typeParameters(serializerOfOrderedCollection, [#R]);
+  typeParameters(collectionOfDynamic, [#C]);
+  typeParameters(collectionWithSerializableOfOrderedCollection, []);
+
+  typeArguments(collectionDecl, []);
+  typeArguments(serializableDecl, []);
+  typeArguments(orderedCollectionDecl, []);
+  typeArguments(abstractOrderedCollectionDecl, []);
+  typeArguments(customOrderedCollectionDecl, []);
+  typeArguments(orderedIntegerCollection, []);
+  typeArguments(customOrderedIntegerCollection, []);
+  typeArguments(serializerDecl, []);
+  typeArguments(collectionSerializerDecl, []);
+  typeArguments(orderedCollectionSerializerDecl, []);
+
+  typeArguments(orderedCollectionOfInt, [reflectClass(int)]);
+  typeArguments(customOrderedCollectionOfInt, [reflectClass(int)]);
+  typeArguments(serializerOfCollection, [collectionOfDynamic]);
+  typeArguments(serializerOfOrderedCollection, [orderedCollectionOfDynamic]);
+  typeArguments(collectionWithSerializableOfOrderedCollection, []);
+}
diff --git a/tests/lib/mirrors/generic_f_bounded_test.dart b/tests/lib/mirrors/generic_f_bounded_test.dart
new file mode 100644
index 0000000..5f84435
--- /dev/null
+++ b/tests/lib/mirrors/generic_f_bounded_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_f_bounded;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Magnitude<T> {}
+
+class Real extends Magnitude<Real> {}
+
+class Sorter<R extends Magnitude<R>> {}
+
+class RealSorter extends Sorter<Real> {}
+
+main() {
+  ClassMirror magnitudeDecl = reflectClass(Magnitude);
+  ClassMirror realDecl = reflectClass(Real);
+  ClassMirror sorterDecl = reflectClass(Sorter);
+  ClassMirror realSorterDecl = reflectClass(RealSorter);
+  ClassMirror magnitudeOfReal = realDecl.superclass!;
+  ClassMirror sorterOfReal = realSorterDecl.superclass!;
+
+  Expect.isTrue(magnitudeDecl.isOriginalDeclaration);
+  Expect.isTrue(realDecl.isOriginalDeclaration);
+  Expect.isTrue(sorterDecl.isOriginalDeclaration);
+  Expect.isTrue(realSorterDecl.isOriginalDeclaration);
+  Expect.isFalse(magnitudeOfReal.isOriginalDeclaration);
+  Expect.isFalse(sorterOfReal.isOriginalDeclaration);
+
+  TypeVariableMirror tFromMagnitude = magnitudeDecl.typeVariables.single;
+  TypeVariableMirror rFromSorter = sorterDecl.typeVariables.single;
+
+  Expect.equals(reflectClass(Object), tFromMagnitude.upperBound);
+
+  ClassMirror magnitudeOfR = rFromSorter.upperBound as ClassMirror;
+  Expect.isFalse(magnitudeOfR.isOriginalDeclaration);
+  Expect.equals(magnitudeDecl, magnitudeOfR.originalDeclaration);
+  Expect.equals(rFromSorter, magnitudeOfR.typeArguments.single);
+
+  typeParameters(magnitudeDecl, [#T]);
+  typeParameters(realDecl, []);
+  typeParameters(sorterDecl, [#R]);
+  typeParameters(realSorterDecl, []);
+  typeParameters(magnitudeOfReal, [#T]);
+  typeParameters(sorterOfReal, [#R]);
+  typeParameters(magnitudeOfR, [#T]);
+
+  typeArguments(magnitudeDecl, []);
+  typeArguments(realDecl, []);
+  typeArguments(sorterDecl, []);
+  typeArguments(realSorterDecl, []);
+  typeArguments(magnitudeOfReal, [realDecl]); //# 01: ok
+  typeArguments(sorterOfReal, [realDecl]); //# 01: ok
+  typeArguments(magnitudeOfR, [rFromSorter]);
+}
diff --git a/tests/lib/mirrors/generic_function_typedef_test.dart b/tests/lib/mirrors/generic_function_typedef_test.dart
new file mode 100644
index 0000000..bee4310
--- /dev/null
+++ b/tests/lib/mirrors/generic_function_typedef_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_function_typedef;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+typedef bool NonGenericPredicate(num n);
+typedef bool GenericPredicate<T>(T t);
+typedef S GenericTransform<S>(S s);
+
+class C<R> {
+  GenericPredicate<num> predicateOfNum = (num n) => false;
+  GenericTransform<String> transformOfString = (String s) => s;
+  GenericTransform<R> transformOfR = (R r) => r;
+}
+
+reflectTypeDeclaration(t) => reflectType(t).originalDeclaration;
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  TypedefMirror predicateOfNum =
+      (reflectClass(C).declarations[#predicateOfNum] as VariableMirror).type
+          as TypedefMirror;
+  TypedefMirror transformOfString =
+      (reflectClass(C).declarations[#transformOfString] as VariableMirror).type
+          as TypedefMirror;
+  TypedefMirror transformOfR =
+      (reflectClass(C).declarations[#transformOfR] as VariableMirror).type
+          as TypedefMirror;
+  TypedefMirror transformOfDouble = (reflect(new C<double>())
+          .type
+          .declarations[#transformOfR] as VariableMirror)
+      .type as TypedefMirror;
+
+  TypeVariableMirror tFromGenericPredicate =
+      reflectTypeDeclaration(GenericPredicate).typeVariables[0];
+  TypeVariableMirror sFromGenericTransform =
+      reflectTypeDeclaration(GenericTransform).typeVariables[0];
+  TypeVariableMirror rFromC = reflectClass(C).typeVariables[0];
+
+  // Typedefs.
+  typeParameters(reflectTypeDeclaration(NonGenericPredicate), []);
+  typeParameters(reflectTypeDeclaration(GenericPredicate), [#T]);
+  typeParameters(reflectTypeDeclaration(GenericTransform), [#S]);
+  typeParameters(predicateOfNum, [#T]);
+  typeParameters(transformOfString, [#S]);
+  typeParameters(transformOfR, [#S]);
+  typeParameters(transformOfDouble, [#S]);
+
+  typeArguments(reflectTypeDeclaration(NonGenericPredicate), []);
+  typeArguments(reflectTypeDeclaration(GenericPredicate), []);
+  typeArguments(reflectTypeDeclaration(GenericTransform), []);
+  typeArguments(predicateOfNum, [reflectClass(num)]);
+  typeArguments(transformOfString, [reflectClass(String)]);
+  typeArguments(transformOfR, [rFromC]);
+  typeArguments(transformOfDouble, [reflectClass(double)]);
+
+  Expect.isTrue(
+      reflectTypeDeclaration(NonGenericPredicate).isOriginalDeclaration);
+  Expect.isTrue(reflectTypeDeclaration(GenericPredicate).isOriginalDeclaration);
+  Expect.isTrue(reflectTypeDeclaration(GenericTransform).isOriginalDeclaration);
+  Expect.isFalse(predicateOfNum.isOriginalDeclaration);
+  Expect.isFalse(transformOfString.isOriginalDeclaration);
+  Expect.isFalse(transformOfR.isOriginalDeclaration);
+  Expect.isFalse(transformOfDouble.isOriginalDeclaration);
+
+  // Function types.
+  typeParameters(reflectTypeDeclaration(NonGenericPredicate).referent, []);
+  typeParameters(reflectTypeDeclaration(GenericPredicate).referent, []);
+  typeParameters(reflectTypeDeclaration(GenericTransform).referent, []);
+  typeParameters(predicateOfNum.referent, []);
+  typeParameters(transformOfString.referent, []);
+  typeParameters(transformOfR.referent, []);
+  typeParameters(transformOfDouble.referent, []);
+
+  typeArguments(reflectTypeDeclaration(NonGenericPredicate).referent, []);
+  typeArguments(reflectTypeDeclaration(GenericPredicate).referent, []);
+  typeArguments(reflectTypeDeclaration(GenericTransform).referent, []);
+  typeArguments(predicateOfNum.referent, []);
+  typeArguments(transformOfString.referent, []);
+  typeArguments(transformOfR.referent, []);
+  typeArguments(transformOfDouble.referent, []);
+
+  // Function types are always non-generic. Only the typedef is generic.
+  Expect.isTrue(reflectTypeDeclaration(NonGenericPredicate)
+      .referent
+      .isOriginalDeclaration);
+  Expect.isTrue(
+      reflectTypeDeclaration(GenericPredicate).referent.isOriginalDeclaration);
+  Expect.isTrue(
+      reflectTypeDeclaration(GenericTransform).referent.isOriginalDeclaration);
+  Expect.isTrue(predicateOfNum.referent.isOriginalDeclaration);
+  Expect.isTrue(transformOfString.referent.isOriginalDeclaration);
+  Expect.isTrue(transformOfR.referent.isOriginalDeclaration);
+  Expect.isTrue(transformOfDouble.referent.isOriginalDeclaration);
+
+  Expect.equals(reflectClass(num),
+      reflectTypeDeclaration(NonGenericPredicate).referent.parameters[0].type);
+  Expect.equals(tFromGenericPredicate,
+      reflectTypeDeclaration(GenericPredicate).referent.parameters[0].type);
+  Expect.equals(sFromGenericTransform,
+      reflectTypeDeclaration(GenericTransform).referent.parameters[0].type);
+
+  Expect.equals(reflectClass(num), predicateOfNum.referent.parameters[0].type);
+  Expect.equals(
+      reflectClass(String), transformOfString.referent.parameters[0].type);
+  Expect.equals(rFromC, transformOfR.referent.parameters[0].type);
+  Expect.equals(
+      reflectClass(double), transformOfDouble.referent.parameters[0].type);
+
+  Expect.equals(reflectClass(bool),
+      reflectTypeDeclaration(NonGenericPredicate).referent.returnType);
+  Expect.equals(reflectClass(bool),
+      reflectTypeDeclaration(GenericPredicate).referent.returnType);
+  Expect.equals(sFromGenericTransform,
+      reflectTypeDeclaration(GenericTransform).referent.returnType);
+  Expect.equals(reflectClass(bool), predicateOfNum.referent.returnType);
+  Expect.equals(reflectClass(String), transformOfString.referent.returnType);
+  Expect.equals(rFromC, transformOfR.referent.returnType);
+  Expect.equals(reflectClass(double), transformOfDouble.referent.returnType);
+}
diff --git a/tests/lib/mirrors/generic_interface_test.dart b/tests/lib/mirrors/generic_interface_test.dart
new file mode 100644
index 0000000..8b38a3b
--- /dev/null
+++ b/tests/lib/mirrors/generic_interface_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_bounded;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Interface<T> {}
+
+class Bounded<S extends num> {}
+
+class Fixed implements Interface<int> {}
+
+class Generic<R> implements Interface<R> {}
+
+class Bienbounded implements Bounded<int> {}
+
+class Malbounded implements Bounded<String> {} // //# 01: compile-time error
+class FBounded implements Interface<FBounded> {}
+
+class Mixin {}
+
+class FixedMixinApplication = Object with Mixin implements Interface<int>;
+class GenericMixinApplication<X> = Object with Mixin implements Interface<X>;
+
+class FixedClass extends Object with Mixin implements Interface<int> {}
+
+class GenericClass<Y> extends Object with Mixin implements Interface<Y> {}
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  ClassMirror interfaceDecl = reflectClass(Interface);
+  ClassMirror boundedDecl = reflectClass(Bounded);
+
+  ClassMirror interfaceOfInt = reflectClass(Fixed).superinterfaces.single;
+  ClassMirror interfaceOfR = reflectClass(Generic).superinterfaces.single;
+  ClassMirror interfaceOfBool =
+      reflect(new Generic<bool>()).type.superinterfaces.single;
+
+  ClassMirror boundedOfInt = reflectClass(Bienbounded).superinterfaces.single;
+  ClassMirror boundedOfString = reflectClass(Malbounded).superinterfaces.single; // //# 01: continued
+  ClassMirror interfaceOfFBounded =
+      reflectClass(FBounded).superinterfaces.single;
+
+  ClassMirror interfaceOfInt2 =
+      reflectClass(FixedMixinApplication).superinterfaces.single;
+  ClassMirror interfaceOfX =
+      reflectClass(GenericMixinApplication).superinterfaces.single;
+  ClassMirror interfaceOfDouble = reflect(new GenericMixinApplication<double>())
+      .type
+      .superinterfaces
+      .single;
+  ClassMirror interfaceOfInt3 = reflectClass(FixedClass).superinterfaces.single;
+  ClassMirror interfaceOfY = reflectClass(GenericClass).superinterfaces.single;
+  ClassMirror interfaceOfDouble2 =
+      reflect(new GenericClass<double>()).type.superinterfaces.single;
+
+  Expect.isTrue(interfaceDecl.isOriginalDeclaration);
+  Expect.isTrue(boundedDecl.isOriginalDeclaration);
+
+  Expect.isFalse(interfaceOfInt.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfR.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfBool.isOriginalDeclaration);
+  Expect.isFalse(boundedOfInt.isOriginalDeclaration);
+  Expect.isFalse(boundedOfString.isOriginalDeclaration); // //# 01: continued
+  Expect.isFalse(interfaceOfFBounded.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfInt2.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfX.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfDouble.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfInt3.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfY.isOriginalDeclaration);
+  Expect.isFalse(interfaceOfDouble2.isOriginalDeclaration);
+
+  TypeVariableMirror tFromInterface = interfaceDecl.typeVariables.single;
+  TypeVariableMirror sFromBounded = boundedDecl.typeVariables.single;
+  TypeVariableMirror rFromGeneric = reflectClass(Generic).typeVariables.single;
+  TypeVariableMirror xFromGenericMixinApplication =
+      reflectClass(GenericMixinApplication).typeVariables.single;
+  TypeVariableMirror yFromGenericClass =
+      reflectClass(GenericClass).typeVariables.single;
+
+  Expect.equals(reflectClass(Object), tFromInterface.upperBound);
+  Expect.equals(reflectClass(num), sFromBounded.upperBound);
+  Expect.equals(reflectClass(Object), rFromGeneric.upperBound);
+  Expect.equals(reflectClass(Object), xFromGenericMixinApplication.upperBound);
+  Expect.equals(reflectClass(Object), yFromGenericClass.upperBound);
+
+  typeParameters(interfaceDecl, [#T]);
+  typeParameters(boundedDecl, [#S]);
+  typeParameters(interfaceOfInt, [#T]);
+  typeParameters(interfaceOfR, [#T]);
+  typeParameters(interfaceOfBool, [#T]);
+  typeParameters(boundedOfInt, [#S]);
+  typeParameters(boundedOfString, [#S]); // //# 01: continued
+  typeParameters(interfaceOfFBounded, [#T]);
+  typeParameters(interfaceOfInt2, [#T]);
+  typeParameters(interfaceOfX, [#T]);
+  typeParameters(interfaceOfDouble, [#T]);
+  typeParameters(interfaceOfInt3, [#T]);
+  typeParameters(interfaceOfY, [#T]);
+  typeParameters(interfaceOfDouble2, [#T]);
+
+  typeArguments(interfaceDecl, []);
+  typeArguments(boundedDecl, []);
+  typeArguments(interfaceOfInt, [reflectClass(int)]);
+  typeArguments(interfaceOfR, [rFromGeneric]);
+  typeArguments(interfaceOfBool, [reflectClass(bool)]);
+  typeArguments(boundedOfInt, [reflectClass(int)]);
+  typeArguments(boundedOfString, [reflectClass(String)]); // //# 01: continued
+  typeArguments(interfaceOfFBounded, [reflectClass(FBounded)]);
+  typeArguments(interfaceOfInt2, [reflectClass(int)]);
+  typeArguments(interfaceOfX, [xFromGenericMixinApplication]);
+  typeArguments(interfaceOfDouble, [reflectClass(double)]);
+  typeArguments(interfaceOfInt3, [reflectClass(int)]);
+  typeArguments(interfaceOfY, [yFromGenericClass]);
+  typeArguments(interfaceOfDouble2, [reflectClass(double)]);
+}
diff --git a/tests/lib/mirrors/generic_list_test.dart b/tests/lib/mirrors/generic_list_test.dart
new file mode 100644
index 0000000..79d5e94
--- /dev/null
+++ b/tests/lib/mirrors/generic_list_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.superclass;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Foo<T> {
+  List<T> makeList() {
+    if (new DateTime.now().millisecondsSinceEpoch == 42) return [];
+    return new List<T>();
+  }
+}
+
+main() {
+  List<String> list = new Foo<String>().makeList();
+  var cls = reflectClass(list.runtimeType);
+  Expect.isNotNull(cls, 'Failed to reflect on MyClass.');
+}
diff --git a/tests/lib/mirrors/generic_local_function_test.dart b/tests/lib/mirrors/generic_local_function_test.dart
new file mode 100644
index 0000000..bc56f29
--- /dev/null
+++ b/tests/lib/mirrors/generic_local_function_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_function_typedef;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class C<T> {
+  makeClosure1() {
+    T closure1(T t) {}
+    return closure1;
+  }
+
+  makeClosure2() {
+    enclosing() {
+      T closure2(T t) {}
+      return closure2;
+    }
+
+    ;
+    return enclosing();
+  }
+}
+
+main() {
+  ClosureMirror closure1 =
+      reflect(new C<String>().makeClosure1()) as ClosureMirror;
+  Expect.equals(reflectClass(String), closure1.function.returnType);
+  Expect.equals(reflectClass(String), closure1.function.parameters[0].type);
+
+  ClosureMirror closure2 =
+      reflect(new C<String>().makeClosure2()) as ClosureMirror;
+  Expect.equals(reflectClass(String), closure2.function.returnType);
+  Expect.equals(reflectClass(String), closure2.function.parameters[0].type);
+}
diff --git a/tests/lib/mirrors/generic_method_test.dart b/tests/lib/mirrors/generic_method_test.dart
new file mode 100644
index 0000000..8189ea6
--- /dev/null
+++ b/tests/lib/mirrors/generic_method_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Foo {
+  T bar<T>() => throw "does-not-return";
+}
+
+void main() {
+  var type = reflectClass(Foo);
+  Expect.isTrue(type.declarations.keys.contains(#bar));
+}
diff --git a/tests/lib/mirrors/generic_mixin_applications_test.dart b/tests/lib/mirrors/generic_mixin_applications_test.dart
new file mode 100644
index 0000000..0880347
--- /dev/null
+++ b/tests/lib/mirrors/generic_mixin_applications_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_mixin_applications;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Super<S> {}
+
+class Mixin<M> {}
+
+class Nixim<N> {}
+
+class NonGenericMixinApplication1 = Super with Mixin;
+class NonGenericMixinApplication2 = Super<num> with Mixin<String>;
+
+class GenericMixinApplication1<MA> = Super<MA> with Mixin<MA>;
+class GenericMixinApplication2<MA> = Super<num> with Mixin<String>;
+
+class NonGenericClass1 extends Super with Mixin {}
+
+class NonGenericClass2 extends Super<num> with Mixin<String> {}
+
+class GenericClass1<C> extends Super<C> with Mixin<C> {}
+
+class GenericClass2<C> extends Super<num> with Mixin<String> {}
+
+class GenericMultipleMixins<A, B, C> extends Super<A> with Mixin<B>, Nixim<C> {}
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  // Declarations.
+  typeParameters(reflectClass(NonGenericMixinApplication1), []);
+  typeParameters(reflectClass(NonGenericMixinApplication2), []);
+  typeParameters(reflectClass(GenericMixinApplication1), [#MA]);
+  typeParameters(reflectClass(GenericMixinApplication2), [#MA]);
+  typeParameters(reflectClass(NonGenericClass1), []);
+  typeParameters(reflectClass(NonGenericClass2), []);
+  typeParameters(reflectClass(GenericClass1), [#C]);
+  typeParameters(reflectClass(GenericClass2), [#C]);
+  typeParameters(reflectClass(GenericMultipleMixins), [#A, #B, #C]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeParameters(reflectClass(NonGenericClass1).superclass, []);
+  typeParameters(reflectClass(NonGenericClass2).superclass, []);
+  typeParameters(reflectClass(GenericClass1).superclass, []);
+  typeParameters(reflectClass(GenericClass2).superclass, []);
+
+  typeArguments(reflectClass(NonGenericMixinApplication1), []);
+  typeArguments(reflectClass(NonGenericMixinApplication2), []);
+  typeArguments(reflectClass(GenericMixinApplication1), []);
+  typeArguments(reflectClass(GenericMixinApplication2), []);
+  typeArguments(reflectClass(NonGenericClass1), []);
+  typeArguments(reflectClass(NonGenericClass2), []);
+  typeArguments(reflectClass(GenericClass1), []);
+  typeArguments(reflectClass(GenericClass2), []);
+  typeArguments(reflectClass(GenericMultipleMixins), []);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeArguments(
+      reflectClass(NonGenericClass1).superclass!.originalDeclaration, []);
+  typeArguments(
+      reflectClass(NonGenericClass2).superclass!.originalDeclaration, []);
+  typeArguments(
+      reflectClass(GenericClass1).superclass!.originalDeclaration, []);
+  typeArguments(
+      reflectClass(GenericClass2).superclass!.originalDeclaration, []);
+
+  // Instantiations.
+  typeParameters(reflect(new NonGenericMixinApplication1()).type, []);
+  typeParameters(reflect(new NonGenericMixinApplication2()).type, []);
+  typeParameters(reflect(new GenericMixinApplication1<bool>()).type, [#MA]);
+  typeParameters(reflect(new GenericMixinApplication2<bool>()).type, [#MA]);
+  typeParameters(reflect(new NonGenericClass1()).type, []);
+  typeParameters(reflect(new NonGenericClass2()).type, []);
+  typeParameters(reflect(new GenericClass1<bool>()).type, [#C]);
+  typeParameters(reflect(new GenericClass2<bool>()).type, [#C]);
+  typeParameters(reflect(new GenericMultipleMixins<bool, String, int>()).type,
+      [#A, #B, #C]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeParameters(reflect(new NonGenericClass1()).type.superclass!, []);
+  typeParameters(reflect(new NonGenericClass2()).type.superclass!, []);
+  typeParameters(reflect(new GenericClass1<bool>()).type.superclass!, []);
+  typeParameters(reflect(new GenericClass2<bool>()).type.superclass!, []);
+
+  typeArguments(reflect(new NonGenericMixinApplication1()).type, []);
+  typeArguments(reflect(new NonGenericMixinApplication2()).type, []);
+  typeArguments(
+      reflect(new GenericMixinApplication1<bool>()).type, [reflectClass(bool)]);
+  typeArguments(
+      reflect(new GenericMixinApplication2<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new NonGenericClass1()).type, []);
+  typeArguments(reflect(new NonGenericClass2()).type, []);
+  typeArguments(reflect(new GenericClass1<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new GenericClass2<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new GenericMultipleMixins<bool, String, int>()).type,
+      [reflectClass(bool), reflectClass(String), reflectClass(int)]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeArguments(reflect(new NonGenericClass1()).type.superclass!, []);
+  typeArguments(reflect(new NonGenericClass2()).type.superclass!, []);
+  typeArguments(reflect(new GenericClass1<bool>()).type.superclass!, []);
+  typeArguments(reflect(new GenericClass2<bool>()).type.superclass!, []);
+}
diff --git a/tests/lib/mirrors/generic_mixin_test.dart b/tests/lib/mirrors/generic_mixin_test.dart
new file mode 100644
index 0000000..238689b
--- /dev/null
+++ b/tests/lib/mirrors/generic_mixin_test.dart
@@ -0,0 +1,183 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generic_mixin;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class Super<S> {}
+
+class Mixin<M> {}
+
+class Nixim<N> {}
+
+class NonGenericMixinApplication1 = Super with Mixin;
+class NonGenericMixinApplication2 = Super<num> with Mixin<String>;
+
+class GenericMixinApplication1<MA> = Super<MA> with Mixin<MA>;
+class GenericMixinApplication2<MA> = Super<num> with Mixin<String>;
+
+class NonGenericClass1 extends Super with Mixin {}
+
+class NonGenericClass2 extends Super<num> with Mixin<String> {}
+
+class GenericClass1<C> extends Super<C> with Mixin<C> {}
+
+class GenericClass2<C> extends Super<num> with Mixin<String> {}
+
+class GenericMultipleMixins<A, B, C> extends Super<A> with Mixin<B>, Nixim<C> {}
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  typeParameters(reflectClass(NonGenericMixinApplication1).mixin, [#M]);
+  typeParameters(reflectClass(NonGenericMixinApplication2).mixin, [#M]);
+  typeParameters(reflectClass(GenericMixinApplication1).mixin, [#M]);
+  typeParameters(reflectClass(GenericMixinApplication2).mixin, [#M]);
+  typeParameters(reflectClass(NonGenericClass1).mixin, []);
+  typeParameters(reflectClass(NonGenericClass2).mixin, []);
+  typeParameters(reflectClass(GenericClass1).mixin, [#C]);
+  typeParameters(reflectClass(GenericClass2).mixin, [#C]);
+  typeParameters(reflectClass(NonGenericClass1).superclass!.mixin, [#M]);
+  typeParameters(reflectClass(NonGenericClass2).superclass!.mixin, [#M]);
+  typeParameters(reflectClass(GenericClass1).superclass!.mixin, [#M]);
+  typeParameters(reflectClass(GenericClass2).superclass!.mixin, [#M]);
+  typeParameters(reflectClass(GenericMultipleMixins).mixin, [#A, #B, #C]);
+  typeParameters(reflectClass(GenericMultipleMixins).superclass!.mixin, [#N]);
+  typeParameters(
+      reflectClass(GenericMultipleMixins).superclass!.superclass!.mixin, [#M]);
+  typeParameters(
+      reflectClass(GenericMultipleMixins)
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin,
+      [#S]);
+
+  typeArguments(
+      reflectClass(NonGenericMixinApplication1).mixin, [dynamicMirror]);
+  typeArguments(
+      reflectClass(NonGenericMixinApplication2).mixin, [reflectClass(String)]);
+  typeArguments(reflectClass(GenericMixinApplication1).mixin,
+      [reflectClass(GenericMixinApplication1).typeVariables.single]);
+  typeArguments(
+      reflectClass(GenericMixinApplication2).mixin, [reflectClass(String)]);
+  typeArguments(reflectClass(NonGenericClass1).mixin, []);
+  typeArguments(reflectClass(NonGenericClass2).mixin, []);
+  typeArguments(reflectClass(GenericClass1).mixin, []);
+  typeArguments(reflectClass(GenericClass2).mixin, []);
+  typeArguments(
+      reflectClass(NonGenericClass1).superclass!.mixin, [dynamicMirror]);
+  typeArguments(
+      reflectClass(NonGenericClass2).superclass!.mixin, [reflectClass(String)]);
+  typeArguments(reflectClass(GenericClass1).superclass!.mixin,
+      [reflectClass(GenericClass1).typeVariables.single]);
+  typeArguments(
+      reflectClass(GenericClass2).superclass!.mixin, [reflectClass(String)]);
+  typeArguments(reflectClass(GenericMultipleMixins).mixin, []);
+  typeArguments(reflectClass(GenericMultipleMixins).superclass!.mixin,
+      [reflectClass(GenericMultipleMixins).typeVariables[2]]);
+  typeArguments(
+      reflectClass(GenericMultipleMixins).superclass!.superclass!.mixin,
+      [reflectClass(GenericMultipleMixins).typeVariables[1]]);
+  typeArguments(
+      reflectClass(GenericMultipleMixins)
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin,
+      [reflectClass(GenericMultipleMixins).typeVariables[0]]);
+
+  typeParameters(reflect(new NonGenericMixinApplication1()).type.mixin, [#M]);
+  typeParameters(reflect(new NonGenericMixinApplication2()).type.mixin, [#M]);
+  typeParameters(
+      reflect(new GenericMixinApplication1<bool>()).type.mixin, [#M]);
+  typeParameters(
+      reflect(new GenericMixinApplication2<bool>()).type.mixin, [#M]);
+  typeParameters(reflect(new NonGenericClass1()).type.mixin, []);
+  typeParameters(reflect(new NonGenericClass2()).type.mixin, []);
+  typeParameters(reflect(new GenericClass1<bool>()).type.mixin, [#C]);
+  typeParameters(reflect(new GenericClass2<bool>()).type.mixin, [#C]);
+  typeParameters(reflect(new NonGenericClass1()).type.superclass!.mixin, [#M]);
+  typeParameters(reflect(new NonGenericClass2()).type.superclass!.mixin, [#M]);
+  typeParameters(
+      reflect(new GenericClass1<bool>()).type.superclass!.mixin, [#M]);
+  typeParameters(
+      reflect(new GenericClass2<bool>()).type.superclass!.mixin, [#M]);
+  typeParameters(
+      reflect(new GenericMultipleMixins<bool, String, int>()).type.mixin,
+      [#A, #B, #C]);
+  typeParameters(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .mixin,
+      [#N]);
+  typeParameters(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .superclass!
+          .mixin,
+      [#M]);
+  typeParameters(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin,
+      [#S]);
+
+  typeArguments(
+      reflect(new NonGenericMixinApplication1()).type.mixin, [dynamicMirror]);
+  typeArguments(reflect(new NonGenericMixinApplication2()).type.mixin,
+      [reflectClass(String)]);
+  typeArguments(reflect(new GenericMixinApplication1<bool>()).type.mixin,
+      [reflectClass(bool)]);
+  typeArguments(reflect(new GenericMixinApplication2<bool>()).type.mixin,
+      [reflectClass(String)]);
+  typeArguments(reflect(new NonGenericClass1()).type.mixin, []);
+  typeArguments(reflect(new NonGenericClass2()).type.mixin, []);
+  typeArguments(
+      reflect(new GenericClass1<bool>()).type.mixin, [reflectClass(bool)]);
+  typeArguments(
+      reflect(new GenericClass2<bool>()).type.mixin, [reflectClass(bool)]);
+  typeArguments(
+      reflect(new NonGenericClass1()).type.superclass!.mixin, [dynamicMirror]);
+  typeArguments(reflect(new NonGenericClass2()).type.superclass!.mixin,
+      [reflectClass(String)]);
+  typeArguments(reflect(new GenericClass1<bool>()).type.superclass!.mixin,
+      [reflectClass(bool)]);
+  typeArguments(reflect(new GenericClass2<bool>()).type.superclass!.mixin,
+      [reflectClass(String)]);
+  typeArguments(
+      reflect(new GenericMultipleMixins<bool, String, int>()).type.mixin,
+      [reflectClass(bool), reflectClass(String), reflectClass(int)]);
+  typeArguments(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .mixin,
+      [reflectClass(int)]);
+  typeArguments(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .superclass!
+          .mixin,
+      [reflectClass(String)]);
+  typeArguments(
+      reflect(new GenericMultipleMixins<bool, String, int>())
+          .type
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin,
+      [reflectClass(bool)]);
+}
diff --git a/tests/lib/mirrors/generic_superclass_test.dart b/tests/lib/mirrors/generic_superclass_test.dart
new file mode 100644
index 0000000..a711523
--- /dev/null
+++ b/tests/lib/mirrors/generic_superclass_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'dart:mirrors';
+
+class A<T> {}
+
+class B extends A<U> {}
+
+class C extends A<C> {}
+
+class D<T> extends A<T> {}
+
+class E<X, Y> extends G<H<Y>> {}
+
+class F<X> implements A<X> {}
+
+class FF<X, Y> implements G<H<Y>> {}
+
+class G<T> {}
+
+class H<T> {}
+
+class U {}
+
+class R {}
+
+void testOriginals() {
+  ClassMirror a = reflectClass(A);
+  ClassMirror b = reflectClass(B);
+  ClassMirror c = reflectClass(C);
+  ClassMirror d = reflectClass(D);
+  ClassMirror e = reflectClass(E);
+  ClassMirror f = reflectClass(F);
+  ClassMirror ff = reflectClass(FF);
+  ClassMirror superA = a.superclass!;
+  ClassMirror superB = b.superclass!;
+  ClassMirror superC = c.superclass!;
+  ClassMirror superD = d.superclass!;
+  ClassMirror superE = e.superclass!;
+  ClassMirror superInterfaceF = f.superinterfaces[0];
+  ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+  TypeVariableMirror aT = a.typeVariables[0];
+  TypeVariableMirror dT = d.typeVariables[0];
+  TypeVariableMirror eX = e.typeVariables[0];
+  TypeVariableMirror eY = e.typeVariables[1];
+  TypeVariableMirror fX = f.typeVariables[0];
+  TypeVariableMirror feX = ff.typeVariables[0];
+  TypeVariableMirror feY = ff.typeVariables[1];
+
+  Expect.isTrue(superA.isOriginalDeclaration);
+  Expect.isFalse(superB.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(superD.isOriginalDeclaration);
+  Expect.isFalse(superE.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+  Expect.equals(reflectClass(Object), superA);
+  Expect.equals(reflect(new A<U>()).type, superB);
+  Expect.equals(reflect(new A<C>()).type, superC); //# 01: ok
+  Expect.equals(reflect(new U()).type, superB.typeArguments[0]);
+  Expect.equals(reflect(new C()).type, superC.typeArguments[0]); //# 01: ok
+  Expect.equals(dT, superD.typeArguments[0]);
+  Expect.equals(eY, superE.typeArguments[0].typeArguments[0]);
+  Expect.equals(feY, superInterfaceFF.typeArguments[0].typeArguments[0]);
+  Expect.equals(fX, superInterfaceF.typeArguments[0]);
+}
+
+void testInstances() {
+  ClassMirror a = reflect(new A<U>()).type;
+  ClassMirror b = reflect(new B()).type;
+  ClassMirror c = reflect(new C()).type;
+  ClassMirror d = reflect(new D<U>()).type;
+  ClassMirror e = reflect(new E<U, R>()).type;
+  ClassMirror e0 = reflect(new E<U, H<R>>()).type;
+  ClassMirror ff = reflect(new FF<U, R>()).type;
+  ClassMirror f = reflect(new F<U>()).type;
+  ClassMirror u = reflect(new U()).type;
+  ClassMirror r = reflect(new R()).type;
+  ClassMirror hr = reflect(new H<R>()).type;
+
+  ClassMirror superA = a.superclass!;
+  ClassMirror superB = b.superclass!;
+  ClassMirror superC = c.superclass!;
+  ClassMirror superD = d.superclass!;
+  ClassMirror superE = e.superclass!;
+  ClassMirror superE0 = e0.superclass!;
+  ClassMirror superInterfaceF = f.superinterfaces[0];
+  ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+  Expect.isTrue(superA.isOriginalDeclaration);
+  Expect.isFalse(superB.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(superD.isOriginalDeclaration);
+  Expect.isFalse(superE.isOriginalDeclaration);
+  Expect.isFalse(superE0.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+  Expect.equals(reflectClass(Object), superA);
+  Expect.equals(reflect(new A<U>()).type, superB);
+  Expect.equals(reflect(new A<C>()).type, superC); //# 01: ok
+  Expect.equals(reflect(new A<U>()).type, superD);
+  Expect.equals(reflect(new G<H<R>>()).type, superE);
+  Expect.equals(reflect(new G<H<H<R>>>()).type, superE0);
+  Expect.equals(reflect(new G<H<R>>()).type, superInterfaceFF);
+  Expect.equals(u, superB.typeArguments[0]);
+  Expect.equals(reflect(new C()).type, superC.typeArguments[0]); //# 01: ok
+  Expect.equals(u, superD.typeArguments[0]);
+  Expect.equals(r, superE.typeArguments[0].typeArguments[0]);
+  Expect.equals(hr, superE0.typeArguments[0].typeArguments[0]);
+  Expect.equals(r, superInterfaceFF.typeArguments[0].typeArguments[0]);
+  Expect.equals(u, superInterfaceF.typeArguments[0]);
+}
+
+void testObject() {
+  ClassMirror object = reflectClass(Object);
+  Expect.equals(null, object.superclass);
+}
+
+main() {
+  testOriginals();
+  testInstances();
+  testObject();
+}
diff --git a/tests/lib/mirrors/generic_type_mirror_test.dart b/tests/lib/mirrors/generic_type_mirror_test.dart
new file mode 100644
index 0000000..b36ef114
--- /dev/null
+++ b/tests/lib/mirrors/generic_type_mirror_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class Foo<W, V> {
+  late V field;
+  V get bar => field;
+  set bar(V v) {}
+  W m() {
+    throw "does-not-return";
+  }
+
+  V n() {
+    throw "does-not-return";
+  }
+
+  H<V> p() {
+    throw "does-not-return";
+  }
+
+  o(W w) {}
+}
+
+class H<T> {}
+
+class Bar {}
+
+class Baz {}
+
+void testInstance() {
+  ClassMirror foo = reflect((new Foo<Bar, Baz>())).type;
+  ClassMirror bar = reflect(new Bar()).type;
+  ClassMirror baz = reflect(new Baz()).type;
+  ClassMirror hOfBaz = reflect(new H<Baz>()).type;
+  VariableMirror field = foo.declarations[#field] as VariableMirror;
+  MethodMirror getter = foo.declarations[#bar] as MethodMirror;
+  MethodMirror setter = foo.declarations[const Symbol('bar=')] as MethodMirror;
+  MethodMirror m = foo.declarations[#m] as MethodMirror;
+  MethodMirror n = foo.declarations[#n] as MethodMirror;
+  MethodMirror o = foo.declarations[#o] as MethodMirror;
+  MethodMirror p = foo.declarations[#p] as MethodMirror;
+
+  Expect.equals(foo, field.owner);
+  Expect.equals(foo, getter.owner);
+  Expect.equals(foo, setter.owner);
+  Expect.equals(foo, m.owner);
+  Expect.equals(foo, n.owner);
+  Expect.equals(foo, o.owner);
+  Expect.equals(foo, p.owner);
+
+  Expect.equals(baz, field.type);
+  Expect.equals(baz, getter.returnType);
+  Expect.equals(bar, m.returnType);
+  Expect.equals(baz, n.returnType);
+  Expect.equals(bar, o.parameters.single.type);
+  Expect.equals(hOfBaz, p.returnType);
+  Expect.equals(1, p.returnType.typeArguments.length);
+  Expect.equals(baz, p.returnType.typeArguments[0]);
+
+  Expect.equals(baz, setter.parameters.single.type);
+}
+
+void testOriginalDeclaration() {
+  ClassMirror foo = reflectClass(Foo);
+
+  VariableMirror field = foo.declarations[#field] as VariableMirror;
+  MethodMirror getter = foo.declarations[#bar] as MethodMirror;
+  MethodMirror setter = foo.declarations[const Symbol('bar=')] as MethodMirror;
+  MethodMirror m = foo.declarations[#m] as MethodMirror;
+  MethodMirror n = foo.declarations[#n] as MethodMirror;
+  MethodMirror o = foo.declarations[#o] as MethodMirror;
+  MethodMirror p = foo.declarations[#p] as MethodMirror;
+  TypeVariableMirror w = foo.typeVariables[0] as TypeVariableMirror;
+  TypeVariableMirror v = foo.typeVariables[1] as TypeVariableMirror;
+
+  Expect.equals(foo, field.owner);
+  Expect.equals(foo, getter.owner);
+  Expect.equals(foo, setter.owner);
+  Expect.equals(foo, m.owner);
+  Expect.equals(foo, n.owner);
+  Expect.equals(foo, o.owner);
+  Expect.equals(foo, p.owner);
+
+  Expect.equals(v, field.type);
+  Expect.equals(v, getter.returnType);
+  Expect.equals(w, m.returnType);
+  Expect.equals(v, n.returnType);
+  Expect.equals(w, o.parameters.single.type);
+  Expect.equals(1, p.returnType.typeArguments.length);
+  Expect.equals(v, p.returnType.typeArguments[0]);
+
+  Expect.equals(v, setter.parameters.single.type);
+}
+
+main() {
+  testInstance();
+  testOriginalDeclaration();
+}
diff --git a/tests/lib/mirrors/generics_double_substitution_test.dart b/tests/lib/mirrors/generics_double_substitution_test.dart
new file mode 100644
index 0000000..4a9dcc8
--- /dev/null
+++ b/tests/lib/mirrors/generics_double_substitution_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generics_double_substitution;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A<R> {}
+
+class B<S> {}
+
+class C<T> extends B<A<T>> {
+  late A<T> field;
+  A<T> returnType() => new A<T>();
+  parameterType(A<T> param) {}
+}
+
+main() {
+  ClassMirror cOfString = reflect(new C<String>()).type;
+  ClassMirror aOfString = reflect(new A<String>()).type;
+
+  VariableMirror field = cOfString.declarations[#field] as VariableMirror;
+  Expect.equals(aOfString, field.type);
+
+  MethodMirror returnType = cOfString.declarations[#returnType] as MethodMirror;
+  Expect.equals(aOfString, returnType.returnType);
+
+  MethodMirror parameterType = cOfString.declarations[#parameterType] as MethodMirror;
+  Expect.equals(aOfString, parameterType.parameters.single.type);
+
+  ClassMirror typeArgOfSuperclass = cOfString.superclass!.typeArguments.single as ClassMirror;
+  Expect.equals(aOfString, typeArgOfSuperclass); //# 01: ok
+}
diff --git a/tests/lib/mirrors/generics_dynamic_test.dart b/tests/lib/mirrors/generics_dynamic_test.dart
new file mode 100644
index 0000000..8a583da
--- /dev/null
+++ b/tests/lib/mirrors/generics_dynamic_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class B<T extends A> extends A implements C {
+  A m(A a) {}
+  late A field;
+}
+
+class C<S, T> {}
+
+class D extends A<int> {}
+
+main() {
+  ClassMirror aDecl = reflectClass(A);
+  ClassMirror bDecl = reflectClass(B);
+  ClassMirror cDecl = reflectClass(C);
+  TypeMirror aInstance = reflect(new A()).type;
+  TypeMirror aInstanceDynamic = reflect(new A<dynamic>()).type;
+  TypeMirror dInstance = reflect(new D()).type;
+  TypeMirror cInstance = reflect(new C<dynamic, dynamic>()).type;
+  TypeMirror cNestedInstance = reflect(new C<C, dynamic>()).type;
+  TypeMirror cTypeArgument = cNestedInstance.typeArguments.first;
+  TypeMirror superA = bDecl.superclass!;
+  TypeMirror superC = bDecl.superinterfaces.single;
+  MethodMirror m = bDecl.declarations[#m] as MethodMirror;
+  VariableMirror field = bDecl.declarations[#field] as VariableMirror;
+  TypeMirror returnTypeA = m.returnType;
+  TypeMirror parameterTypeA = m.parameters.first.type;
+  TypeMirror fieldTypeA = field.type;
+  TypeMirror upperBoundA = bDecl.typeVariables.single.upperBound;
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  Expect.isTrue(aDecl.isOriginalDeclaration);
+  Expect.isTrue(reflect(dInstance).type.isOriginalDeclaration);
+  Expect.isFalse(aInstance.isOriginalDeclaration);
+  Expect.isFalse(aInstanceDynamic.isOriginalDeclaration);
+  Expect.isFalse(superA.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(returnTypeA.isOriginalDeclaration);
+  Expect.isFalse(parameterTypeA.isOriginalDeclaration);
+  Expect.isFalse(fieldTypeA.isOriginalDeclaration);
+  Expect.isFalse(upperBoundA.isOriginalDeclaration);
+  Expect.isFalse(cInstance.isOriginalDeclaration);
+  Expect.isFalse(cNestedInstance.isOriginalDeclaration);
+  Expect.isFalse(cTypeArgument.isOriginalDeclaration);
+
+  Expect.isTrue(aDecl.typeArguments.isEmpty);
+  Expect.isTrue(dInstance.typeArguments.isEmpty);
+  Expect.equals(dynamicMirror, aInstance.typeArguments.single);
+  Expect.equals(dynamicMirror, aInstanceDynamic.typeArguments.single);
+  Expect.equals(dynamicMirror, superA.typeArguments.single);
+  Expect.equals(dynamicMirror, superC.typeArguments.first);
+  Expect.equals(dynamicMirror, superC.typeArguments.last);
+  Expect.equals(dynamicMirror, returnTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, parameterTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, fieldTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, upperBoundA.typeArguments.single);
+  Expect.equals(dynamicMirror, cInstance.typeArguments.first);
+  Expect.equals(dynamicMirror, cInstance.typeArguments.last);
+  Expect.equals(dynamicMirror, cNestedInstance.typeArguments.last);
+  Expect.equals(dynamicMirror, cTypeArgument.typeArguments.first);
+  Expect.equals(dynamicMirror, cTypeArgument.typeArguments.last);
+}
diff --git a/tests/lib/mirrors/generics_helper.dart b/tests/lib/mirrors/generics_helper.dart
new file mode 100644
index 0000000..da10962
--- /dev/null
+++ b/tests/lib/mirrors/generics_helper.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library generics_helper;
+
+import 'package:expect/expect.dart';
+
+typeParameters(mirror, parameterNames) {
+  Expect.listEquals(
+      parameterNames, mirror.typeVariables.map((v) => v.simpleName).toList());
+}
+
+typeArguments(mirror, argumentMirrors) {
+  Expect.listEquals(argumentMirrors, mirror.typeArguments);
+}
diff --git a/tests/lib/mirrors/generics_special_types_test.dart b/tests/lib/mirrors/generics_special_types_test.dart
new file mode 100644
index 0000000..49f72ec
--- /dev/null
+++ b/tests/lib/mirrors/generics_special_types_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generics_special_types;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+  Expect.isTrue(dynamicMirror.isOriginalDeclaration);
+  Expect.equals(dynamicMirror, dynamicMirror.originalDeclaration);
+  Expect.listEquals([], dynamicMirror.typeVariables);
+  Expect.listEquals([], dynamicMirror.typeArguments);
+
+  TypeMirror voidMirror = currentMirrorSystem().voidType;
+  Expect.isTrue(voidMirror.isOriginalDeclaration);
+  Expect.equals(voidMirror, voidMirror.originalDeclaration);
+  Expect.listEquals([], voidMirror.typeVariables);
+  Expect.listEquals([], voidMirror.typeArguments);
+
+  TypeMirror dynamicMirror2 = reflectType(dynamic);
+  Expect.equals(dynamicMirror, dynamicMirror2);
+  Expect.isTrue(dynamicMirror2.isOriginalDeclaration);
+  Expect.equals(dynamicMirror2, dynamicMirror2.originalDeclaration);
+  Expect.listEquals([], dynamicMirror2.typeVariables);
+  Expect.listEquals([], dynamicMirror2.typeArguments);
+}
diff --git a/tests/lib/mirrors/generics_substitution_test.dart b/tests/lib/mirrors/generics_substitution_test.dart
new file mode 100644
index 0000000..9c2c0ae
--- /dev/null
+++ b/tests/lib/mirrors/generics_substitution_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.generics_substitution;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class SuperGeneric<R, S> {
+  late R r;
+  s(S s) {}
+}
+
+class Generic<T> extends SuperGeneric<T, int> {
+  T t() => throw "does-not-return"; //
+}
+
+main() {
+  ClassMirror genericDecl = reflectClass(Generic);
+  ClassMirror genericOfString = reflect(new Generic<String>()).type;
+  ClassMirror superGenericDecl = reflectClass(SuperGeneric);
+  ClassMirror superOfTAndInt = genericDecl.superclass!;
+  ClassMirror superOfStringAndInt = genericOfString.superclass!;
+
+  Expect.isTrue(genericDecl.isOriginalDeclaration);
+  Expect.isFalse(genericOfString.isOriginalDeclaration);
+  Expect.isTrue(superGenericDecl.isOriginalDeclaration);
+  Expect.isFalse(superOfTAndInt.isOriginalDeclaration);
+  Expect.isFalse(superOfStringAndInt.isOriginalDeclaration);
+
+  Symbol r(ClassMirror cm) =>
+      (cm.declarations[#r] as VariableMirror).type.simpleName;
+  Symbol s(ClassMirror cm) =>
+      (cm.declarations[#s] as MethodMirror).parameters[0].type.simpleName;
+  Symbol t(ClassMirror cm) =>
+      (cm.declarations[#t] as MethodMirror).returnType.simpleName;
+
+  Expect.equals(#T, r(genericDecl.superclass!));
+  Expect.equals(#int, s(genericDecl.superclass!));
+  Expect.equals(#T, t(genericDecl));
+
+  Expect.equals(#String, r(genericOfString.superclass!));
+  Expect.equals(#int, s(genericOfString.superclass!));
+  Expect.equals(#String, t(genericOfString));
+
+  Expect.equals(#R, r(superGenericDecl));
+  Expect.equals(#S, s(superGenericDecl));
+
+  Expect.equals(#T, r(superOfTAndInt));
+  Expect.equals(#int, s(superOfTAndInt));
+
+  Expect.equals(#String, r(superOfStringAndInt));
+  Expect.equals(#int, s(superOfStringAndInt));
+}
diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart
new file mode 100644
index 0000000..fface13
--- /dev/null
+++ b/tests/lib/mirrors/generics_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.type_arguments_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+import 'generics_helper.dart';
+
+class A<T> {}
+
+class Z<T> {}
+
+class B extends A {}
+
+class C
+    extends A<num, int> //# 01: compile-time error
+{}
+
+class D extends A<int> {}
+
+class E<S> extends A<S> {}
+
+class F<R> extends A<int> {}
+
+class G {}
+
+class H<A, B, C> {}
+
+class I extends G {}
+
+main() {
+  // Declarations.
+  typeParameters(reflectClass(A), [#T]);
+  typeParameters(reflectClass(G), []);
+  typeParameters(reflectClass(B), []);
+  typeParameters(reflectClass(C), []);
+  typeParameters(reflectClass(D), []);
+  typeParameters(reflectClass(E), [#S]);
+  typeParameters(reflectClass(F), [#R]);
+  typeParameters(reflectClass(G), []);
+  typeParameters(reflectClass(H), [#A, #B, #C]);
+  typeParameters(reflectClass(I), []);
+
+  typeArguments(reflectClass(A), []);
+  typeArguments(reflectClass(B), []);
+  typeArguments(reflectClass(C), []);
+  typeArguments(reflectClass(D), []);
+  typeArguments(reflectClass(E), []);
+  typeArguments(reflectClass(F), []);
+  typeArguments(reflectClass(G), []);
+  typeArguments(reflectClass(H), []);
+  typeArguments(reflectClass(I), []);
+
+  Expect.isTrue(reflectClass(A).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(B).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(C).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(D).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(E).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(F).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(G).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(H).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(I).isOriginalDeclaration);
+
+  Expect.equals(reflectClass(A), reflectClass(A).originalDeclaration);
+  Expect.equals(reflectClass(B), reflectClass(B).originalDeclaration);
+  Expect.equals(reflectClass(C), reflectClass(C).originalDeclaration);
+  Expect.equals(reflectClass(D), reflectClass(D).originalDeclaration);
+  Expect.equals(reflectClass(E), reflectClass(E).originalDeclaration);
+  Expect.equals(reflectClass(F), reflectClass(F).originalDeclaration);
+  Expect.equals(reflectClass(G), reflectClass(G).originalDeclaration);
+  Expect.equals(reflectClass(H), reflectClass(H).originalDeclaration);
+  Expect.equals(reflectClass(I), reflectClass(I).originalDeclaration);
+
+  // Instantiations.
+  typeParameters(reflect(new A<num>()).type, [#T]);
+  typeParameters(reflect(new B()).type, []);
+  typeParameters(reflect(new C()).type, []);
+  typeParameters(reflect(new D()).type, []);
+  typeParameters(reflect(new E()).type, [#S]);
+  typeParameters(reflect(new F<num>()).type, [#R]);
+  typeParameters(reflect(new G()).type, []);
+  typeParameters(reflect(new H()).type, [#A, #B, #C]);
+  typeParameters(reflect(new I()).type, []);
+
+  var numMirror = reflectClass(num);
+  var dynamicMirror = currentMirrorSystem().dynamicType;
+  typeArguments(reflect(new A<num>()).type, [numMirror]);
+  typeArguments(reflect(new A<dynamic>()).type, [dynamicMirror]);
+  typeArguments(reflect(new A()).type, [dynamicMirror]);
+  typeArguments(reflect(new B()).type, []);
+  typeArguments(reflect(new C()).type, []);
+  typeArguments(reflect(new D()).type, []);
+  typeArguments(reflect(new E<num>()).type, [numMirror]);
+  typeArguments(reflect(new E<dynamic>()).type, [dynamicMirror]);
+  typeArguments(reflect(new E()).type, [dynamicMirror]);
+  typeArguments(reflect(new F<num>()).type, [numMirror]);
+  typeArguments(reflect(new F<dynamic>()).type, [dynamicMirror]);
+  typeArguments(reflect(new F()).type, [dynamicMirror]);
+  typeArguments(reflect(new G()).type, []);
+  typeArguments(reflect(new H<dynamic, num, dynamic>()).type,
+      [dynamicMirror, numMirror, dynamicMirror]);
+  typeArguments(reflect(new I()).type, []);
+
+  Expect.isFalse(reflect(new A<num>()).type.isOriginalDeclaration);
+  Expect.isTrue(reflect(new B()).type.isOriginalDeclaration);
+  Expect.isTrue(reflect(new C()).type.isOriginalDeclaration);
+  Expect.isTrue(reflect(new D()).type.isOriginalDeclaration);
+  Expect.isFalse(reflect(new E<num>()).type.isOriginalDeclaration);
+  Expect.isFalse(reflect(new F<num>()).type.isOriginalDeclaration);
+  Expect.isTrue(reflect(new G()).type.isOriginalDeclaration);
+  Expect.isFalse(reflect(new H()).type.isOriginalDeclaration);
+  Expect.isTrue(reflect(new I()).type.isOriginalDeclaration);
+
+  Expect.equals(
+      reflectClass(A), reflect(new A<num>()).type.originalDeclaration);
+  Expect.equals(reflectClass(B), reflect(new B()).type.originalDeclaration);
+  Expect.equals(reflectClass(C), reflect(new C()).type.originalDeclaration);
+  Expect.equals(reflectClass(D), reflect(new D()).type.originalDeclaration);
+  Expect.equals(
+      reflectClass(E), reflect(new E<num>()).type.originalDeclaration);
+  Expect.equals(
+      reflectClass(F), reflect(new F<num>()).type.originalDeclaration);
+  Expect.equals(reflectClass(G), reflect(new G()).type.originalDeclaration);
+  Expect.equals(reflectClass(H), reflect(new H()).type.originalDeclaration);
+  Expect.equals(reflectClass(I), reflect(new I()).type.originalDeclaration);
+
+  Expect.notEquals(reflect(new A<num>()).type,
+      reflect(new A<num>()).type.originalDeclaration);
+  Expect.equals(
+      reflect(new B()).type, reflect(new B()).type.originalDeclaration);
+  Expect.equals(
+      reflect(new C()).type, reflect(new C()).type.originalDeclaration);
+  Expect.equals(
+      reflect(new D()).type, reflect(new D()).type.originalDeclaration);
+  Expect.notEquals(reflect(new E<num>()).type,
+      reflect(new E<num>()).type.originalDeclaration);
+  Expect.notEquals(reflect(new F<num>()).type,
+      reflect(new F<num>()).type.originalDeclaration);
+  Expect.equals(
+      reflect(new G()).type, reflect(new G()).type.originalDeclaration);
+  Expect.notEquals(
+      reflect(new H()).type, reflect(new H()).type.originalDeclaration);
+  Expect.equals(
+      reflect(new I()).type, reflect(new I()).type.originalDeclaration);
+
+  // Library members are all uninstantiated generics or non-generics.
+  currentMirrorSystem().libraries.values.forEach((libraryMirror) {
+    libraryMirror.declarations.values.forEach((declaration) {
+      if (declaration is ClassMirror) {
+        Expect.isTrue(declaration.isOriginalDeclaration);
+        Expect.equals(declaration, declaration.originalDeclaration);
+      }
+    });
+  });
+
+  Expect.equals(reflectClass(A).typeVariables[0].owner, reflectClass(A));
+  Expect.equals(reflectClass(Z).typeVariables[0].owner, reflectClass(Z));
+  Expect.notEquals(
+      reflectClass(A).typeVariables[0], reflectClass(Z).typeVariables[0]);
+  Expect.equals(
+      reflectClass(A).typeVariables[0], reflectClass(A).typeVariables[0]);
+}
diff --git a/tests/lib/mirrors/get_field_cache_test.dart b/tests/lib/mirrors/get_field_cache_test.dart
new file mode 100644
index 0000000..60c57f5
--- /dev/null
+++ b/tests/lib/mirrors/get_field_cache_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, 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:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  toString() => "A";
+}
+
+class B {
+  int x = 99;
+  toString() => "B";
+}
+
+void main() {
+  var a = new A();
+  var am = reflect(a);
+  for (int i = 0; i < 10; i++) {
+    // Adds a probe function on the symbol.
+    am.getField(#toString);
+  }
+  var b = new B();
+  var bm = reflect(b);
+  for (int i = 0; i < 10; i++) {
+    // Adds a field-cache on the mirror.
+    bm.getField(#x);
+  }
+  // There is a cache now, but the cache should not contain 'toString' from
+  // JavaScript's Object.prototype.
+  var toString = bm.getField(#toString).reflectee;
+  Expect.equals("B", toString());
+}
diff --git a/tests/lib/mirrors/get_field_static_test.dart b/tests/lib/mirrors/get_field_static_test.dart
new file mode 100644
index 0000000..60edc92
--- /dev/null
+++ b/tests/lib/mirrors/get_field_static_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  static foo(y, [x]) => y;
+  static get bar => 499;
+  static operator$foo([optional = 499]) => optional;
+  static var x = 42;
+  static final y = "toto";
+  static const z = true;
+}
+
+main() {
+  var cm = reflectClass(A);
+  var closure = cm.getField(#foo).reflectee;
+  Expect.equals("b", closure("b"));
+
+  closure = cm.getField(#operator$foo).reflectee;
+  Expect.equals(499, closure());
+
+  Expect.equals(499, cm.getField(#bar).reflectee);
+  Expect.equals(42, cm.getField(#x).reflectee);
+  Expect.equals("toto", cm.getField(#y).reflectee); // //# 00: ok
+  Expect.equals(true, cm.getField(#z).reflectee); //   //# 00: ok
+}
diff --git a/tests/lib/mirrors/get_field_test.dart b/tests/lib/mirrors/get_field_test.dart
new file mode 100644
index 0000000..d2a2d1c
--- /dev/null
+++ b/tests/lib/mirrors/get_field_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  foo(y, [x]) => y;
+  operator +(other) => null;
+  get bar => 499;
+  operator$foo([optional = 499]) => optional;
+}
+
+main() {
+  // We are using `getField` to tear off `foo`. We must make sure that all
+  // stub methods are installed.
+  var closure = reflect(new A()).getField(#foo).reflectee;
+  Expect.equals("b", closure("b"));
+
+  closure = reflect(new A()).getField(#operator$foo).reflectee;
+  Expect.equals(499, closure());
+}
diff --git a/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart
new file mode 100644
index 0000000..854dc58
--- /dev/null
+++ b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that MirrorSystem.getName works correctly on symbols returned from
+/// Invocation.memberName.  This is especially relevant when minifying.
+
+import 'dart:mirrors' show MirrorSystem;
+
+class Foo {
+  String noSuchMethod(Invocation invocation) {
+    return MirrorSystem.getName(invocation.memberName);
+  }
+}
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected: "$expected", but got "$actual"';
+  }
+}
+
+main() {
+  dynamic foo = new Foo();
+  expect('foo', foo.foo);
+  expect('foo', foo.foo());
+  expect('foo', foo.foo(null));
+  expect('foo', foo.foo(null, null));
+  expect('foo', foo.foo(a: null, b: null));
+
+  expect('baz', foo.baz);
+  expect('baz', foo.baz());
+  expect('baz', foo.baz(null));
+  expect('baz', foo.baz(null, null));
+  expect('baz', foo.baz(a: null, b: null));
+}
diff --git a/tests/lib/mirrors/get_symbol_name_test.dart b/tests/lib/mirrors/get_symbol_name_test.dart
new file mode 100644
index 0000000..68b3cb1
--- /dev/null
+++ b/tests/lib/mirrors/get_symbol_name_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors' show MirrorSystem;
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected: "$expected", but got "$actual"';
+  }
+}
+
+main() {
+  expect('fisk', MirrorSystem.getName(const Symbol('fisk')));
+  expect('fisk', MirrorSystem.getName(new Symbol('fisk')));
+}
diff --git a/tests/lib/mirrors/globalized_closures2_test.dart b/tests/lib/mirrors/globalized_closures2_test.dart
new file mode 100644
index 0000000..8d0bb9d
--- /dev/null
+++ b/tests/lib/mirrors/globalized_closures2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, 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.
+
+// Dart2js crashed on this example. It globalized both closures and created
+// top-level classes for closures (here the globalized_closure{2}). There was a
+// name-clash (both being named "main_closure") which led to a crash.
+
+library main;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return confuse(() => print(42));
+  }
+  return x;
+}
+
+main() {
+  var globalized_closure = confuse(() => 499);
+  var globalized_closure2 = confuse(() => 99);
+  globalized_closure();
+  globalized_closure2();
+  final ms = currentMirrorSystem();
+  var lib = ms.findLibrary(#main);
+  var collectedParents = [];
+  var classes = lib.declarations.values;
+  for (var c in classes) {
+    if (c is ClassMirror && c.superclass != null) {
+      collectedParents.add(MirrorSystem.getName(c.superclass!.simpleName));
+    }
+  }
+  Expect.isTrue(collectedParents.isEmpty); //  //# 00: ok
+}
diff --git a/tests/lib/mirrors/globalized_closures_test.dart b/tests/lib/mirrors/globalized_closures_test.dart
new file mode 100644
index 0000000..9de8ae0
--- /dev/null
+++ b/tests/lib/mirrors/globalized_closures_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, 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.
+
+// Dart2js crashed on this example. It globalized closures and created
+// top-level classes for closures (here the globalized_closure). There was a
+// name-clash with the global "main_closure" class which led to a crash.
+
+library main;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class main_closure {}
+
+confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(() => 42);
+  return x;
+}
+
+main() {
+  new main_closure();
+  var globalized_closure = confuse(() => 499);
+  globalized_closure();
+  final ms = currentMirrorSystem();
+  var lib = ms.findLibrary(#main);
+  var collectedParents = [];
+  var classes = lib.declarations.values;
+  for (var c in classes) {
+    if (c is ClassMirror && c.superclass != null) {
+      collectedParents.add(MirrorSystem.getName(c.superclass!.simpleName));
+    }
+  }
+  Expect.listEquals(["Object"], collectedParents); //  //# 00: ok
+}
diff --git a/tests/lib/mirrors/hierarchy_invariants_test.dart b/tests/lib/mirrors/hierarchy_invariants_test.dart
new file mode 100644
index 0000000..2ff3dc8
--- /dev/null
+++ b/tests/lib/mirrors/hierarchy_invariants_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.hierarchy_invariants_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+isAnonymousMixinApplication(classMirror) {
+  return MirrorSystem.getName(classMirror.simpleName).contains(' with ');
+}
+
+checkClass(classMirror) {
+  Expect.isTrue(classMirror.simpleName is Symbol);
+  Expect.notEquals(null, classMirror.owner);
+  Expect.isTrue(classMirror.owner is LibraryMirror);
+  if (!isAnonymousMixinApplication(classMirror)) {
+    Expect.equals(classMirror.originalDeclaration,
+        classMirror.owner.declarations[classMirror.simpleName]);
+  } else {
+    Expect.isNull(classMirror.owner.declarations[classMirror.simpleName]);
+  }
+  Expect.isTrue(classMirror.superinterfaces is List);
+  if (classMirror.superclass == null) {
+    Expect.isTrue((reflectClass(Object) == classMirror) ||
+        (classMirror.toString() == "ClassMirror on 'FutureOr'"));
+  } else {
+    checkClass(classMirror.superclass);
+  }
+}
+
+checkLibrary(libraryMirror) {
+  libraryMirror.declarations.values
+      .where((d) => d is ClassMirror)
+      .forEach(checkClass);
+}
+
+main() {
+  currentMirrorSystem().libraries.values.forEach(checkLibrary);
+}
diff --git a/tests/lib/mirrors/hot_get_field_test.dart b/tests/lib/mirrors/hot_get_field_test.dart
new file mode 100644
index 0000000..65cf281
--- /dev/null
+++ b/tests/lib/mirrors/hot_get_field_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2014, 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 test.hot_get_field;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+  var field;
+  var _field;
+  operator +(other) => field + other;
+}
+
+const int optimizationThreshold = 20;
+
+testPublic() {
+  var c = new C();
+  var im = reflect(c);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    c.field = i;
+    Expect.equals(i, im.getField(#field).reflectee);
+  }
+}
+
+testPrivate() {
+  var c = new C();
+  var im = reflect(c);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    c._field = i;
+    Expect.equals(i, im.getField(#_field).reflectee);
+  }
+}
+
+testPrivateWrongLibrary() {
+  var c = new C();
+  var im = reflect(c);
+  var selector = MirrorSystem.getSymbol(
+      '_field', reflectClass(Mirror).owner as LibraryMirror);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    Expect.throwsNoSuchMethodError(() => im.getField(selector));
+  }
+}
+
+testOperator() {
+  var plus = const Symbol("+");
+  var c = new C();
+  var im = reflect(c);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    c.field = i;
+    var closurizedPlus = im.getField(plus).reflectee;
+    Expect.isTrue(closurizedPlus is Function);
+    Expect.equals(2 * i, closurizedPlus(i));
+  }
+}
+
+main() {
+  testPublic();
+  testPrivate();
+  testPrivateWrongLibrary();
+  testOperator();
+}
diff --git a/tests/lib/mirrors/hot_set_field_test.dart b/tests/lib/mirrors/hot_set_field_test.dart
new file mode 100644
index 0000000..cd084d3
--- /dev/null
+++ b/tests/lib/mirrors/hot_set_field_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2014, 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 test.hot_set_field;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+  var field;
+  var _field;
+}
+
+const int optimizationThreshold = 20;
+
+testPublic() {
+  var c = new C();
+  var im = reflect(c);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    im.setField(#field, i);
+    Expect.equals(i, c.field);
+  }
+}
+
+testPrivate() {
+  var c = new C();
+  var im = reflect(c);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    im.setField(#_field, i);
+    Expect.equals(i, c._field);
+  }
+}
+
+testPrivateWrongLibrary() {
+  var c = new C();
+  var im = reflect(c);
+  var selector = MirrorSystem.getSymbol(
+      '_field', reflectClass(Mirror).owner as LibraryMirror);
+
+  for (int i = 0; i < (2 * optimizationThreshold); i++) {
+    Expect.throwsNoSuchMethodError(() => im.setField(selector, i));
+  }
+}
+
+main() {
+  testPublic();
+  testPrivate();
+  testPrivateWrongLibrary();
+}
diff --git a/tests/lib/mirrors/immutable_collections_test.dart b/tests/lib/mirrors/immutable_collections_test.dart
new file mode 100644
index 0000000..ed2f3af
--- /dev/null
+++ b/tests/lib/mirrors/immutable_collections_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.immutable_collections;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+bool someException(e) => e is Exception || e is Error;
+
+checkList(dynamic l, String reason) {
+  Expect.throws(() => l[0] = 'value', someException, reason);
+  Expect.throws(() => l.add('value'), someException, reason);
+  Expect.throws(() => l.clear(), someException, reason);
+}
+
+checkMap(Map m, String reason) {
+  Expect.throws(() => m[#key] = 'value', someException, reason);
+  checkList(m.keys, '$reason keys');
+  checkList(m.values, '$reason values');
+}
+
+checkVariable(VariableMirror vm) {
+  checkList(vm.metadata, 'VariableMirror.metadata');
+}
+
+checkTypeVariable(TypeVariableMirror tvm) {
+  checkList(tvm.metadata, 'TypeVariableMirror.metadata');
+}
+
+checkParameter(ParameterMirror pm) {
+  checkList(pm.metadata, 'ParameterMirror.metadata');
+}
+
+checkMethod(MethodMirror mm) {
+  checkList(mm.parameters, 'MethodMirror.parameters');
+  checkList(mm.metadata, 'MethodMirror.metadata');
+
+  mm.parameters.forEach(checkParameter);
+}
+
+checkClass(ClassMirror cm) {
+  checkMap(cm.declarations, 'ClassMirror.declarations');
+  checkMap(cm.instanceMembers, 'ClassMirror.instanceMembers');
+  checkMap(cm.staticMembers, 'ClassMirror.staticMembers');
+  checkList(cm.metadata, 'ClassMirror.metadata');
+  checkList(cm.superinterfaces, 'ClassMirror.superinterfaces');
+  checkList(cm.typeArguments, 'ClassMirror.typeArguments');
+  checkList(cm.typeVariables, 'ClassMirror.typeVariables');
+
+  cm.declarations.values.forEach(checkDeclaration);
+  cm.instanceMembers.values.forEach(checkDeclaration);
+  cm.staticMembers.values.forEach(checkDeclaration);
+  cm.typeVariables.forEach(checkTypeVariable);
+}
+
+checkType(TypeMirror tm) {
+  checkList(tm.metadata, 'TypeMirror.metadata');
+}
+
+checkDeclaration(DeclarationMirror dm) {
+  if (dm is MethodMirror) checkMethod(dm);
+  if (dm is ClassMirror) checkClass(dm);
+  if (dm is TypeMirror) checkType(dm);
+  if (dm is VariableMirror) checkVariable(dm);
+  if (dm is TypeVariableMirror) checkTypeVariable(dm);
+}
+
+checkLibrary(LibraryMirror lm) {
+  checkMap(lm.declarations, 'LibraryMirror.declarations');
+  checkList(lm.metadata, 'LibraryMirror.metadata');
+
+  lm.declarations.values.forEach(checkDeclaration);
+}
+
+main() {
+  currentMirrorSystem().libraries.values.forEach(checkLibrary);
+  checkType(currentMirrorSystem().voidType);
+  checkType(currentMirrorSystem().dynamicType);
+}
diff --git a/tests/lib/mirrors/inference_and_no_such_method_test.dart b/tests/lib/mirrors/inference_and_no_such_method_test.dart
new file mode 100644
index 0000000..79dd635
--- /dev/null
+++ b/tests/lib/mirrors/inference_and_no_such_method_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that did type inferencing on parameters
+// whose type may change at runtime due to an invocation through
+// [InstanceMirror.delegate].
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class A {
+  noSuchMethod(im) {
+    reflect(new B()).delegate(im);
+  }
+}
+
+class B {
+  foo(a) => a + 42;
+}
+
+main() {
+  Expect.equals(42, new B().foo(0));
+  dynamic a = new A();
+  Expect.throwsTypeError(() => a.foo('foo'));
+}
diff --git a/tests/lib/mirrors/inherit_field_test.dart b/tests/lib/mirrors/inherit_field_test.dart
new file mode 100644
index 0000000..d8590ed
--- /dev/null
+++ b/tests/lib/mirrors/inherit_field_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test inherited fields.
+
+library test.inherit_field_test;
+
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+class Foo {
+  var field;
+}
+
+class Bar extends Foo {}
+
+void main() {
+  expect(
+      'Variable(s(field) in s(Foo))', reflectClass(Foo).declarations[#field]);
+  expect('<null>', reflectClass(Bar).declarations[#field]);
+}
diff --git a/tests/lib/mirrors/inherited_metadata_test.dart b/tests/lib/mirrors/inherited_metadata_test.dart
new file mode 100644
index 0000000..87a2b42
--- /dev/null
+++ b/tests/lib/mirrors/inherited_metadata_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, 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 test.mirrors;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class RemoteClass {
+  final String name;
+  const RemoteClass([this.name = "default"]);
+}
+
+class A {}
+
+@RemoteClass("ASF")
+class B extends A {}
+
+class C extends B {}
+
+void main() {
+  bool foundB = false;
+
+  MirrorSystem mirrorSystem = currentMirrorSystem();
+  mirrorSystem.libraries.forEach((lk, l) {
+    l.declarations.forEach((dk, d) {
+      if (d is ClassMirror) {
+        d.metadata.forEach((md) {
+          InstanceMirror metadata = md as InstanceMirror;
+          // Metadata must not be inherited.
+          if (metadata.type == reflectClass(RemoteClass)) {
+            Expect.isFalse(foundB);
+            Expect.equals(#B, d.simpleName);
+            foundB = true;
+          }
+        });
+      }
+    });
+  });
+
+  Expect.isTrue(foundB);
+}
diff --git a/tests/lib/mirrors/initializing_formals_test.dart b/tests/lib/mirrors/initializing_formals_test.dart
new file mode 100644
index 0000000..f02a0ee
--- /dev/null
+++ b/tests/lib/mirrors/initializing_formals_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.initializing_formals;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  late num numField;
+  late bool boolField;
+  late String stringField;
+  late T tField;
+  late dynamic _privateField;
+
+  Class.nongeneric(this.numField);
+  Class.named({this.boolField = false});
+  Class.optPos([this.stringField = 'default']);
+  Class.generic(this.tField);
+  Class.private(this._privateField);
+
+  Class.explicitType(num this.numField);
+  Class.withVar(var this.numField);
+  Class.withSubtype(int this.numField);
+}
+
+class Constant {
+  final num value;
+  const Constant(this.value);
+  const Constant.marked(final this.value);
+}
+
+main() {
+  MethodMirror mm;
+  ParameterMirror pm;
+
+  mm = reflectClass(Class).declarations[#Class.nongeneric] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#numField, pm.simpleName);
+  Expect.equals(reflectClass(num), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.named] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#boolField, pm.simpleName);
+  Expect.equals(reflectClass(bool), pm.type);
+  Expect.isTrue(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isTrue(pm.isOptional); // //# 01: ok
+  Expect.isTrue(pm.hasDefaultValue); // //# 01: ok
+  Expect.equals(false, pm.defaultValue!.reflectee); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.optPos] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#stringField, pm.simpleName);
+  Expect.equals(reflectClass(String), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isTrue(pm.isOptional); // //# 01: ok
+  Expect.isTrue(pm.hasDefaultValue); // //# 01: ok
+  Expect.equals('default', pm.defaultValue!.reflectee); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.generic] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#tField, pm.simpleName);
+  Expect.equals(reflectClass(Class).typeVariables.single, pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.private] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#_privateField, pm.simpleName); // //# 03: ok
+  Expect.equals(currentMirrorSystem().dynamicType, pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isTrue(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.explicitType] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#numField, pm.simpleName);
+  Expect.equals(reflectClass(num), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.withVar] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#numField, pm.simpleName);
+  Expect.equals(reflectClass(num), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Class).declarations[#Class.withSubtype] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#numField, pm.simpleName);
+  Expect.equals(reflectClass(int), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal); // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Constant).declarations[#Constant] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#value, pm.simpleName);
+  Expect.equals(reflectClass(num), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isFalse(pm.isFinal);  // N.B. // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  mm = reflectClass(Constant).declarations[#Constant.marked] as MethodMirror;
+  pm = mm.parameters.single;
+  Expect.equals(#value, pm.simpleName);
+  Expect.equals(reflectClass(num), pm.type);
+  Expect.isFalse(pm.isNamed); // //# 01: ok
+  Expect.isTrue(pm.isFinal);  // N.B. // //# 01: ok
+  Expect.isFalse(pm.isOptional); // //# 01: ok
+  Expect.isFalse(pm.hasDefaultValue); // //# 01: ok
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+}
diff --git a/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart b/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart
new file mode 100644
index 0000000..bfdd69c
--- /dev/null
+++ b/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that instance creation expressions inside function
+// annotations are properly handled.  See dartbug.com/23354
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+  final String s;
+  const C(this.s);
+}
+
+class D {
+  final C c;
+  const D(this.c);
+}
+
+@D(const C('foo'))
+f() {}
+
+main() {
+  ClosureMirror closureMirror = reflect(f) as ClosureMirror;
+  List<InstanceMirror> metadata = closureMirror.function.metadata;
+  Expect.equals(1, metadata.length);
+  Expect.equals(metadata[0].reflectee.c.s, 'foo');
+}
diff --git a/tests/lib/mirrors/instance_members_easier_test.dart b/tests/lib/mirrors/instance_members_easier_test.dart
new file mode 100644
index 0000000..4a9fe66
--- /dev/null
+++ b/tests/lib/mirrors/instance_members_easier_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.instance_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'declarations_model_easier.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+class EasierSuperclass {
+  shuper() {}
+  static staticShuper() {}
+}
+
+class EasierMixin {
+  mixin() {}
+  static staticMixin() {}
+}
+
+class EasierMixinApplication extends EasierSuperclass with EasierMixin {
+  application() {}
+  static staticApplication() {}
+}
+
+class Derived extends EasierMixinApplication {
+  derived() {}
+  static staticDerived() {}
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+
+  Expect.setEquals([
+    #+,
+    #instanceVariable,
+    const Symbol('instanceVariable='),
+    #instanceGetter,
+    const Symbol('instanceSetter='),
+    #instanceMethod,
+    #-,
+    #inheritedInstanceVariable,
+    const Symbol('inheritedInstanceVariable='),
+    #inheritedInstanceGetter,
+    const Symbol('inheritedInstanceSetter='),
+    #inheritedInstanceMethod,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+
+  Expect.setEquals([
+    #instanceVariable,
+    const Symbol('instanceVariable='),
+    #inheritedInstanceVariable,
+    const Symbol('inheritedInstanceVariable=')
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+
+  cm = reflectClass(Derived);
+  Expect.setEquals([
+    #derived,
+    #shuper,
+    #mixin,
+    #application,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+
+  cm = reflectClass(EasierMixinApplication);
+  Expect.setEquals([
+    #shuper,
+    #mixin,
+    #application,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+}
diff --git a/tests/lib/mirrors/instance_members_test.dart b/tests/lib/mirrors/instance_members_test.dart
new file mode 100644
index 0000000..4bbf79f
--- /dev/null
+++ b/tests/lib/mirrors/instance_members_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.instance_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'declarations_model.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+
+  Expect.setEquals([
+    #+,
+    #instanceVariable,
+    const Symbol('instanceVariable='),
+    #instanceGetter,
+    const Symbol('instanceSetter='),
+    #instanceMethod,
+    #-,
+    #inheritedInstanceVariable,
+    const Symbol('inheritedInstanceVariable='),
+    #inheritedInstanceGetter,
+    const Symbol('inheritedInstanceSetter='),
+    #inheritedInstanceMethod,
+    #*,
+    #mixinInstanceVariable,
+    const Symbol('mixinInstanceVariable='),
+    #mixinInstanceGetter,
+    const Symbol('mixinInstanceSetter='),
+    #mixinInstanceMethod,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+
+  Expect.setEquals([
+    #instanceVariable,
+    const Symbol('instanceVariable='),
+    #inheritedInstanceVariable,
+    const Symbol('inheritedInstanceVariable='),
+    #mixinInstanceVariable,
+    const Symbol('mixinInstanceVariable=')
+  ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic));
+}
diff --git a/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart b/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart
new file mode 100644
index 0000000..5c26410
--- /dev/null
+++ b/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.instance_members_unimplemented_interface;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class I {
+  implementMe() {}
+}
+
+abstract class C implements I {}
+
+selectKeys<K, V>(Map<K, V> map, bool predicate(V)) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror cm = reflectClass(C);
+
+  // N.B.: Does not include #implementMe.
+  Expect.setEquals([#hashCode, #runtimeType, #==, #noSuchMethod, #toString],
+      selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+}
diff --git a/tests/lib/mirrors/instance_members_with_override_test.dart b/tests/lib/mirrors/instance_members_with_override_test.dart
new file mode 100644
index 0000000..94a2252
--- /dev/null
+++ b/tests/lib/mirrors/instance_members_with_override_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.instance_members_with_override;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'package:meta/meta.dart' show virtual;
+
+class S {
+  @virtual
+  var field;
+  @virtual
+  final finalField = 0;
+  method() {}
+  get getter {}
+  set setter(x) {}
+  notOverridden() {}
+}
+
+abstract class C extends S {
+  var field;
+  final finalField = 0;
+  method() {}
+  get getter {}
+  set setter(x) {}
+  /* abstract */ notOverridden();
+}
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror sMirror = reflectClass(S);
+  ClassMirror cMirror = reflectClass(C);
+
+  Expect.setEquals([
+    #field,
+    const Symbol('field='),
+    #finalField,
+    #method,
+    #getter,
+    const Symbol('setter='),
+    #notOverridden,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(sMirror.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+
+  Expect.equals(sMirror, sMirror.instanceMembers[#field]!.owner);
+  Expect.equals(
+      sMirror, sMirror.instanceMembers[const Symbol('field=')]!.owner);
+  Expect.equals(sMirror, sMirror.instanceMembers[#finalField]!.owner);
+  Expect.equals(sMirror, sMirror.instanceMembers[#method]!.owner);
+  Expect.equals(sMirror, sMirror.instanceMembers[#getter]!.owner);
+  Expect.equals(
+      sMirror, sMirror.instanceMembers[const Symbol('setter=')]!.owner);
+
+  Expect.setEquals([
+    #field,
+    const Symbol('field='),
+    #finalField,
+    #method,
+    #getter,
+    const Symbol('setter='),
+    #notOverridden,
+    #hashCode,
+    #runtimeType,
+    #==,
+    #noSuchMethod,
+    #toString
+  ], selectKeys(cMirror.instanceMembers, (dm) => !dm.isPrivate));
+  // Filter out private to avoid implementation-specific members of Object.
+
+  Expect.equals(cMirror, cMirror.instanceMembers[#field]!.owner);
+  Expect.equals(
+      cMirror, cMirror.instanceMembers[const Symbol('field=')]!.owner);
+  Expect.equals(cMirror, cMirror.instanceMembers[#finalField]!.owner);
+  Expect.equals(cMirror, cMirror.instanceMembers[#method]!.owner);
+  Expect.equals(cMirror, cMirror.instanceMembers[#getter]!.owner);
+  Expect.equals(
+      cMirror, cMirror.instanceMembers[const Symbol('setter=')]!.owner);
+
+  Expect.equals(sMirror, sMirror.instanceMembers[#notOverridden]!.owner);
+  Expect.equals(sMirror, cMirror.instanceMembers[#notOverridden]!.owner);
+}
diff --git a/tests/lib/mirrors/instantiate_abstract_class_test.dart b/tests/lib/mirrors/instantiate_abstract_class_test.dart
new file mode 100644
index 0000000..057b40b
--- /dev/null
+++ b/tests/lib/mirrors/instantiate_abstract_class_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.instantiate_abstract_class;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+assertInstanitationErrorOnGenerativeConstructors(classMirror) {
+  classMirror.declarations.values.forEach((decl) {
+    if (decl is! MethodMirror) return;
+    if (!decl.isGenerativeConstructor) return;
+    var args = new List(decl.parameters.length);
+    Expect.throws(
+        () => classMirror.newInstance(decl.constructorName, args),
+        (e) => e is AbstractClassInstantiationError,
+        '${decl.qualifiedName} should have failed');
+  });
+}
+
+runFactoryConstructors(classMirror) {
+  classMirror.declarations.values.forEach((decl) {
+    if (decl is! MethodMirror) return;
+    if (!decl.isFactoryConstructor) return;
+    var args = new List(decl.parameters.length);
+    classMirror.newInstance(decl.constructorName, args); // Should not throw.
+  });
+}
+
+abstract class AbstractClass {
+  AbstractClass();
+  AbstractClass.named();
+  factory AbstractClass.named2() => new ConcreteClass();
+}
+
+class ConcreteClass implements AbstractClass {}
+
+main() {
+  assertInstanitationErrorOnGenerativeConstructors(reflectType(num));
+  assertInstanitationErrorOnGenerativeConstructors(reflectType(double));
+  assertInstanitationErrorOnGenerativeConstructors(reflectType(StackTrace));
+
+  assertInstanitationErrorOnGenerativeConstructors(reflectType(AbstractClass));
+  runFactoryConstructors(reflectType(AbstractClass));
+}
diff --git a/tests/lib/mirrors/intercepted_cache_test.dart b/tests/lib/mirrors/intercepted_cache_test.dart
new file mode 100644
index 0000000..b38881c
--- /dev/null
+++ b/tests/lib/mirrors/intercepted_cache_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a test for a problem in how dart2js cached InstanceMirror.invoke,
+// etc. The test is using getField, as invoke, setField, and getField all share
+// the same caching.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Foo {
+  Foo(this.length);
+  int length;
+}
+
+main() {
+  Expect.equals(1, reflect(new Foo(1)).getField(#length).reflectee);
+  Expect.equals(2, reflect(new Foo(2)).getField(#length).reflectee);
+  Expect.equals(0, reflect([]).getField(#length).reflectee);
+}
diff --git a/tests/lib/mirrors/intercepted_class_test.dart b/tests/lib/mirrors/intercepted_class_test.dart
new file mode 100644
index 0000000..57a7737
--- /dev/null
+++ b/tests/lib/mirrors/intercepted_class_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Ensure that classes handled specially by dart2js can be reflected on.
+
+library test.intercepted_class_test;
+
+import 'dart:mirrors';
+
+import 'stringify.dart' show stringify, expect;
+
+checkClassMirrorMethods(ClassMirror cls) {
+  var variables = new Map();
+  cls.declarations.forEach((Symbol key, DeclarationMirror value) {
+    if (value is VariableMirror && !value.isStatic && !value.isPrivate) {
+      variables[key] = value;
+    }
+  });
+  expect('{}', variables);
+}
+
+checkClassMirror(ClassMirror cls, String name) {
+  expect('s($name)', cls.simpleName);
+  checkClassMirrorMethods(cls);
+}
+
+main() {
+  checkClassMirror(reflectClass(String), 'String');
+  checkClassMirror(reflectClass(int), 'int');
+  checkClassMirror(reflectClass(double), 'double');
+  checkClassMirror(reflectClass(num), 'num');
+  checkClassMirror(reflectClass(bool), 'bool');
+  checkClassMirror(reflectClass(List), 'List');
+}
diff --git a/tests/lib/mirrors/intercepted_object_test.dart b/tests/lib/mirrors/intercepted_object_test.dart
new file mode 100644
index 0000000..5acdf8b
--- /dev/null
+++ b/tests/lib/mirrors/intercepted_object_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Ensure that objects handled specially by dart2js can be reflected on.
+
+library test.intercepted_object_test;
+
+import 'dart:mirrors';
+
+import 'stringify.dart' show stringify, expect;
+
+import 'intercepted_class_test.dart' show checkClassMirrorMethods;
+
+checkImplements(object, String name) {
+  ClassMirror cls = reflect(object).type;
+  checkClassMirrorMethods(cls);
+
+  // The VM implements List via a mixin, so check for that.
+  if (cls.superinterfaces.isEmpty && object is List) {
+    cls = cls.superclass!.superclass!.mixin;
+  }
+
+  // The VM implements String through an intermediate abstract
+  // class.
+  if (cls.superinterfaces.isEmpty && object is String) {
+    cls = cls.superclass!;
+  }
+
+  // The VM implements int through an intermediate abstract
+  // class.
+  if (object is int &&
+      stringify(cls.superclass!.simpleName) == 's(_IntegerImplementation)') {
+    cls = cls.superclass!;
+  }
+
+  List<ClassMirror> superinterfaces = cls.superinterfaces;
+  String symName = 's($name)';
+  for (ClassMirror superinterface in superinterfaces) {
+    print(superinterface.simpleName);
+    if (symName == stringify(superinterface.simpleName)) {
+      checkClassMirrorMethods(superinterface);
+      return;
+    }
+  }
+
+  // A class implements itself, even if not explicitly declared.
+  if (symName == stringify(cls.simpleName)) {
+    checkClassMirrorMethods(cls);
+    return;
+  }
+
+  // TODO(floitsch): use correct fail
+  expect(name, "super interface not found");
+}
+
+main() {
+  checkImplements('', 'String');
+  checkImplements(1, 'int');
+  checkImplements(1.5, 'double');
+  checkImplements(true, 'bool');
+  checkImplements(false, 'bool');
+  checkImplements([], 'List');
+}
diff --git a/tests/lib/mirrors/intercepted_superclass_test.dart b/tests/lib/mirrors/intercepted_superclass_test.dart
new file mode 100644
index 0000000..a9ea3a5
--- /dev/null
+++ b/tests/lib/mirrors/intercepted_superclass_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.intercepted_superclass_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+check(ClassMirror cm) {
+  Expect.isTrue(cm is ClassMirror);
+  Expect.isNotNull(cm);
+}
+
+main() {
+  check(reflect('').type.superclass!);
+  check(reflect(1).type.superclass!);
+  check(reflect(1.5).type.superclass!);
+  check(reflect(true).type.superclass!);
+  check(reflect(false).type.superclass!);
+  check(reflect([]).type.superclass!);
+
+  check(reflectClass(String).superclass!);
+  check(reflectClass(int).superclass!);
+  check(reflectClass(double).superclass!);
+  check(reflectClass(num).superclass!);
+  check(reflectClass(bool).superclass!);
+  check(reflectClass(List).superclass!);
+}
diff --git a/tests/lib/mirrors/invocation_cache_test.dart b/tests/lib/mirrors/invocation_cache_test.dart
new file mode 100644
index 0000000..f8ec29c
--- /dev/null
+++ b/tests/lib/mirrors/invocation_cache_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  toString() => "A";
+}
+
+main() {
+  // The invocation cache must not find the 'toString' from JavaScript's
+  // Object.prototype.
+  var toString = reflect(new A()).getField(#toString).reflectee;
+  Expect.equals("A", Function.apply(toString, [], {}));
+}
diff --git a/tests/lib/mirrors/invocation_fuzz_test.dart b/tests/lib/mirrors/invocation_fuzz_test.dart
new file mode 100644
index 0000000..d08c351
--- /dev/null
+++ b/tests/lib/mirrors/invocation_fuzz_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2014, 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.
+
+// This test reflectively enumerates all the methods in the system and tries to
+// invoke them with various basic values (nulls, ints, etc). This may result in
+// Dart exceptions or hangs, but should never result in crashes or JavaScript
+// exceptions.
+
+library test.invoke_natives;
+
+import 'dart:mirrors';
+import 'dart:async';
+import 'dart:io';
+
+// Methods to be skipped, by qualified name.
+var blacklist = [
+  // Don't recurse on this test.
+  'test.invoke_natives',
+
+  // Don't exit the test pre-maturely.
+  'dart.io.exit',
+
+  // Don't change the exit code, which may fool the test harness.
+  'dart.io.exitCode',
+
+  // Don't kill random other processes.
+  'dart.io.Process.killPid',
+
+  // Don't break into the debugger.
+  'dart.developer.debugger',
+
+  // Don't run blocking io calls.
+  'dart.io.sleep',
+  new RegExp(r".*Sync$"),
+
+  // Don't call private methods in dart.async as they may circumvent the zoned
+  // error handling below.
+  new RegExp(r"^dart\.async\._.*$"),
+];
+
+bool isBlacklisted(Symbol qualifiedSymbol) {
+  var qualifiedString = MirrorSystem.getName(qualifiedSymbol);
+  for (var pattern in blacklist) {
+    if (qualifiedString.contains(pattern)) {
+      print('Skipping $qualifiedString');
+      return true;
+    }
+  }
+  return false;
+}
+
+class Task {
+  dynamic name;
+  dynamic action;
+}
+
+var queue = new List<Task>();
+
+checkMethod(MethodMirror m, ObjectMirror target, [origin]) {
+  if (isBlacklisted(m.qualifiedName)) return;
+
+  var task = new Task();
+  task.name = '${MirrorSystem.getName(m.qualifiedName)} from $origin';
+
+  if (m.isRegularMethod) {
+    task.action = () => target.invoke(
+        m.simpleName, new List.filled(m.parameters.length, fuzzArgument));
+  } else if (m.isGetter) {
+    task.action = () => target.getField(m.simpleName);
+  } else if (m.isSetter) {
+    task.action = () => target.setField(m.simpleName, null);
+  } else if (m.isConstructor) {
+    return;
+  } else {
+    throw "Unexpected method kind";
+  }
+
+  queue.add(task);
+}
+
+checkInstance(instanceMirror, origin) {
+  ClassMirror? klass = instanceMirror.type;
+  while (klass != null) {
+    instanceMirror.type.declarations.values
+        .where((d) => d is MethodMirror && !d.isStatic)
+        .forEach((m) => checkMethod(m, instanceMirror, origin));
+    klass = klass.superclass;
+  }
+}
+
+checkClass(classMirror) {
+  classMirror.declarations.values
+      .where((d) => d is MethodMirror && d.isStatic)
+      .forEach((m) => checkMethod(m, classMirror));
+
+  classMirror.declarations.values
+      .where((d) => d is MethodMirror && d.isConstructor)
+      .forEach((m) {
+    if (isBlacklisted(m.qualifiedName)) return;
+    var task = new Task();
+    task.name = MirrorSystem.getName(m.qualifiedName);
+
+    task.action = () {
+      var instance = classMirror.newInstance(m.constructorName,
+          new List.filled(m.parameters.length, fuzzArgument));
+      checkInstance(instance, task.name);
+    };
+    queue.add(task);
+  });
+}
+
+checkLibrary(libraryMirror) {
+  print(libraryMirror.simpleName);
+  if (isBlacklisted(libraryMirror.qualifiedName)) return;
+
+  libraryMirror.declarations.values
+      .where((d) => d is ClassMirror)
+      .forEach(checkClass);
+
+  libraryMirror.declarations.values
+      .where((d) => d is MethodMirror)
+      .forEach((m) => checkMethod(m, libraryMirror));
+}
+
+var testZone;
+
+doOneTask() {
+  if (queue.length == 0) {
+    print('Done');
+    // Forcibly exit as we likely opened sockets and timers during the fuzzing.
+    exit(0);
+  }
+
+  var task = queue.removeLast();
+  print(task.name);
+  try {
+    task.action();
+  } catch (e) {}
+
+  // Register the next task in a timer callback so as to yield to async code
+  // scheduled in the current task. This isn't necessary for the test itself,
+  // but is helpful when trying to figure out which function is responsible for
+  // a crash.
+  testZone.createTimer(Duration.zero, doOneTask);
+}
+
+var fuzzArgument;
+
+main() {
+  fuzzArgument = null;
+  fuzzArgument = 1; // //# smi: ok
+  fuzzArgument = false; // //# false: ok
+  fuzzArgument = 'string'; // //# string: ok
+  fuzzArgument = new List(0); // //# emptyarray: ok
+
+  print('Fuzzing with $fuzzArgument');
+
+  currentMirrorSystem().libraries.values.forEach(checkLibrary);
+
+  var valueObjects = [
+    true,
+    false,
+    null,
+    [],
+    {},
+    dynamic,
+    0,
+    0xEFFFFFF,
+    0xFFFFFFFF,
+    0xFFFFFFFFFFFFFFFF,
+    3.14159,
+    "foo",
+    'blåbærgrød',
+    'Îñţérñåţîöñåļîžåţîờñ',
+    "\u{1D11E}",
+    #symbol
+  ];
+  valueObjects.forEach((v) => checkInstance(reflect(v), 'value object'));
+
+  void uncaughtErrorHandler(self, parent, zone, error, stack) {}
+
+  var zoneSpec =
+      new ZoneSpecification(handleUncaughtError: uncaughtErrorHandler);
+  testZone = Zone.current.fork(specification: zoneSpec);
+  testZone.createTimer(Duration.zero, doOneTask);
+}
diff --git a/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart b/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart
new file mode 100644
index 0000000..a7a6d75
--- /dev/null
+++ b/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors" show reflect;
+import "package:expect/expect.dart";
+
+class Proxy {
+  final proxied;
+  Proxy(this.proxied);
+  noSuchMethod(mirror) => reflect(proxied).delegate(mirror);
+}
+
+main() {
+  testList();
+  testString();
+  testInt();
+  testDouble();
+}
+
+testList() {
+  dynamic list = [];
+  dynamic proxy = new Proxy(list);
+
+  Expect.isTrue(proxy.isEmpty);
+  Expect.isTrue(list.isEmpty);
+
+  proxy.add(42);
+
+  Expect.isFalse(proxy.isEmpty);
+  Expect.equals(1, proxy.length);
+  Expect.equals(42, proxy[0]);
+
+  Expect.isFalse(list.isEmpty);
+  Expect.equals(1, list.length);
+  Expect.equals(42, list[0]);
+
+  proxy.add(87);
+
+  Expect.equals(2, proxy.length);
+  Expect.equals(87, proxy[1]);
+
+  Expect.equals(2, list.length);
+  Expect.equals(87, list[1]);
+
+  Expect.throwsNoSuchMethodError(() => proxy.funky());
+  Expect.throwsNoSuchMethodError(() => list.funky());
+}
+
+testString() {
+  dynamic string = "funky";
+  dynamic proxy = new Proxy(string);
+
+  Expect.equals(string.codeUnitAt(0), proxy.codeUnitAt(0));
+  Expect.equals(string.length, proxy.length);
+
+  Expect.throwsNoSuchMethodError(() => proxy.funky());
+  Expect.throwsNoSuchMethodError(() => string.funky());
+}
+
+testInt() {
+  dynamic number = 42;
+  dynamic proxy = new Proxy(number);
+
+  Expect.equals(number + 87, proxy + 87);
+  Expect.equals(number.toDouble(), proxy.toDouble());
+
+  Expect.throwsNoSuchMethodError(() => proxy.funky());
+  Expect.throwsNoSuchMethodError(() => number.funky());
+}
+
+testDouble() {
+  dynamic number = 42.99;
+  dynamic proxy = new Proxy(number);
+
+  Expect.equals(number + 87, proxy + 87);
+  Expect.equals(number.toInt(), proxy.toInt());
+
+  Expect.throwsNoSuchMethodError(() => proxy.funky());
+  Expect.throwsNoSuchMethodError(() => number.funky());
+}
diff --git a/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart b/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart
new file mode 100644
index 0000000..c1151a3
--- /dev/null
+++ b/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors" show reflect;
+import "package:expect/expect.dart";
+
+// Testing InstanceMirror.delegate method; test of issue 7227.
+
+var reachedSetX = 0;
+var reachedGetX = 0;
+var reachedM = 0;
+
+class A {
+  set x(val) {
+    reachedSetX = val;
+  }
+
+  get x {
+    reachedGetX = 1;
+  }
+
+  m() {
+    reachedM = 1;
+  }
+}
+
+class B {
+  final a = new A();
+  noSuchMethod(mirror) => reflect(a).delegate(mirror);
+}
+
+main() {
+  dynamic b = new B();
+  b.x = 10;
+  Expect.equals(10, reachedSetX);
+  b.x;
+  Expect.equals(1, reachedGetX);
+  b.m();
+  Expect.equals(1, reachedM);
+}
diff --git a/tests/lib/mirrors/invoke_call_on_closure_test.dart b/tests/lib/mirrors/invoke_call_on_closure_test.dart
new file mode 100644
index 0000000..bb08c37
--- /dev/null
+++ b/tests/lib/mirrors/invoke_call_on_closure_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2014, 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 test.invoke_call_on_closure;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  get fakeFunctionCall => new FakeFunctionCall();
+  get fakeFunctionNSM => new FakeFunctionNSM();
+  get closure => (x, y) => '2 $this $x $y';
+  get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w';
+  get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w';
+  tearOff(x, y) => '22 $this $x $y';
+  tearOffOpt(x, y, [z, w]) => '33 $this $x $y $z $w';
+  tearOffNamed(x, y, {z, w}) => '44 $this $x $y $z $w';
+
+  noSuchMethod(msg) => 'DNU';
+
+  toString() => 'C';
+}
+
+main() {
+  var c = new C();
+  InstanceMirror im;
+
+  im = reflect(c.fakeFunctionCall);
+  Expect.equals('1 5 6', im.invoke(#call, [5, 6]).reflectee);
+
+  im = reflect(c.fakeFunctionNSM);
+  Expect.equals('7, 8', im.invoke(#call, [7, 8]).reflectee);
+
+  im = reflect(c.closure);
+  Expect.equals('2 C 9 10', im.invoke(#call, [9, 10]).reflectee);
+
+  im = reflect(c.closureOpt);
+  Expect.equals('3 C 11 12 13 null', im.invoke(#call, [11, 12, 13]).reflectee);
+
+  im = reflect(c.closureNamed);
+  Expect.equals(
+      '4 C 14 15 null 16', im.invoke(#call, [14, 15], {#w: 16}).reflectee);
+
+  im = reflect(c.tearOff);
+  Expect.equals('22 C 9 10', im.invoke(#call, [9, 10]).reflectee);
+
+  im = reflect(c.tearOffOpt);
+  Expect.equals('33 C 11 12 13 null', im.invoke(#call, [11, 12, 13]).reflectee);
+
+  im = reflect(c.tearOffNamed);
+  Expect.equals(
+      '44 C 14 15 null 16', im.invoke(#call, [14, 15], {#w: 16}).reflectee);
+}
diff --git a/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart b/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart
new file mode 100644
index 0000000..f1bbc5b
--- /dev/null
+++ b/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_call_through_getter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  get fakeFunctionCall => new FakeFunctionCall();
+  get fakeFunctionNSM => new FakeFunctionNSM();
+  get closure => (x, y) => '2 $this $x $y';
+  get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w';
+  get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w';
+  get notAClosure => 'Not a closure';
+  noSuchMethod(msg) => 'DNU';
+
+  toString() => 'C';
+}
+
+testInstanceBase() {
+  dynamic c = new C();
+
+  Expect.equals('1 5 6', c.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', c.fakeFunctionNSM(7, 8));
+  Expect.equals('2 C 9 10', c.closure(9, 10));
+  Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13));
+  Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16));
+  Expect.equals('DNU', c.doesNotExist(17, 18));
+  Expect.throwsNoSuchMethodError(() => c.closure('wrong arity'));
+  Expect.throwsNoSuchMethodError(() => c.notAClosure());
+}
+
+testInstanceReflective() {
+  InstanceMirror im = reflect(new C());
+
+  Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 C 14 15 null 16', //                                       //# named: ok
+                im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //   //# named: continued
+  Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee);
+  Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity']));
+  Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, []));
+}
+
+class D {
+  static get fakeFunctionCall => new FakeFunctionCall();
+  static get fakeFunctionNSM => new FakeFunctionNSM();
+  static get closure => (x, y) => '2 $x $y';
+  static get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w';
+  static get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w';
+  static get notAClosure => 'Not a closure';
+}
+
+testClassBase() {
+  Expect.equals('1 5 6', D.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', D.fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', D.closure(9, 10));
+  Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16));
+  Expect.throwsNoSuchMethodError(() => D.closure('wrong arity'));
+}
+
+testClassReflective() {
+  ClassMirror cm = reflectClass(D);
+
+  Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                        //# named: continued
+                cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //  //# named: continued
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity']));
+}
+
+get fakeFunctionCall => new FakeFunctionCall();
+get fakeFunctionNSM => new FakeFunctionNSM();
+get closure => (x, y) => '2 $x $y';
+get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w';
+get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w';
+get notAClosure => 'Not a closure';
+
+testLibraryBase() {
+  Expect.equals('1 5 6', fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', closure(9, 10));
+  Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16));
+  Expect.throwsNoSuchMethodError(() => closure('wrong arity'));
+}
+
+testLibraryReflective() {
+  LibraryMirror lm = reflectClass(D).owner as LibraryMirror;
+
+  Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                       //# named: continued
+                lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued
+  Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity']));
+}
+
+main() {
+  // Access the getters/closures at the base level in this variant.
+  testInstanceBase();
+  testInstanceReflective();
+  testClassBase();
+  testClassReflective();
+  testLibraryBase();
+  testLibraryReflective();
+}
diff --git a/tests/lib/mirrors/invoke_call_through_getter_test.dart b/tests/lib/mirrors/invoke_call_through_getter_test.dart
new file mode 100644
index 0000000..57ff6dd
--- /dev/null
+++ b/tests/lib/mirrors/invoke_call_through_getter_test.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_call_through_getter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  get fakeFunctionCall => new FakeFunctionCall();
+  get fakeFunctionNSM => new FakeFunctionNSM();
+  get closure => (x, y) => '2 $this $x $y';
+  get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w';
+  get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w';
+  get notAClosure => 'Not a closure';
+  noSuchMethod(msg) => 'DNU';
+
+  toString() => 'C';
+}
+
+testInstanceBase() {
+  dynamic c = new C();
+
+  Expect.equals('1 5 6', c.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', c.fakeFunctionNSM(7, 8));
+  Expect.equals('2 C 9 10', c.closure(9, 10));
+  Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13));
+  Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16));
+  Expect.equals('DNU', c.doesNotExist(17, 18));
+  Expect.throwsNoSuchMethodError(() => c.closure('wrong arity'));
+  Expect.throwsNoSuchMethodError(() => c.notAClosure());
+}
+
+testInstanceReflective() {
+  InstanceMirror im = reflect(new C());
+
+  Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 C 14 15 null 16', //                                       //# named: ok
+                im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //   //# named: continued
+  Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee);
+  Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity']));
+  Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, []));
+}
+
+class D {
+  static get fakeFunctionCall => new FakeFunctionCall();
+  static get fakeFunctionNSM => new FakeFunctionNSM();
+  static get closure => (x, y) => '2 $x $y';
+  static get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w';
+  static get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w';
+  static get notAClosure => 'Not a closure';
+}
+
+testClassBase() {
+  Expect.equals('1 5 6', D.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', D.fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', D.closure(9, 10));
+  Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16));
+  Expect.throwsNoSuchMethodError(() => D.closure('wrong arity'));
+}
+
+testClassReflective() {
+  ClassMirror cm = reflectClass(D);
+
+  Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                        //# named: continued
+                cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //  //# named: continued
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity']));
+}
+
+get fakeFunctionCall => new FakeFunctionCall();
+get fakeFunctionNSM => new FakeFunctionNSM();
+get closure => (x, y) => '2 $x $y';
+get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w';
+get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w';
+get notAClosure => 'Not a closure';
+
+testLibraryBase() {
+  Expect.equals('1 5 6', fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', closure(9, 10));
+  Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16));
+  Expect.throwsNoSuchMethodError(() => closure('wrong arity'));
+}
+
+testLibraryReflective() {
+  LibraryMirror lm = reflectClass(D).owner as LibraryMirror;
+
+  Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                       //# named: continued
+                lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued
+  Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity']));
+}
+
+main() {
+  // Do not access the getters/closures at the base level in this variant.
+  //testInstanceBase();
+  testInstanceReflective();
+  //testClassBase();
+  testClassReflective();
+  //testLibraryBase();
+  testLibraryReflective();
+}
diff --git a/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart b/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart
new file mode 100644
index 0000000..2504ea6
--- /dev/null
+++ b/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2014, 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 test.invoke_call_through_implicit_getter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  var fakeFunctionCall = new FakeFunctionCall();
+  var fakeFunctionNSM = new FakeFunctionNSM();
+  var closure; // = (x, y) => '2 $this $x $y';
+  var closureOpt; // = (x, y, [z, w]) => '3 $this $x $y $z $w';
+  var closureNamed; // = (x, y, {z, w}) => '4 $this $x $y $z $w';
+  var notAClosure = 'Not a closure';
+  noSuchMethod(msg) => 'DNU';
+
+  C() {
+    closure = (x, y) => '2 $this $x $y';
+    closureOpt = (x, y, [z, w]) => '3 $this $x $y $z $w';
+    closureNamed = (x, y, {z, w}) => '4 $this $x $y $z $w';
+  }
+
+  toString() => 'C';
+}
+
+testInstanceBase() {
+  dynamic c = new C();
+
+  Expect.equals('1 5 6', c.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', c.fakeFunctionNSM(7, 8));
+  Expect.equals('2 C 9 10', c.closure(9, 10));
+  Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13));
+  Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16));
+  Expect.equals('DNU', c.doesNotExist(17, 18));
+  Expect.throwsNoSuchMethodError(() => c.closure('wrong arity'));
+  Expect.throwsNoSuchMethodError(() => c.notAClosure());
+}
+
+testInstanceReflective() {
+  InstanceMirror im = reflect(new C());
+
+  Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 C 14 15 null 16', //                                       //# named: ok
+                im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //   //# named: continued
+  Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee);
+  Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity']));
+  Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, []));
+}
+
+class D {
+  static dynamic fakeFunctionCall = new FakeFunctionCall();
+  static dynamic fakeFunctionNSM = new FakeFunctionNSM();
+  static var closure = (x, y) => '2 $x $y';
+  static var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w';
+  static var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w';
+  static var notAClosure = 'Not a closure';
+}
+
+testClassBase() {
+  Expect.equals('1 5 6', D.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', D.fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', D.closure(9, 10));
+  Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16));
+}
+
+testClassReflective() {
+  ClassMirror cm = reflectClass(D);
+
+  Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                        //# named: continued
+                cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); //  //# named: continued
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity']));
+}
+
+var fakeFunctionCall = new FakeFunctionCall();
+dynamic fakeFunctionNSM = new FakeFunctionNSM();
+var closure = (x, y) => '2 $x $y';
+var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w';
+var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w';
+var notAClosure = 'Not a closure';
+
+testLibraryBase() {
+  Expect.equals('1 5 6', fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', closure(9, 10));
+  Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16));
+}
+
+testLibraryReflective() {
+  LibraryMirror lm = reflectClass(D).owner as LibraryMirror;
+
+  Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16', //                                       //# named: continued
+                lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued
+  Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity']));
+}
+
+main() {
+  testInstanceBase();
+  testInstanceReflective();
+  testClassBase();
+  testClassReflective();
+  testLibraryBase();
+  testLibraryReflective();
+}
diff --git a/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart b/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart
new file mode 100644
index 0000000..fd0b481
--- /dev/null
+++ b/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2014, 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 test.invoke_call_through_implicit_getter;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class FakeFunctionCall {
+  call(x, y) => '1 $x $y';
+}
+
+class FakeFunctionNSM {
+  noSuchMethod(msg) => msg.positionalArguments.join(', ');
+}
+
+class C {
+  dynamic fakeFunctionCall = new FakeFunctionCall();
+  dynamic fakeFunctionNSM = new FakeFunctionNSM();
+  var closure; // = (x, y) => '2 $this $x $y';
+  var closureOpt; // = (x, y, [z, w]) => '3 $this $x $y $z $w';
+  var closureNamed; // = (x, y, {z, w}) => '4 $this $x $y $z $w';
+  dynamic notAClosure = 'Not a closure';
+  noSuchMethod(msg) => 'DNU';
+
+  C() {
+    closure = (x, y) => '2 $this $x $y';
+    closureOpt = (x, y, [z, w]) => '3 $this $x $y $z $w';
+    closureNamed = (x, y, {z, w}) => '4 $this $x $y $z $w';
+  }
+
+  toString() => 'C';
+}
+
+testInstanceBase() {
+  dynamic c = new C();
+
+  Expect.equals('1 5 6', c.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', c.fakeFunctionNSM(7, 8));
+  Expect.equals('2 C 9 10', c.closure(9, 10));
+  Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13));
+  Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16));
+  Expect.equals('DNU', c.doesNotExist(17, 18));
+  Expect.throwsNoSuchMethodError(() => c.notAClosure());
+}
+
+testInstanceReflective() {
+  InstanceMirror im = reflect(new C());
+
+  Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 C 14 15 null 16',
+      im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee);
+  Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee);
+  Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity']));
+  Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, []));
+}
+
+class D {
+  static dynamic fakeFunctionCall = new FakeFunctionCall();
+  static dynamic fakeFunctionNSM = new FakeFunctionNSM();
+  static var closure = (x, y) => '2 $x $y';
+  static var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w';
+  static var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w';
+  static var notAClosure = 'Not a closure';
+}
+
+testClassBase() {
+  Expect.equals('1 5 6', D.fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', D.fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', D.closure(9, 10));
+  Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16));
+}
+
+testClassReflective() {
+  ClassMirror cm = reflectClass(D);
+
+  Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16',
+      cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee);
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity']));
+}
+
+var fakeFunctionCall = new FakeFunctionCall();
+dynamic fakeFunctionNSM = new FakeFunctionNSM();
+var closure = (x, y) => '2 $x $y';
+var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w';
+var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w';
+var notAClosure = 'Not a closure';
+
+testLibraryBase() {
+  Expect.equals('1 5 6', fakeFunctionCall(5, 6));
+  Expect.equals('7, 8', fakeFunctionNSM(7, 8));
+  Expect.equals('2 9 10', closure(9, 10));
+  Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13));
+  Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16));
+}
+
+testLibraryReflective() {
+  LibraryMirror lm = reflectClass(D).owner as LibraryMirror;
+
+  Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee);
+  Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee);
+  Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee);
+  Expect.equals(
+      '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee);
+  Expect.equals('4 14 15 null 16',
+      lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee);
+  Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity']));
+}
+
+main() {
+  // Do not access the getters/closures at the base level in this variant.
+  //testInstanceBase();
+  testInstanceReflective();
+  //testClassBase();
+  testClassReflective();
+  //testLibraryBase();
+  testLibraryReflective();
+}
diff --git a/tests/lib/mirrors/invoke_closurization2_test.dart b/tests/lib/mirrors/invoke_closurization2_test.dart
new file mode 100644
index 0000000..2e18330
--- /dev/null
+++ b/tests/lib/mirrors/invoke_closurization2_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2014, 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 test.invoke_closurization_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  foo() => "foo";
+  bar([x]) => "bar-$x";
+  gee({named}) => "gee-$named";
+
+  // Methods that must be intercepted.
+
+  // Tear-offs we will also get without mirrors.
+  codeUnitAt(x) => "codeUnitAt-$x";
+  toUpperCase() => "toUpperCase";
+  // indexOf takes an optional argument in String.
+  indexOf(x) => "indexOf-$x";
+  // lastIndexOf matches signature from String.
+  lastIndexOf(x, [y]) => "lastIndexOf-$x,$y";
+  // splitMapJoin matches signature from String.
+  splitMapJoin(x, {onMatch, onNonMatch}) =>
+      "splitMapJoin-$x,$onMatch,$onNonMatch";
+  // Same name as intercepted, but with named argument.
+  trim({named}) => "trim-$named";
+
+  // Tear-offs we will not call directly.
+  endsWith(x) => "endsWith-$x";
+  toLowerCase() => "toLowerCase";
+  // matchAsPrefix matches signature from String.
+  matchAsPrefix(x, [y = 0]) => "matchAsPrefix-$x,$y";
+  // Matches signature from List
+  toList({growable: true}) => "toList-$growable";
+  // Same name as intercepted, but with named argument.
+  toSet({named}) => "toSet-$named";
+}
+
+// The recursive call makes inlining difficult.
+// The use of DateTime.now makes the result unpredictable.
+confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return confuse(new DateTime.now().millisecondsSinceEpoch);
+  }
+  return x;
+}
+
+main() {
+  var list = ["foo", new List(), new A()];
+
+  getAMirror() => reflect(list[confuse(2)]);
+
+  // Tear-off without mirrors.
+  var f = confuse(getAMirror().reflectee.codeUnitAt);
+  Expect.equals("codeUnitAt-42", f(42));
+  f = confuse(getAMirror().reflectee.toUpperCase);
+  Expect.equals("toUpperCase", f());
+  f = confuse(getAMirror().reflectee.indexOf);
+  Expect.equals("indexOf-499", f(499));
+  f = confuse(getAMirror().reflectee.lastIndexOf);
+  Expect.equals("lastIndexOf-FOO,BAR", f("FOO", "BAR"));
+  f = confuse(getAMirror().reflectee.splitMapJoin);
+  Expect.equals("splitMapJoin-1,2,3", f(1, onMatch: 2, onNonMatch: 3));
+  f = confuse(getAMirror().reflectee.trim);
+  Expect.equals("trim-true", f(named: true));
+
+  // Now the same thing through mirrors.
+  f = getAMirror().getField(#codeUnitAt).reflectee;
+  Expect.equals("codeUnitAt-42", f(42));
+  f = getAMirror().getField(#toUpperCase).reflectee;
+  Expect.equals("toUpperCase", f());
+  f = getAMirror().getField(#indexOf).reflectee;
+  Expect.equals("indexOf-499", f(499));
+  f = getAMirror().getField(#lastIndexOf).reflectee;
+  Expect.equals("lastIndexOf-FOO,BAR", f("FOO", "BAR"));
+  f = getAMirror().getField(#splitMapJoin).reflectee;
+  Expect.equals("splitMapJoin-1,2,3", f(1, onMatch: 2, onNonMatch: 3));
+  f = getAMirror().getField(#trim).reflectee;
+  Expect.equals("trim-true", f(named: true));
+
+  // Now the same thing through mirrors and mirror-invocation.
+  f = getAMirror().getField(#codeUnitAt);
+  Expect.equals("codeUnitAt-42", f.invoke(#call, [42], {}).reflectee);
+  f = getAMirror().getField(#toUpperCase);
+  Expect.equals("toUpperCase", f.invoke(#call, [], {}).reflectee);
+  f = getAMirror().getField(#indexOf);
+  Expect.equals("indexOf-499", f.invoke(#call, [499], {}).reflectee);
+  f = getAMirror().getField(#lastIndexOf);
+  Expect.equals(
+      "lastIndexOf-FOO,BAR", f.invoke(#call, ["FOO", "BAR"]).reflectee);
+  f = getAMirror().getField(#splitMapJoin);
+  Expect.equals("splitMapJoin-1,2,3",
+      f.invoke(#call, [1], {#onMatch: 2, #onNonMatch: 3}).reflectee);
+  f = getAMirror().getField(#trim);
+  Expect.equals("trim-true", f.invoke(#call, [], {#named: true}).reflectee);
+
+  // Tear-offs only through mirrors. (No direct selector in the code).
+  // --------
+
+  f = getAMirror().getField(#endsWith).reflectee;
+  Expect.equals("endsWith-42", f(42));
+  f = getAMirror().getField(#toLowerCase).reflectee;
+  Expect.equals("toLowerCase", f());
+  f = getAMirror().getField(#indexOf).reflectee;
+  Expect.equals("indexOf-499", f(499));
+  f = getAMirror().getField(#matchAsPrefix).reflectee;
+  Expect.equals("matchAsPrefix-FOO,BAR", f("FOO", "BAR"));
+  f = getAMirror().getField(#toList).reflectee;
+  Expect.equals("toList-1", f(growable: 1));
+  f = getAMirror().getField(#toSet).reflectee;
+  Expect.equals("toSet-true", f(named: true));
+
+  f = getAMirror().getField(#endsWith);
+  Expect.equals("endsWith-42", f.invoke(#call, [42], {}).reflectee);
+  f = getAMirror().getField(#toLowerCase);
+  Expect.equals("toLowerCase", f.invoke(#call, [], {}).reflectee);
+  f = getAMirror().getField(#indexOf);
+  Expect.equals("indexOf-499", f.invoke(#call, [499], {}).reflectee);
+  f = getAMirror().getField(#matchAsPrefix);
+  Expect.equals(
+      "matchAsPrefix-FOO,BAR", f.invoke(#call, ["FOO", "BAR"]).reflectee);
+  f = getAMirror().getField(#toList);
+  Expect.equals("toList-1", f.invoke(#call, [], {#growable: 1}).reflectee);
+  f = getAMirror().getField(#toSet);
+  Expect.equals("toSet-true", f.invoke(#call, [], {#named: true}).reflectee);
+}
diff --git a/tests/lib/mirrors/invoke_closurization_test.dart b/tests/lib/mirrors/invoke_closurization_test.dart
new file mode 100644
index 0000000..aa07913
--- /dev/null
+++ b/tests/lib/mirrors/invoke_closurization_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_closurization_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class C {
+  instanceMethod(x, y, z) => '$x+$y+$z';
+  static staticFunction(x, y, z) => '$x-$y-$z';
+}
+
+libraryFunction(x, y, z) => '$x:$y:$z';
+
+testSync() {
+  var result;
+
+  C c = new C();
+  InstanceMirror im = reflect(c);
+  result = im.getField(#instanceMethod);
+  Expect.isTrue(result.reflectee is Function, "Should be closure");
+  Expect.equals("A+B+C", result.reflectee('A', 'B', 'C'));
+
+  ClassMirror cm = reflectClass(C);
+  result = cm.getField(#staticFunction);
+  Expect.isTrue(result.reflectee is Function, "Should be closure");
+  Expect.equals("A-B-C", result.reflectee('A', 'B', 'C'));
+
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  result = lm.getField(#libraryFunction);
+  Expect.isTrue(result.reflectee is Function, "Should be closure");
+  Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
+}
+
+main() {
+  testSync();
+}
diff --git a/tests/lib/mirrors/invoke_import_test.dart b/tests/lib/mirrors/invoke_import_test.dart
new file mode 100644
index 0000000..7b41c55
--- /dev/null
+++ b/tests/lib/mirrors/invoke_import_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_import_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'other_library.dart';
+
+main() {
+  LibraryMirror thisLibrary =
+      currentMirrorSystem().findLibrary(#test.invoke_import_test);
+
+  Expect.throwsNoSuchMethodError(
+      () => thisLibrary.invoke(#topLevelMethod, []),
+      'Should not invoke imported method #topLevelMethod');
+
+  Expect.throwsNoSuchMethodError(
+      () => thisLibrary.getField(#topLevelGetter),
+      'Should not invoke imported getter #topLevelGetter');
+
+  Expect.throwsNoSuchMethodError(
+      () => thisLibrary.getField(#topLevelField),
+      'Should not invoke imported field #topLevelField');
+
+  Expect.throwsNoSuchMethodError(
+      () => thisLibrary.setField(#topLevelSetter, 23),
+      'Should not invoke imported setter #topLevelSetter');
+
+  Expect.throwsNoSuchMethodError(
+      () => thisLibrary.setField(#topLevelField, 23),
+      'Should not invoke imported field #topLevelField');
+}
diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart
new file mode 100644
index 0000000..04d547b
--- /dev/null
+++ b/tests/lib/mirrors/invoke_named_test.dart
@@ -0,0 +1,288 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_named_test;
+
+import 'dart:mirrors';
+
+import 'dart:async' show Future;
+
+import 'package:expect/expect.dart';
+import 'invoke_test.dart';
+
+// TODO(ahe): Remove this variable (http://dartbug.com/12863).
+bool isDart2js = false;
+
+class C {
+  a(a, {b: 'B', c}) => "$a-$b-$c";
+  b({a: 'A', b, c}) => "$a-$b-$c";
+  c(a, [b, c = 'C']) => "$a-$b-$c";
+  d([a, b = 'B', c = 'C']) => "$a-$b-$c";
+  e(a, b, c) => "$a-$b-$c";
+}
+
+class D {
+  static a(a, {b: 'B', c}) => "$a-$b-$c";
+  static b({a: 'A', b, c}) => "$a-$b-$c";
+  static c(a, [b, c = 'C']) => "$a-$b-$c";
+  static d([a, b = 'B', c = 'C']) => "$a-$b-$c";
+  static e(a, b, c) => "$a-$b-$c";
+}
+
+class E {
+  var field;
+  E(a, {b: 'B', c}) : this.field = "$a-$b-$c";
+  E.b({a: 'A', b, c}) : this.field = "$a-$b-$c";
+  E.c(a, [b, c = 'C']) : this.field = "$a-$b-$c";
+  E.d([a, b = 'B', c = 'C']) : this.field = "$a-$b-$c";
+  E.e(a, b, c) : this.field = "$a-$b-$c";
+}
+
+a(a, {b: 'B', c}) => "$a-$b-$c";
+b({a: 'A', b, c}) => "$a-$b-$c";
+c(a, [b, c = 'C']) => "$a-$b-$c";
+d([a, b = 'B', c = 'C']) => "$a-$b-$c";
+e(a, b, c) => "$a-$b-$c";
+
+testSyncInvoke(ObjectMirror om) {
+  InstanceMirror result;
+
+  result = om.invoke(const Symbol('a'), ['X']);
+  Expect.equals('X-B-null', result.reflectee);
+  result = om.invoke(const Symbol('a'), ['X'], {const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-null', result.reflectee);
+  result = om.invoke(const Symbol('a'), ['X'],
+      {const Symbol('c'): 'Z', const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('a'), []),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('a'), ['X', 'Y']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('a'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = om.invoke(const Symbol('b'), []);
+  Expect.equals('A-null-null', result.reflectee);
+  result = om.invoke(const Symbol('b'), [], {const Symbol('a'): 'X'});
+  Expect.equals('X-null-null', result.reflectee);
+  result = om.invoke(const Symbol('b'), [],
+      {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'});
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('b'), ['X']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = om.invoke(const Symbol('c'), ['X']);
+  Expect.equals('X-null-C', result.reflectee);
+  result = om.invoke(const Symbol('c'), ['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee);
+  result = om.invoke(const Symbol('c'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('c'), []),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('c'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = om.invoke(const Symbol('d'), []);
+  Expect.equals('null-B-C', result.reflectee);
+  result = om.invoke(const Symbol('d'), ['X']);
+  Expect.equals('X-B-C', result.reflectee);
+  result = om.invoke(const Symbol('d'), ['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee);
+  result = om.invoke(const Symbol('d'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('d'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = om.invoke(const Symbol('e'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('e'), ['X']),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('e'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => om.invoke(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+}
+
+testSyncNewInstance() {
+  ClassMirror cm = reflectClass(E);
+  InstanceMirror result;
+
+  result = cm.newInstance(Symbol.empty, ['X']);
+  Expect.equals('X-B-null', result.reflectee.field);
+  result = cm.newInstance(Symbol.empty, ['X'], {const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-null', result.reflectee.field);
+  result = cm.newInstance(
+      Symbol.empty, ['X'], {const Symbol('c'): 'Z', const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-Z', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, []),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, ['X', 'Y']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(Symbol.empty, ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = cm.newInstance(const Symbol('b'), []);
+  Expect.equals('A-null-null', result.reflectee.field);
+  result = cm.newInstance(const Symbol('b'), [], {const Symbol('a'): 'X'});
+  Expect.equals('X-null-null', result.reflectee.field);
+  result = cm.newInstance(const Symbol('b'), [],
+      {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'});
+  Expect.equals('X-Y-Z', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('b'), ['X']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm
+          .newInstance(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = cm.newInstance(const Symbol('c'), ['X']);
+  Expect.equals('X-null-C', result.reflectee.field);
+  result = cm.newInstance(const Symbol('c'), ['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee.field);
+  result = cm.newInstance(const Symbol('c'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('c'), []),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(const Symbol('c'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm
+          .newInstance(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = cm.newInstance(const Symbol('d'), []);
+  Expect.equals('null-B-C', result.reflectee.field);
+  result = cm.newInstance(const Symbol('d'), ['X']);
+  Expect.equals('X-B-C', result.reflectee.field);
+  result = cm.newInstance(const Symbol('d'), ['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee.field);
+  result = cm.newInstance(const Symbol('d'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(const Symbol('d'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm
+          .newInstance(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  result = cm.newInstance(const Symbol('e'), ['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('e'), ['X']),
+      'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(const Symbol('e'), ['X', 'Y', 'Z', 'W']),
+      'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm
+          .newInstance(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+}
+
+testSyncApply() {
+  ClosureMirror cm;
+  InstanceMirror result;
+
+  cm = reflect(a) as ClosureMirror;
+  result = cm.apply(['X']);
+  Expect.equals('X-B-null', result.reflectee);
+  result = cm.apply(['X'], {const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-null', result.reflectee);
+  result = cm.apply(['X'], {const Symbol('c'): 'Z', const Symbol('b'): 'Y'});
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply([]), 'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X', 'Y']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  cm = reflect(b) as ClosureMirror;
+  result = cm.apply([]);
+  Expect.equals('A-null-null', result.reflectee);
+  result = cm.apply([], {const Symbol('a'): 'X'});
+  Expect.equals('X-null-null', result.reflectee);
+  result = cm.apply([],
+      {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'});
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  cm = reflect(c) as ClosureMirror;
+  result = cm.apply(['X']);
+  Expect.equals('X-null-C', result.reflectee);
+  result = cm.apply(['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee);
+  result = cm.apply(['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply([]), 'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  cm = reflect(d) as ClosureMirror;
+  result = cm.apply([]);
+  Expect.equals('null-B-C', result.reflectee);
+  result = cm.apply(['X']);
+  Expect.equals('X-B-C', result.reflectee);
+  result = cm.apply(['X', 'Y']);
+  Expect.equals('X-Y-C', result.reflectee);
+  result = cm.apply(['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+
+  cm = reflect(e) as ClosureMirror;
+  result = cm.apply(['X', 'Y', 'Z']);
+  Expect.equals('X-Y-Z', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X']), 'Insufficient positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments');
+  Expect.throwsNoSuchMethodError(
+      () => cm.apply(['X'], {const Symbol('undef'): 'Y'}),
+      'Unmatched named argument');
+}
+
+main() {
+  isDart2js = true; //# 01: ok
+
+  testSyncInvoke(reflect(new C())); // InstanceMirror
+
+  if (isDart2js) return;
+
+  testSyncInvoke(reflectClass(D)); // ClassMirror
+  LibraryMirror lib = reflectClass(D).owner as LibraryMirror;
+  testSyncInvoke(lib); // LibraryMirror
+
+  testSyncNewInstance();
+
+  testSyncApply();
+}
diff --git a/tests/lib/mirrors/invoke_natives_malicious_test.dart b/tests/lib/mirrors/invoke_natives_malicious_test.dart
new file mode 100644
index 0000000..43ccb5d
--- /dev/null
+++ b/tests/lib/mirrors/invoke_natives_malicious_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, 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 test.invoke_natives;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+test(name, action) {
+  print(name);
+  Expect.throws(action, (e) => true, name);
+  print("done");
+}
+
+main() {
+  LibraryMirror dartcore = reflectClass(Object).owner as LibraryMirror;
+
+  test('List_copyFromObjectArray', () {
+    var receiver = new List(3);
+    var selector = MirrorSystem.getSymbol('_copyFromObjectArray', dartcore);
+    var src = new List(3);
+    var srcStart = 10;
+    var dstStart = 10;
+    var count = 10;
+    reflect(receiver).invoke(selector, [src, srcStart, dstStart, count]);
+  });
+}
diff --git a/tests/lib/mirrors/invoke_private_test.dart b/tests/lib/mirrors/invoke_private_test.dart
new file mode 100644
index 0000000..753dd9e
--- /dev/null
+++ b/tests/lib/mirrors/invoke_private_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_private_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class C {
+  var _field;
+  C() : this._field = 'default';
+  C._named(this._field);
+
+  get _getter => 'get $_field';
+  set _setter(v) => _field = 'set $v';
+  _method(x, y, z) => '$x+$y+$z';
+
+  static var _staticField = 'initial';
+  static get _staticGetter => 'sget $_staticField';
+  static set _staticSetter(v) => _staticField = 'sset $v';
+  static _staticFunction(x, y) => "($x,$y)";
+}
+
+var _libraryField = 'a priori';
+get _libraryGetter => 'lget $_libraryField';
+set _librarySetter(v) => _libraryField = 'lset $v';
+_libraryFunction(x, y) => '$x$y';
+
+main() {
+  var result;
+
+  // InstanceMirror.
+  C c = new C();
+  InstanceMirror im = reflect(c);
+  result = im.invoke(#_method, [2, 4, 8]);
+  Expect.equals('2+4+8', result.reflectee);
+
+  result = im.getField(#_getter);
+  Expect.equals('get default', result.reflectee);
+  result = im.getField(#_field);
+  Expect.equals('default', result.reflectee);
+
+  im.setField(#_setter, 'foo');
+  Expect.equals('set foo', c._field);
+  im.setField(#_field, 'bar');
+  Expect.equals('bar', c._field);
+
+  // ClassMirror.
+  ClassMirror cm = reflectClass(C);
+  result = cm.invoke(#_staticFunction, [3, 4]);
+  Expect.equals('(3,4)', result.reflectee);
+
+  result = cm.getField(#_staticGetter);
+  Expect.equals('sget initial', result.reflectee);
+  result = cm.getField(#_staticField);
+  Expect.equals('initial', result.reflectee);
+
+  cm.setField(#_staticSetter, 'sfoo');
+  Expect.equals('sset sfoo', C._staticField);
+  cm.setField(#_staticField, 'sbar');
+  Expect.equals('sbar', C._staticField);
+
+  result = cm.newInstance(#_named, ['my value']);
+  Expect.isTrue(result.reflectee is C);
+  Expect.equals('my value', result.reflectee._field);
+
+  // LibraryMirror.
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  result = lm.invoke(#_libraryFunction, [':', ')']);
+  Expect.equals(':)', result.reflectee);
+
+  result = lm.getField(#_libraryGetter);
+  Expect.equals('lget a priori', result.reflectee);
+  result = lm.getField(#_libraryField);
+  Expect.equals('a priori', result.reflectee);
+
+  lm.setField(#_librarySetter, 'lfoo');
+  Expect.equals('lset lfoo', _libraryField);
+  lm.setField(#_libraryField, 'lbar');
+  Expect.equals('lbar', _libraryField);
+}
diff --git a/tests/lib/mirrors/invoke_private_wrong_library_test.dart b/tests/lib/mirrors/invoke_private_wrong_library_test.dart
new file mode 100644
index 0000000..f0ded32
--- /dev/null
+++ b/tests/lib/mirrors/invoke_private_wrong_library_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+
+import 'invoke_private_test.dart' show C;
+
+main() {
+  var result;
+
+  C c = new C();
+  InstanceMirror im = reflect(c);
+  Expect.throwsNoSuchMethodError(() => im.invoke(#_method, [2, 4, 8]));
+  Expect.throwsNoSuchMethodError(() => im.getField(#_getter));
+  Expect.throwsNoSuchMethodError(() => im.getField(#_field));
+  Expect.throwsNoSuchMethodError(() => im.setField(#_setter, 'foo'));
+  Expect.throwsNoSuchMethodError(() => im.setField(#_field, 'bar'));
+
+  ClassMirror cm = reflectClass(C);
+  Expect.throwsNoSuchMethodError(() => cm.invoke(#_staticFunction, [3, 4]));
+  Expect.throwsNoSuchMethodError(() => cm.getField(#_staticGetter));
+  Expect.throwsNoSuchMethodError(() => cm.getField(#_staticField));
+  Expect.throwsNoSuchMethodError(() => cm.setField(#_staticSetter, 'sfoo'));
+  Expect.throwsNoSuchMethodError(() => cm.setField(#_staticField, 'sbar'));
+  Expect.throwsNoSuchMethodError(() => cm.newInstance(#_named, ['my value']));
+
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  Expect.throwsNoSuchMethodError(
+      () => lm.invoke(#_libraryFunction, [':', ')']));
+  Expect.throwsNoSuchMethodError(() => lm.getField(#_libraryGetter));
+  Expect.throwsNoSuchMethodError(() => lm.getField(#_libraryField));
+  Expect.throwsNoSuchMethodError(() => lm.setField(#_librarySetter, 'lfoo'));
+  Expect.throwsNoSuchMethodError(() => lm.setField(#_libraryField, 'lbar'));
+}
diff --git a/tests/lib/mirrors/invoke_test.dart b/tests/lib/mirrors/invoke_test.dart
new file mode 100644
index 0000000..fd5215f
--- /dev/null
+++ b/tests/lib/mirrors/invoke_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_test;
+
+import 'dart:mirrors';
+
+import 'dart:async' show Future;
+
+import 'package:expect/expect.dart';
+
+class C {
+  var field;
+  C() : this.field = 'default';
+  C.named(this.field);
+
+  get getter => 'get $field';
+  set setter(v) => field = 'set $v';
+  method(x, y, z) => '$x+$y+$z';
+  toString() => 'a C';
+
+  noSuchMethod(invocation) => 'DNU';
+
+  static var staticField = 'initial';
+  static get staticGetter => 'sget $staticField';
+  static set staticSetter(v) => staticField = 'sset $v';
+  static staticFunction(x, y) => "($x,$y)";
+}
+
+var libraryField = 'a priori';
+get libraryGetter => 'lget $libraryField';
+set librarySetter(v) => libraryField = 'lset $v';
+libraryFunction(x, y) => '$x$y';
+
+testSync() {
+  var result;
+
+  // InstanceMirror invoke
+  C c = new C();
+  InstanceMirror im = reflect(c);
+  result = im.invoke(const Symbol('method'), [2, 4, 8]);
+  Expect.equals('2+4+8', result.reflectee);
+  result = im.invoke(const Symbol('doesntExist'), [2, 4, 8]);
+  Expect.equals('DNU', result.reflectee);
+  result = im.invoke(const Symbol('method'), [2, 4]); // Wrong arity.
+  Expect.equals('DNU', result.reflectee);
+
+  // InstanceMirror invokeGetter
+  result = im.getField(const Symbol('getter'));
+  Expect.equals('get default', result.reflectee);
+  result = im.getField(const Symbol('field'));
+  Expect.equals('default', result.reflectee);
+  result = im.getField(const Symbol('doesntExist'));
+  Expect.equals('DNU', result.reflectee);
+
+  // InstanceMirror invokeSetter
+  result = im.setField(const Symbol('setter'), 'foo');
+  Expect.equals('foo', result.reflectee);
+  Expect.equals('set foo', c.field);
+  Expect.equals('set foo', im.getField(const Symbol('field')).reflectee);
+  result = im.setField(const Symbol('field'), 'bar');
+  Expect.equals('bar', result.reflectee);
+  Expect.equals('bar', c.field);
+  Expect.equals('bar', im.getField(const Symbol('field')).reflectee);
+  result = im.setField(const Symbol('doesntExist'), 'bar');
+  Expect.equals('bar', result.reflectee);
+
+  // ClassMirror invoke
+  ClassMirror cm = reflectClass(C);
+  result = cm.invoke(const Symbol('staticFunction'), [3, 4]);
+  Expect.equals('(3,4)', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.invoke(const Symbol('doesntExist'), [3, 4]), 'Not defined');
+  Expect.throwsNoSuchMethodError(
+      () => cm.invoke(const Symbol('staticFunction'), [3]), 'Wrong arity');
+
+  // ClassMirror invokeGetter
+  result = cm.getField(const Symbol('staticGetter'));
+  Expect.equals('sget initial', result.reflectee);
+  result = cm.getField(const Symbol('staticField'));
+  Expect.equals('initial', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.getField(const Symbol('doesntExist')), 'Not defined');
+
+  // ClassMirror invokeSetter
+  result = cm.setField(const Symbol('staticSetter'), 'sfoo');
+  Expect.equals('sfoo', result.reflectee);
+  Expect.equals('sset sfoo', C.staticField);
+  Expect.equals(
+      'sset sfoo', cm.getField(const Symbol('staticField')).reflectee);
+  result = cm.setField(const Symbol('staticField'), 'sbar');
+  Expect.equals('sbar', result.reflectee);
+  Expect.equals('sbar', C.staticField);
+  Expect.equals('sbar', cm.getField(const Symbol('staticField')).reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => cm.setField(const Symbol('doesntExist'), 'sbar'), 'Not defined');
+
+  // ClassMirror invokeConstructor
+  result = cm.newInstance(Symbol.empty, []);
+  Expect.isTrue(result.reflectee is C);
+  Expect.equals('default', result.reflectee.field);
+  result = cm.newInstance(const Symbol('named'), ['my value']);
+  Expect.isTrue(result.reflectee is C);
+  Expect.equals('my value', result.reflectee.field);
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(const Symbol('doesntExist'), ['my value']),
+      'Not defined');
+  Expect.throwsNoSuchMethodError(
+      () => cm.newInstance(const Symbol('named'), []), 'Wrong arity');
+
+  // LibraryMirror invoke
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  result = lm.invoke(const Symbol('libraryFunction'), [':', ')']);
+  Expect.equals(':)', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => lm.invoke(const Symbol('doesntExist'), [':', ')']), 'Not defined');
+  Expect.throwsNoSuchMethodError(
+      () => lm.invoke(const Symbol('libraryFunction'), [':']), 'Wrong arity');
+
+  // LibraryMirror invokeGetter
+  result = lm.getField(const Symbol('libraryGetter'));
+  Expect.equals('lget a priori', result.reflectee);
+  result = lm.getField(const Symbol('libraryField'));
+  Expect.equals('a priori', result.reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => lm.getField(const Symbol('doesntExist')), 'Not defined');
+
+  // LibraryMirror invokeSetter
+  result = lm.setField(const Symbol('librarySetter'), 'lfoo');
+  Expect.equals('lfoo', result.reflectee);
+  Expect.equals('lset lfoo', libraryField);
+  Expect.equals(
+      'lset lfoo', lm.getField(const Symbol('libraryField')).reflectee);
+  result = lm.setField(const Symbol('libraryField'), 'lbar');
+  Expect.equals('lbar', result.reflectee);
+  Expect.equals('lbar', libraryField);
+  Expect.equals('lbar', lm.getField(const Symbol('libraryField')).reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => lm.setField(const Symbol('doesntExist'), 'lbar'), 'Not defined');
+}
+
+main() {
+  testSync();
+}
diff --git a/tests/lib/mirrors/invoke_throws_test.dart b/tests/lib/mirrors/invoke_throws_test.dart
new file mode 100644
index 0000000..59f5b2f
--- /dev/null
+++ b/tests/lib/mirrors/invoke_throws_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.invoke_throws_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class MyException {}
+
+class Class {
+  Class.noException();
+  Class.generative() {
+    throw new MyException();
+  }
+  Class.redirecting() : this.generative();
+  factory Class.faktory() {
+    throw new MyException();
+  }
+  factory Class.redirectingFactory() = Class.faktory;
+
+  get getter {
+    throw new MyException();
+  }
+
+  set setter(v) {
+    throw new MyException();
+  }
+
+  method() {
+    throw new MyException();
+  }
+
+  noSuchMethod(invocation) {
+    throw new MyException();
+  }
+
+  static get staticGetter {
+    throw new MyException();
+  }
+
+  static set staticSetter(v) {
+    throw new MyException();
+  }
+
+  static staticFunction() {
+    throw new MyException();
+  }
+}
+
+get libraryGetter {
+  throw new MyException();
+}
+
+set librarySetter(v) {
+  throw new MyException();
+}
+
+libraryFunction() {
+  throw new MyException();
+}
+
+bool isMyException(e) => e is MyException;
+
+main() {
+  InstanceMirror im = reflect(new Class.noException());
+  Expect.throws(() => im.getField(#getter), isMyException);
+  Expect.throws(() => im.setField(#setter, ['arg']), isMyException);
+  Expect.throws(() => im.invoke(#method, []), isMyException);
+  Expect.throws(() => im.invoke(#triggerNoSuchMethod, []), isMyException);
+
+  ClassMirror cm = reflectClass(Class);
+  Expect.throws(() => cm.getField(#staticGetter), isMyException);
+  Expect.throws(() => cm.setField(#staticSetter, ['arg']), isMyException);
+  Expect.throws(() => cm.invoke(#staticFunction, []), isMyException);
+  Expect.throws(() => cm.newInstance(#generative, []), isMyException);
+  Expect.throws(() => cm.newInstance(#redirecting, []), isMyException);
+  Expect.throws(() => cm.newInstance(#faktory, []), isMyException);
+  Expect.throws(() => cm.newInstance(#redirectingFactory, []), isMyException);
+
+  LibraryMirror lm = reflectClass(Class).owner as LibraryMirror;
+  Expect.throws(() => lm.getField(#libraryGetter), isMyException);
+  Expect.throws(() => lm.setField(#librarySetter, ['arg']), isMyException);
+  Expect.throws(() => lm.invoke(#libraryFunction, []), isMyException);
+}
diff --git a/tests/lib/mirrors/io_html_mutual_exclusion_test.dart b/tests/lib/mirrors/io_html_mutual_exclusion_test.dart
new file mode 100644
index 0000000..087b8a6
--- /dev/null
+++ b/tests/lib/mirrors/io_html_mutual_exclusion_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.io_html_mutual_exclusion;
+
+import 'dart:mirrors';
+
+main() {
+  var libraries = currentMirrorSystem().libraries;
+  bool has_io = libraries[Uri.parse('dart:io')] != null;
+  bool has_html = libraries[Uri.parse('dart:html')] != null;
+
+  if (has_io && has_html) {
+    throw "No embedder should have both dart:io and dart:html accessible";
+  }
+}
diff --git a/tests/lib/mirrors/is_odd_test.dart b/tests/lib/mirrors/is_odd_test.dart
new file mode 100644
index 0000000..0dc1655
--- /dev/null
+++ b/tests/lib/mirrors/is_odd_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that otherwise unused intercepted methods are reified correctly.  This
+/// was a bug in dart2js.
+library test.is_odd_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.isTrue(reflect(1).getField(#isOdd).reflectee);
+  Expect.isFalse(reflect(2).getField(#isOdd).reflectee);
+}
diff --git a/tests/lib/mirrors/issue21079_test.dart b/tests/lib/mirrors/issue21079_test.dart
new file mode 100644
index 0000000..7d86954
--- /dev/null
+++ b/tests/lib/mirrors/issue21079_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test case for http://dartbug.com/21079
+import 'dart:mirrors';
+import 'dart:isolate';
+import "package:expect/expect.dart";
+
+void main() {
+  Expect.isTrue(reflectClass(MyException).superclass!.reflectedType ==
+      IsolateSpawnException);
+
+  Expect.isTrue(reflectClass(IsolateSpawnException).reflectedType ==
+      IsolateSpawnException);
+}
+
+class MyException extends IsolateSpawnException {
+  MyException() : super("Test") {}
+}
diff --git a/tests/lib/mirrors/lazy_static_test.dart b/tests/lib/mirrors/lazy_static_test.dart
new file mode 100644
index 0000000..65ac909
--- /dev/null
+++ b/tests/lib/mirrors/lazy_static_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test static members.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+
+class Foo {
+  static dynamic hello = {
+    'a': 'b',
+    'c': 'd',
+  };
+}
+
+void main() {
+  expect('Variable(s(hello) in s(Foo), static)',
+      reflectClass(Foo).declarations[#hello]);
+  var reflectee = reflectClass(Foo).getField(#hello).reflectee;
+  Expect.stringEquals('a, c', reflectee.keys.join(', '));
+  // Call the lazy getter twice as different things probably happen in the
+  // underlying implementation.
+  reflectee = reflectClass(Foo).getField(#hello).reflectee;
+  Expect.stringEquals('a, c', reflectee.keys.join(', '));
+  var value = 'fisk';
+  Foo.hello = value;
+  reflectee = reflectClass(Foo).getField(#hello).reflectee;
+  Expect.identical(value, reflectee);
+}
diff --git a/tests/lib/mirrors/libraries_test.dart b/tests/lib/mirrors/libraries_test.dart
new file mode 100644
index 0000000..80d4736
--- /dev/null
+++ b/tests/lib/mirrors/libraries_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.libraries_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  Expect.isNotNull(mirrors, 'mirrors is null');
+
+  Map<Uri, LibraryMirror> libraries = mirrors.libraries;
+  Expect.isNotNull(libraries, 'libraries is null');
+
+  Expect.isTrue(libraries.isNotEmpty);
+  LibraryMirror? mirrorsLibrary = libraries[Uri.parse('dart:mirrors')];
+  if (mirrorsLibrary == null) {
+    // In minified mode we don't preserve the URIs.
+    mirrorsLibrary = libraries.values
+        .firstWhere((LibraryMirror lm) => lm.simpleName == #dart.mirrors);
+    Uri uri = mirrorsLibrary.uri;
+    Expect.equals("https", uri.scheme);
+    Expect.equals("dartlang.org", uri.host);
+    Expect.equals("/dart2js-stripped-uri", uri.path);
+  }
+
+  ClassMirror cls = mirrorsLibrary.declarations[#LibraryMirror] as ClassMirror;
+  Expect.isNotNull(cls, 'cls is null');
+
+  Expect.equals(#dart.mirrors.LibraryMirror, cls.qualifiedName);
+  Expect.equals(reflectClass(LibraryMirror), cls);
+}
diff --git a/tests/lib/mirrors/library_declarations_test.dart b/tests/lib/mirrors/library_declarations_test.dart
new file mode 100644
index 0000000..80cd982
--- /dev/null
+++ b/tests/lib/mirrors/library_declarations_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.library_declarations_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model.dart' as declarations_model;
+
+main() {
+  LibraryMirror lm =
+      currentMirrorSystem().findLibrary(#test.declarations_model);
+
+  Expect.setEquals([
+    'Variable(s(_libraryVariable)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Variable(s(libraryVariable)'
+        ' in s(test.declarations_model), top-level, static)'
+  ], lm.declarations.values.where((dm) => dm is VariableMirror).map(stringify),
+      'variables');
+
+  // dart2js stops testing here.
+  return; // //# 01: ok
+
+  Expect.setEquals(
+      [
+        'Method(s(_libraryGetter)'
+            ' in s(test.declarations_model), private, top-level, static, getter)',
+        'Method(s(libraryGetter)'
+            ' in s(test.declarations_model), top-level, static, getter)'
+      ],
+      lm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isGetter)
+          .map(stringify),
+      'getters');
+
+  Expect.setEquals(
+      [
+        'Method(s(_librarySetter=)'
+            ' in s(test.declarations_model), private, top-level, static, setter)',
+        'Method(s(librarySetter=)'
+            ' in s(test.declarations_model), top-level, static, setter)'
+      ],
+      lm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isSetter)
+          .map(stringify),
+      'setters');
+
+  Expect.setEquals(
+      [
+        'Method(s(_libraryMethod)'
+            ' in s(test.declarations_model), private, top-level, static)',
+        'Method(s(libraryMethod)'
+            ' in s(test.declarations_model), top-level, static)'
+      ],
+      lm.declarations.values
+          .where((dm) => dm is MethodMirror && dm.isRegularMethod)
+          .map(stringify),
+      'regular methods');
+
+  Expect.setEquals([
+    'Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass)'
+        ' in s(test.declarations_model), private, top-level)'
+  ], lm.declarations.values.where((dm) => dm is ClassMirror).map(stringify),
+      'classes');
+
+  Expect.setEquals([
+    'Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass)'
+        ' in s(test.declarations_model), private, top-level)'
+  ], lm.declarations.values.where((dm) => dm is TypeMirror).map(stringify),
+      'types');
+
+  Expect.setEquals([
+    'Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Method(s(libraryGetter)'
+        ' in s(test.declarations_model), top-level, static, getter)',
+    'Method(s(libraryMethod)'
+        ' in s(test.declarations_model), top-level, static)',
+    'Method(s(librarySetter=)'
+        ' in s(test.declarations_model), top-level, static, setter)',
+    'Variable(s(libraryVariable)'
+        ' in s(test.declarations_model), top-level, static)'
+  ], lm.declarations.values.where((dm) => !dm.isPrivate).map(stringify),
+      'public');
+
+  Expect.setEquals([
+    'Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass) in s(test.declarations_model), private, top-level)',
+    'Method(s(_libraryGetter)'
+        ' in s(test.declarations_model), private, top-level, static, getter)',
+    'Method(s(_libraryMethod)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Method(s(_librarySetter=)'
+        ' in s(test.declarations_model), private, top-level, static, setter)',
+    'Variable(s(_libraryVariable)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Method(s(libraryGetter)'
+        ' in s(test.declarations_model), top-level, static, getter)',
+    'Method(s(libraryMethod) in s(test.declarations_model), top-level, static)',
+    'Method(s(librarySetter=)'
+        ' in s(test.declarations_model), top-level, static, setter)',
+    'Variable(s(libraryVariable)'
+        ' in s(test.declarations_model), top-level, static)'
+  ], lm.declarations.values.map(stringify), 'all declarations');
+}
diff --git a/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart b/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart
new file mode 100644
index 0000000..7783b74
--- /dev/null
+++ b/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library library_enumeration_deferred_loading;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import 'other_library.dart' deferred as other;
+
+main() {
+  var ms = currentMirrorSystem();
+  Expect.throws(() => ms.findLibrary(#test.other_library), (e) => true,
+      "should not be loaded yet");
+
+  asyncStart();
+  other.loadLibrary().then((_) {
+    asyncEnd();
+    LibraryMirror otherMirror = ms.findLibrary(#test.other_library);
+    Expect.isNotNull(otherMirror);
+    Expect.equals(#test.other_library, otherMirror.simpleName);
+    Expect.equals(42, other.topLevelMethod());
+  });
+}
diff --git a/tests/lib/mirrors/library_exports_hidden.dart b/tests/lib/mirrors/library_exports_hidden.dart
new file mode 100644
index 0000000..c1ea081
--- /dev/null
+++ b/tests/lib/mirrors/library_exports_hidden.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_exports_hidden;
+
+export 'library_imports_a.dart' hide somethingFromA, somethingFromBoth;
+export 'library_imports_b.dart' hide somethingFromB;
+
+var somethingFromHidden;
diff --git a/tests/lib/mirrors/library_exports_hidden_test.dart b/tests/lib/mirrors/library_exports_hidden_test.dart
new file mode 100644
index 0000000..e69fef4
--- /dev/null
+++ b/tests/lib/mirrors/library_exports_hidden_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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 test.library_exports_hidden;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_exports_hidden.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror hidden = mirrors.findLibrary(#library_exports_hidden);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals(
+      [a, b, core], hidden.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'export library_imports_a\n'
+      ' hide somethingFromA\n'
+      ' hide somethingFromBoth\n'
+      'export library_imports_b\n'
+      ' hide somethingFromB\n',
+      stringifyDependencies(hidden));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_exports_shown.dart b/tests/lib/mirrors/library_exports_shown.dart
new file mode 100644
index 0000000..524ab4c
--- /dev/null
+++ b/tests/lib/mirrors/library_exports_shown.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_exports_shown;
+
+export 'library_imports_a.dart' show somethingFromA, somethingFromBoth;
+export 'library_imports_b.dart' show somethingFromB;
+
+var somethingFromShown;
diff --git a/tests/lib/mirrors/library_exports_shown_test.dart b/tests/lib/mirrors/library_exports_shown_test.dart
new file mode 100644
index 0000000..003de2f
--- /dev/null
+++ b/tests/lib/mirrors/library_exports_shown_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, 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 test.library_exports_shown;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_exports_shown.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror shown = mirrors.findLibrary(#library_exports_shown);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals(
+      [a, b, core], shown.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'export library_imports_a\n'
+      ' show somethingFromA\n'
+      ' show somethingFromBoth\n'
+      'export library_imports_b\n'
+      ' show somethingFromB\n',
+      stringifyDependencies(shown));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_import_deferred_loading_test.dart b/tests/lib/mirrors/library_import_deferred_loading_test.dart
new file mode 100644
index 0000000..728b6b0
--- /dev/null
+++ b/tests/lib/mirrors/library_import_deferred_loading_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library library_loading_deferred_loading;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+import 'package:async_helper/async_helper.dart';
+
+import 'other_library.dart' deferred as other;
+
+main() {
+  var ms = currentMirrorSystem();
+  LibraryMirror thisLibrary = ms.findLibrary(#library_loading_deferred_loading);
+  LibraryDependencyMirror dep =
+      thisLibrary.libraryDependencies.singleWhere((d) => d.prefix == #other);
+  Expect.isNull(dep.targetLibrary, "should not be loaded yet");
+
+  asyncStart();
+  other.loadLibrary().then((_) {
+    asyncEnd();
+    Expect.isNotNull(dep.targetLibrary);
+    Expect.equals(#test.other_library, dep.targetLibrary!.simpleName);
+    Expect.equals(42, other.topLevelMethod());
+  });
+}
diff --git a/tests/lib/mirrors/library_imports_a.dart b/tests/lib/mirrors/library_imports_a.dart
new file mode 100644
index 0000000..afdc329
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_a.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2014, 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 library_imports_a;
+
+var somethingFromA;
+var somethingFromBoth;
diff --git a/tests/lib/mirrors/library_imports_b.dart b/tests/lib/mirrors/library_imports_b.dart
new file mode 100644
index 0000000..493f323
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_b.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2014, 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 library_imports_b;
+
+var somethingFromB;
+var somethingFromBoth;
diff --git a/tests/lib/mirrors/library_imports_bad_metadata_test.dart b/tests/lib/mirrors/library_imports_bad_metadata_test.dart
new file mode 100644
index 0000000..43d873b
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_bad_metadata_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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 test.library_imports_bad_metadata;
+
+@undefined // //# 01: compile-time error
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+main() {
+  LibraryMirror thisLibrary =
+      currentMirrorSystem().findLibrary(#test.library_imports_bad_metadata);
+
+  thisLibrary.libraryDependencies.forEach((dep) {
+    Expect.listEquals([], dep.metadata);
+  });
+}
diff --git a/tests/lib/mirrors/library_imports_deferred_test.dart b/tests/lib/mirrors/library_imports_deferred_test.dart
new file mode 100644
index 0000000..ab2668d
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_deferred_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.library_imports_deferred;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'dart:collection' as eagercollection;
+import 'dart:collection' deferred as lazycollection;
+
+test(MirrorSystem mirrors) {
+  LibraryMirror thisLibrary =
+      mirrors.findLibrary(#test.library_imports_deferred);
+  LibraryMirror collection = mirrors.findLibrary(#dart.collection);
+
+  var importsOfCollection = thisLibrary.libraryDependencies
+      .where((dep) => dep.targetLibrary == collection)
+      .toList();
+  Expect.equals(2, importsOfCollection.length);
+  Expect.notEquals(importsOfCollection[0].isDeferred,
+      importsOfCollection[1].isDeferred); // One deferred, one not.
+
+  // Only collection is defer-imported.
+  LibraryDependencyMirror dep =
+      thisLibrary.libraryDependencies.singleWhere((dep) => dep.isDeferred);
+  Expect.equals(collection, dep.targetLibrary);
+
+  Expect.stringEquals(
+      'import dart.collection as eagercollection\n'
+      'import dart.collection deferred as lazycollection\n'
+      ' hide loadLibrary\n'
+      'import dart.core\n'
+      'import dart.mirrors\n'
+      'import expect\n'
+      'import test.stringify\n',
+      stringifyDependencies(thisLibrary));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_imports_hidden.dart b/tests/lib/mirrors/library_imports_hidden.dart
new file mode 100644
index 0000000..deccc64
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_hidden.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_imports_hidden;
+
+import 'library_imports_a.dart' hide somethingFromA, somethingFromBoth;
+import 'library_imports_b.dart' hide somethingFromB;
+
+var somethingFromHidden;
diff --git a/tests/lib/mirrors/library_imports_hidden_test.dart b/tests/lib/mirrors/library_imports_hidden_test.dart
new file mode 100644
index 0000000..edc19e0
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_hidden_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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 test.library_imports_hidden;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_imports_hidden.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror hidden = mirrors.findLibrary(#library_imports_hidden);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals(
+      [a, b, core], hidden.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'import library_imports_a\n'
+      ' hide somethingFromA\n'
+      ' hide somethingFromBoth\n'
+      'import library_imports_b\n'
+      ' hide somethingFromB\n',
+      stringifyDependencies(hidden));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_imports_metadata.dart b/tests/lib/mirrors/library_imports_metadata.dart
new file mode 100644
index 0000000..15e0403
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_metadata.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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 library_imports_metadata;
+
+@m1
+import 'dart:mirrors' as mirrors;
+
+@m2
+@m3
+import 'dart:collection';
+
+import 'dart:async';
+
+const m1 = const Object();
+const m2 = const Object();
+const m3 = const Object();
diff --git a/tests/lib/mirrors/library_imports_metadata_test.dart b/tests/lib/mirrors/library_imports_metadata_test.dart
new file mode 100644
index 0000000..ab1c15d
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_metadata_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2014, 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 test.library_imports;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_imports_metadata.dart';
+
+main() {
+  LibraryMirror lib =
+      currentMirrorSystem().findLibrary(#library_imports_metadata);
+
+  LibraryMirror core = currentMirrorSystem().findLibrary(#dart.core);
+  LibraryMirror mirrors = currentMirrorSystem().findLibrary(#dart.mirrors);
+  LibraryMirror collection =
+      currentMirrorSystem().findLibrary(#dart.collection);
+  LibraryMirror async = currentMirrorSystem().findLibrary(#dart.async);
+
+  Expect.setEquals([core, mirrors, collection, async],
+      lib.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.async\n'
+      'import dart.collection\n'
+      'import dart.core\n'
+      'import dart.mirrors as mirrors\n',
+      stringifyDependencies(lib));
+
+  Expect.listEquals(
+      [].map(reflect).toList(),
+      lib.libraryDependencies
+          .singleWhere((dep) => dep.targetLibrary == core)
+          .metadata);
+
+  Expect.listEquals(
+      [m1].map(reflect).toList(),
+      lib.libraryDependencies
+          .singleWhere((dep) => dep.targetLibrary == mirrors)
+          .metadata);
+
+  Expect.listEquals(
+      [m2, m3].map(reflect).toList(),
+      lib.libraryDependencies
+          .singleWhere((dep) => dep.targetLibrary == collection)
+          .metadata);
+
+  Expect.listEquals(
+      [].map(reflect).toList(),
+      lib.libraryDependencies
+          .singleWhere((dep) => dep.targetLibrary == async)
+          .metadata);
+}
diff --git a/tests/lib/mirrors/library_imports_prefixed.dart b/tests/lib/mirrors/library_imports_prefixed.dart
new file mode 100644
index 0000000..ad50f42
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_prefixed.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_imports_prefixed;
+
+import 'library_imports_a.dart' as prefixa;
+import 'library_imports_b.dart' as prefixb;
+
+var somethingFromPrefixed;
diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide.dart
new file mode 100644
index 0000000..ea7c71f
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_prefixed_show_hide.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_imports_prefixed_show_hide;
+
+import 'library_imports_a.dart' as prefixa show somethingFromA;
+import 'library_imports_b.dart' as prefixb hide somethingFromB;
+
+var somethingFromPrefixed;
diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
new file mode 100644
index 0000000..a4089c0
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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 test.library_imports_prefixed_show_hide;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_imports_prefixed_show_hide.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror prefixed_show_hide =
+      mirrors.findLibrary(#library_imports_prefixed_show_hide);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals([a, b, core],
+      prefixed_show_hide.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'import library_imports_a as prefixa\n'
+      ' show somethingFromA\n'
+      'import library_imports_b as prefixb\n'
+      ' hide somethingFromB\n',
+      stringifyDependencies(prefixed_show_hide));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_imports_prefixed_test.dart b/tests/lib/mirrors/library_imports_prefixed_test.dart
new file mode 100644
index 0000000..7915fae
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_prefixed_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2014, 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 test.library_imports_prefixed;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_imports_prefixed.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror prefixed = mirrors.findLibrary(#library_imports_prefixed);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals([a, b, core],
+      prefixed.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'import library_imports_a as prefixa\n'
+      'import library_imports_b as prefixb\n',
+      stringifyDependencies(prefixed));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_imports_shown.dart b/tests/lib/mirrors/library_imports_shown.dart
new file mode 100644
index 0000000..6790902
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_shown.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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 library_imports_shown;
+
+import 'library_imports_a.dart' show somethingFromA, somethingFromBoth;
+import 'library_imports_b.dart' show somethingFromB;
+
+var somethingFromShown;
diff --git a/tests/lib/mirrors/library_imports_shown_test.dart b/tests/lib/mirrors/library_imports_shown_test.dart
new file mode 100644
index 0000000..44086e2
--- /dev/null
+++ b/tests/lib/mirrors/library_imports_shown_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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 test.library_imports_shown;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+import 'library_imports_shown.dart';
+
+test(MirrorSystem mirrors) {
+  LibraryMirror shown = mirrors.findLibrary(#library_imports_shown);
+  LibraryMirror a = mirrors.findLibrary(#library_imports_a);
+  LibraryMirror b = mirrors.findLibrary(#library_imports_b);
+  LibraryMirror core = mirrors.findLibrary(#dart.core);
+
+  Expect.setEquals(
+      [a, b, core], shown.libraryDependencies.map((dep) => dep.targetLibrary));
+
+  Expect.stringEquals(
+      'import dart.core\n'
+      'import library_imports_a\n'
+      ' show somethingFromA\n'
+      ' show somethingFromBoth\n'
+      'import library_imports_b\n'
+      ' show somethingFromB\n',
+      stringifyDependencies(shown));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/library_metadata2_lib1.dart b/tests/lib/mirrors/library_metadata2_lib1.dart
new file mode 100644
index 0000000..75149b3
--- /dev/null
+++ b/tests/lib/mirrors/library_metadata2_lib1.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@MyConst()
+library lib1;
+
+class MyConst {
+  const MyConst();
+}
diff --git a/tests/lib/mirrors/library_metadata2_lib2.dart b/tests/lib/mirrors/library_metadata2_lib2.dart
new file mode 100644
index 0000000..b8a447f
--- /dev/null
+++ b/tests/lib/mirrors/library_metadata2_lib2.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@MyConst()
+library lib2;
diff --git a/tests/lib/mirrors/library_metadata2_test.dart b/tests/lib/mirrors/library_metadata2_test.dart
new file mode 100644
index 0000000..b6fc2d9
--- /dev/null
+++ b/tests/lib/mirrors/library_metadata2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+import 'library_metadata2_lib1.dart';
+
+import 'library_metadata2_lib2.dart'; //# 01: compile-time error
+
+void main() {
+  for (var library in currentMirrorSystem().libraries.values) {
+    print(library.metadata); // Processing @MyConst() in lib2 results in a
+    // delayed compilation error here.
+  }
+}
diff --git a/tests/lib/mirrors/library_metadata_test.dart b/tests/lib/mirrors/library_metadata_test.dart
new file mode 100644
index 0000000..2a85166
--- /dev/null
+++ b/tests/lib/mirrors/library_metadata_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@string
+@symbol
+library test.library_metadata_test;
+
+import 'dart:mirrors';
+
+import 'metadata_test.dart';
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  checkMetadata(
+      mirrors.findLibrary(#test.library_metadata_test), [string, symbol]);
+  checkMetadata(mirrors.findLibrary(#test.metadata_test), []);
+}
diff --git a/tests/lib/mirrors/library_metatarget_test.dart b/tests/lib/mirrors/library_metatarget_test.dart
new file mode 100644
index 0000000..6800bab
--- /dev/null
+++ b/tests/lib/mirrors/library_metatarget_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for the combined use of metatargets and library tags.
+
+library topLib;
+
+import 'library_metatarget_test_lib.dart';
+import 'library_metatarget_test_annotations_lib.dart';
+
+import 'dart:mirrors';
+
+void main() {
+  print(new A());
+}
diff --git a/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart b/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart
new file mode 100644
index 0000000..9464fa7
--- /dev/null
+++ b/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for the combined use of metatargets and library tags.
+
+library annotations;
+
+class UsedOnlyOnLibrary {
+  const UsedOnlyOnLibrary();
+}
+
+const usedOnlyOnLibrary = const UsedOnlyOnLibrary();
+
+class Reflectable {
+  const Reflectable();
+}
+
+const Reflectable reflectable = const Reflectable();
diff --git a/tests/lib/mirrors/library_metatarget_test_lib.dart b/tests/lib/mirrors/library_metatarget_test_lib.dart
new file mode 100644
index 0000000..f8126c1
--- /dev/null
+++ b/tests/lib/mirrors/library_metatarget_test_lib.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for the combined use of metatargets and library tags.
+
+@usedOnlyOnLibrary
+library subLib;
+
+import 'library_metatarget_test_annotations_lib.dart';
+
+class A {
+  @reflectable
+  var reflectableField = 1;
+  var nonreflectableField = 2;
+}
diff --git a/tests/lib/mirrors/library_uri_io_test.dart b/tests/lib/mirrors/library_uri_io_test.dart
new file mode 100644
index 0000000..8400843
--- /dev/null
+++ b/tests/lib/mirrors/library_uri_io_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test library uri for a library read as a file.
+
+library MirrorsTest;
+
+import 'dart:io';
+import 'dart:mirrors';
+
+import 'package:async_helper/async_minitest.dart';
+
+class Class {}
+
+testLibraryUri(var value, Uri expectedUri) {
+  var valueMirror = reflect(value);
+  ClassMirror valueClass = valueMirror.type;
+  LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
+  expect(valueLibrary.uri, equals(expectedUri));
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  test("Test current library uri", () {
+    Uri uri = Uri.base.resolveUri(Platform.script);
+    testLibraryUri(new Class(), uri);
+  });
+}
diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart
new file mode 100644
index 0000000..0116005
--- /dev/null
+++ b/tests/lib/mirrors/library_uri_package_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test library uri for a library read as a package .
+
+library MirrorsTest;
+
+import 'dart:mirrors';
+import 'package:args/args.dart';
+import 'package:async_helper/async_minitest.dart';
+
+testLibraryUri(var value, Uri expectedUri) {
+  var valueMirror = reflect(value);
+  ClassMirror valueClass = valueMirror.type;
+  LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
+  Uri uri = valueLibrary.uri;
+  if (uri.scheme != "https" ||
+      uri.host != "dartlang.org" ||
+      uri.path != "/dart2js-stripped-uri") {
+    expect(uri, equals(expectedUri));
+  }
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  test("Test package library uri", () {
+    testLibraryUri(
+        new ArgParser(), Uri.parse('package:args/src/arg_parser.dart'));
+  });
+}
diff --git a/tests/lib/mirrors/library_with_annotated_declaration.dart b/tests/lib/mirrors/library_with_annotated_declaration.dart
new file mode 100644
index 0000000..07a498b
--- /dev/null
+++ b/tests/lib/mirrors/library_with_annotated_declaration.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@metadata
+library library_with_annotated_declaration;
+
+const metadata = 'metadata';
+
+class ClassInLibraryWithAnnotatedDeclaration {}
diff --git a/tests/lib/mirrors/library_without_declaration.dart b/tests/lib/mirrors/library_without_declaration.dart
new file mode 100644
index 0000000..d9e1fe4
--- /dev/null
+++ b/tests/lib/mirrors/library_without_declaration.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// NO LIBRARY DECLARATION
+
+class ClassInLibraryWithoutDeclaration {}
diff --git a/tests/lib/mirrors/list_constructor_test.dart b/tests/lib/mirrors/list_constructor_test.dart
new file mode 100644
index 0000000..16f3c45
--- /dev/null
+++ b/tests/lib/mirrors/list_constructor_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import 'dart:mirrors';
+
+main() {
+  var cls = reflectClass(List);
+  Expect.throwsArgumentError(() => cls.newInstance(Symbol.empty, [null]));
+
+  var list = cls.newInstance(Symbol.empty, [42]).reflectee;
+  // Check that the list is fixed.
+  Expect.equals(42, list.length);
+  Expect.throwsUnsupportedError(() => list.add(2));
+  list[0] = 1;
+  Expect.equals(1, list[0]);
+
+  testGrowableList(); //# 01: ok
+}
+
+testGrowableList() {
+  var cls = reflectClass(List);
+  var list = cls.newInstance(Symbol.empty, []).reflectee;
+  // Check that the list is growable.
+  Expect.equals(0, list.length);
+  list.add(42);
+  Expect.equals(1, list.length);
+}
diff --git a/tests/lib/mirrors/load_library_test.dart b/tests/lib/mirrors/load_library_test.dart
new file mode 100644
index 0000000..39af8d2
--- /dev/null
+++ b/tests/lib/mirrors/load_library_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library load_library;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import 'other_library.dart' deferred as other;
+
+main() {
+  var ms = currentMirrorSystem();
+  LibraryMirror thisLibrary = ms.findLibrary(#load_library);
+  var dep =
+      thisLibrary.libraryDependencies.singleWhere((d) => d.prefix == #other);
+  Expect.isNull(dep.targetLibrary, "should not be loaded yet");
+
+  asyncStart();
+  dep.loadLibrary().then((_) {
+    asyncEnd();
+    Expect.isNotNull(dep.targetLibrary);
+    Expect.equals(#test.other_library, dep.targetLibrary!.simpleName);
+    Expect.equals(42, other.topLevelMethod());
+  });
+}
diff --git a/tests/lib/mirrors/local_function_is_static_test.dart b/tests/lib/mirrors/local_function_is_static_test.dart
new file mode 100644
index 0000000..131fb75
--- /dev/null
+++ b/tests/lib/mirrors/local_function_is_static_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, 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 test.local_function_is_static;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+topLevel() => 1;
+topLevelLocal() => () => 2;
+
+class C {
+  static klass() => 3;
+  static klassLocal() => () => 4;
+  instance() => 5;
+  instanceLocal() => () => 6;
+}
+
+main() {
+  var f = topLevel;
+  Expect.equals(1, f());
+  Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic);
+
+  f = topLevelLocal();
+  Expect.equals(2, f());
+  Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic);
+
+  f = C.klass;
+  Expect.equals(3, f());
+  Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic);
+
+  f = C.klassLocal();
+  Expect.equals(4, f());
+  Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic);
+
+  f = new C().instance;
+  Expect.equals(5, f());
+  Expect.isFalse((reflect(f) as ClosureMirror).function.isStatic);
+
+  f = new C().instanceLocal();
+  Expect.equals(6, f());
+  Expect.isFalse((reflect(f) as ClosureMirror).function.isStatic);
+}
diff --git a/tests/lib/mirrors/local_isolate_test.dart b/tests/lib/mirrors/local_isolate_test.dart
new file mode 100644
index 0000000..e619812
--- /dev/null
+++ b/tests/lib/mirrors/local_isolate_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the local IsolateMirror.
+
+library test.local_isolate_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Foo {}
+
+void main() {
+  LibraryMirror rootLibrary = reflectClass(Foo).owner as LibraryMirror;
+  IsolateMirror isolate = currentMirrorSystem().isolate;
+  Expect.isTrue(isolate.debugName is String);
+  Expect.isTrue(isolate.isCurrent);
+  Expect.equals(rootLibrary, isolate.rootLibrary);
+}
diff --git a/tests/lib/mirrors/metadata_allowed_values_import.dart b/tests/lib/mirrors/metadata_allowed_values_import.dart
new file mode 100644
index 0000000..67df4e2
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_import.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Imported {
+  const Imported();
+  const Imported.named();
+  static const CONSTANT = 0;
+}
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
new file mode 100644
index 0000000..3204730
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.metadata_allowed_values;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'metadata_allowed_values_import.dart'; // Unprefixed.
+import 'metadata_allowed_values_import.dart' as prefix;
+
+@A // //# 01: compile-time error
+class A {}
+
+@B.CONSTANT
+class B {
+  static const CONSTANT = 3;
+}
+
+@C(3)
+class C {
+  final field;
+  const C(this.field);
+}
+
+@D.named(4)
+class D {
+  final field;
+  const D.named(this.field);
+}
+
+@E.NOT_CONSTANT // //# 02: compile-time error
+class E {
+  static var NOT_CONSTANT = 3;
+}
+
+@F(6) // //# 03: compile-time error
+class F {
+  final field;
+  F(this.field);
+}
+
+@G.named(4) // //# 04: compile-time error
+class G {
+  final field;
+  G.named(this.field);
+}
+
+@H<int>() // //# 05: compile-time error
+class H<T> {
+  const H();
+}
+
+@I[0] // //# 06: compile-time error
+class I {}
+
+@this.toString // //# 07: compile-time error
+class J {}
+
+@super.toString // //# 08: compile-time error
+class K {}
+
+@L.func() // //# 09: compile-time error
+class L {
+  static func() => 6;
+}
+
+@Imported // //# 10: compile-time error
+class M {}
+
+@Imported()
+class N {}
+
+@Imported.named()
+class O {}
+
+@Imported.CONSTANT
+class P {}
+
+@prefix.Imported // //# 11: compile-time error
+class Q {}
+
+@prefix.Imported()
+class R {}
+
+@prefix.Imported.named()
+class S {}
+
+@prefix.Imported.CONSTANT
+class T {}
+
+@U..toString() // //# 12: compile-time error
+class U {}
+
+@V.tearOff // //# 13: compile-time error
+class V {
+  static tearOff() {}
+}
+
+topLevelTearOff() => 4;
+
+@topLevelTearOff // //# 14: compile-time error
+class W {}
+
+@TypeParameter // //# 15: compile-time error
+class X<TypeParameter> {}
+
+@TypeParameter.member // //# 16: compile-time error
+class Y<TypeParameter> {}
+
+@1 // //# 17: compile-time error
+class Z {}
+
+@3.14 // //# 18: compile-time error
+class AA {}
+
+@'string' // //# 19: compile-time error
+class BB {}
+
+@#symbol // //# 20: compile-time error
+class CC {}
+
+@['element'] // //# 21: compile-time error
+class DD {}
+
+@{'key': 'value'} // //# 22: compile-time error
+class EE {}
+
+@true // //# 23: compile-time error
+class FF {}
+
+@false // //# 24: compile-time error
+class GG {}
+
+@null // //# 25: compile-time error
+class HH {}
+
+const a = const [1, 2, 3];
+
+@a
+class II {}
+
+@a[0] // //# 26: compile-time error
+class JJ {}
+
+@kk // //# 27: compile-time error
+class KK {
+  const KK();
+}
+
+get kk => const KK();
+
+@LL(() => 42) // //# 28: compile-time error
+class LL {
+  final field;
+  const LL(this.field);
+}
+
+@MM((x) => 42) // //# 29: compile-time error
+class MM {
+  final field;
+  const MM(this.field);
+}
+
+@NN(() {}) // //# 30: compile-time error
+class NN {
+  final field;
+  const NN(this.field);
+}
+
+@OO(() { () {} }) // //# 31: compile-time error
+class OO {
+  final field;
+  const OO(this.field);
+}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+  reflectClass(A).metadata;
+  checkMetadata(reflectClass(B), [B.CONSTANT]);
+  checkMetadata(reflectClass(C), [const C(3)]);
+  checkMetadata(reflectClass(D), [const D.named(4)]);
+  reflectClass(E).metadata;
+  reflectClass(F).metadata;
+  reflectClass(G).metadata;
+  reflectClass(H).metadata;
+  reflectClass(I).metadata;
+  reflectClass(J).metadata;
+  reflectClass(K).metadata;
+  reflectClass(L).metadata;
+  reflectClass(M).metadata;
+  checkMetadata(reflectClass(N), [const Imported()]);
+  checkMetadata(reflectClass(O), [const Imported.named()]);
+  checkMetadata(reflectClass(P), [Imported.CONSTANT]);
+  reflectClass(Q).metadata;
+  checkMetadata(reflectClass(R), [const prefix.Imported()]);
+  checkMetadata(reflectClass(S), [const prefix.Imported.named()]);
+  checkMetadata(reflectClass(T), [prefix.Imported.CONSTANT]);
+  reflectClass(U).metadata;
+  reflectClass(V).metadata;
+  reflectClass(W).metadata;
+  reflectClass(X).metadata;
+  reflectClass(Y).metadata;
+  reflectClass(Z).metadata;
+  reflectClass(AA).metadata;
+  reflectClass(BB).metadata;
+  reflectClass(CC).metadata;
+  reflectClass(DD).metadata;
+  reflectClass(EE).metadata;
+  reflectClass(FF).metadata;
+  reflectClass(GG).metadata;
+  reflectClass(HH).metadata;
+  reflectClass(II).metadata;
+  reflectClass(JJ).metadata;
+  reflectClass(KK).metadata;
+  reflectClass(LL).metadata;
+  reflectClass(MM).metadata;
+  reflectClass(NN).metadata;
+  reflectClass(OO).metadata;
+}
diff --git a/tests/lib/mirrors/metadata_class_mirror_test.dart b/tests/lib/mirrors/metadata_class_mirror_test.dart
new file mode 100644
index 0000000..9dab024
--- /dev/null
+++ b/tests/lib/mirrors/metadata_class_mirror_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for http://dartbug.com/19173
+
+library lib;
+
+import 'dart:mirrors';
+
+class A {
+  const A();
+}
+
+@deprecated
+const A anA = const A();
+
+main() {
+  ClassMirror typeMirror = reflectType(A) as ClassMirror;
+  var decs = typeMirror.declarations;
+  print(decs.length);
+}
diff --git a/tests/lib/mirrors/metadata_const_map_test.dart b/tests/lib/mirrors/metadata_const_map_test.dart
new file mode 100644
index 0000000..dcf8376
--- /dev/null
+++ b/tests/lib/mirrors/metadata_const_map_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 20776. Tests that the needed classes for the
+// constant map in the metadata are generated.
+
+library lib;
+
+import 'dart:mirrors';
+
+class C {
+  final x;
+  const C(this.x);
+}
+
+@C(const {'foo': 'bar'})
+class A {}
+
+main() {
+  print(reflectClass(A).metadata);
+}
diff --git a/tests/lib/mirrors/metadata_constructed_constant_test.dart b/tests/lib/mirrors/metadata_constructed_constant_test.dart
new file mode 100644
index 0000000..16746a0
--- /dev/null
+++ b/tests/lib/mirrors/metadata_constructed_constant_test.dart
@@ -0,0 +1,27 @@
+// compile options: --emit-metadata
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.metadata_constructed_constant_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class ConstructedConstant {
+  final value;
+  const ConstructedConstant(this.value);
+  toString() => 'ConstructedConstant($value)';
+}
+
+class Foo {
+  @ConstructedConstant(StateError)
+  m() {}
+}
+
+main() {
+  var m = reflectClass(Foo).declarations[#m] as MethodMirror;
+  var value = m.metadata.single.reflectee;
+  Expect.stringEquals('ConstructedConstant($StateError)', '$value');
+}
diff --git a/tests/lib/mirrors/metadata_constructor_arguments_test.dart b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
new file mode 100644
index 0000000..bc459e9
--- /dev/null
+++ b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
@@ -0,0 +1,73 @@
+// compile options: --emit-metadata
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for Issue 13817.
+
+library test.metadata_constructor_arguments;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Tag {
+  final name;
+  const Tag({named}) : this.name = named;
+}
+
+@Tag(named: undefined) // //# 01: compile-time error
+class A {}
+
+@Tag(named: 'valid')
+class B {}
+
+@Tag(named: C.STATIC_FIELD)
+class C {
+  static const STATIC_FIELD = 3;
+}
+
+@Tag(named: D.instanceMethod()) // //# 02: compile-time error
+class D {
+  instanceMethod() {}
+}
+
+@Tag(named: instanceField) // //# 03: compile-time error
+class E {
+  var instanceField;
+}
+
+@Tag(named: F.nonConstStaticField) // //# 04: compile-time error
+class F {
+  static var nonConstStaticField = 6;
+}
+
+@Tag(named: instanceMethod) // //# 05: compile-time error
+class G {
+  instanceMethod() {}
+}
+
+@Tag(named: this) // //# 06: compile-time error
+class H {
+  instanceMethod() {}
+}
+
+@Tag(named: super) // //# 07: compile-time error
+class I {
+  instanceMethod() {}
+}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+  reflectClass(A).metadata;
+  checkMetadata(reflectClass(B), [const Tag(named: 'valid')]);
+  checkMetadata(reflectClass(C), [const Tag(named: C.STATIC_FIELD)]);
+  reflectClass(D).metadata;
+  reflectClass(E).metadata;
+  reflectClass(F).metadata;
+  reflectClass(G).metadata;
+  reflectClass(H).metadata;
+  reflectClass(I).metadata;
+}
diff --git a/tests/lib/mirrors/metadata_nested_constructor_call_test.dart b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart
new file mode 100644
index 0000000..d2edccc
--- /dev/null
+++ b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart
@@ -0,0 +1,86 @@
+// compile options: --emit-metadata
+// Copyright (c) 2014, 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.
+
+// Regression test for Issue 17141.
+
+library test.metadata_nested_constructor_call;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Box {
+  final contents;
+  const Box([this.contents]);
+}
+
+class MutableBox {
+  var contents;
+  MutableBox([this.contents]); // Not const.
+}
+
+@Box()
+class A {}
+
+@Box(const Box())
+class B {}
+
+@Box(const Box(const Box()))
+class C {}
+
+@Box(const Box(const MutableBox())) // //# 01: compile-time error
+class D {}
+
+@Box(const MutableBox(const Box())) // //# 02: compile-time error
+class E {}
+
+@Box(Box())
+class F {}
+
+@Box(Box(const Box()))
+class G {}
+
+@Box(Box(const MutableBox())) // //# 05: compile-time error
+class H {}
+
+@Box(MutableBox(const Box())) // //# 06: compile-time error
+class I {}
+
+final closure = () => 42;
+
+@Box(closure()) // //# 07: compile-time error
+class J {}
+
+@Box(closure) // //# 08: compile-time error
+class K {}
+
+function() => 42;
+
+@Box(function()) // //# 09: compile-time error
+class L {}
+
+// N.B. This is legal, but @function is not (tested by metadata_allowed_values).
+@Box(function)
+class M {}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+  closure();
+  checkMetadata(reflectClass(A), [const Box()]);
+  checkMetadata(reflectClass(B), [const Box(const Box())]);
+  checkMetadata(reflectClass(C), [const Box(const Box(const Box()))]);
+  reflectClass(D).metadata;
+  reflectClass(E).metadata;
+  reflectClass(F).metadata;
+  reflectClass(G).metadata;
+  reflectClass(H).metadata;
+  reflectClass(I).metadata;
+  reflectClass(J).metadata;
+  reflectClass(K).metadata;
+  reflectClass(L).metadata;
+  reflectClass(M).metadata;
+}
diff --git a/tests/lib/mirrors/metadata_scope_test.dart b/tests/lib/mirrors/metadata_scope_test.dart
new file mode 100644
index 0000000..8848d41
--- /dev/null
+++ b/tests/lib/mirrors/metadata_scope_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2014, 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 test.metadata_scope;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Annotation {
+  final contents;
+  const Annotation(this.contents);
+  toString() => "Annotation($contents)";
+}
+
+// Note there is no compile-time constant 'foo' in scope. In particular, A.foo
+// is not in scope here.
+@Annotation(foo) // //# 01: compile-time error
+class A<@Annotation(foo) T> {
+  @Annotation(foo)
+  static foo() {}
+
+  @Annotation(foo)
+  static bar() {}
+}
+
+@Annotation(B.foo)
+class B<@Annotation(B.foo) T> {
+  @Annotation(B.foo)
+  static foo() {}
+
+  @Annotation(B.foo)
+  static bar() {}
+}
+
+baz() {}
+
+// Note the top-level function baz is in scope here, not C.baz.
+@Annotation(baz)
+class C<@Annotation(baz) T> {
+  @Annotation(baz)
+  static baz() {}
+}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+  reflectClass(A).metadata;
+  checkMetadata(reflectClass(A).declarations[#T]!, [const Annotation(A.foo)]);
+  checkMetadata(reflectClass(A).declarations[#foo]!, [const Annotation(A.foo)]);
+  checkMetadata(reflectClass(A).declarations[#bar]!, [const Annotation(A.foo)]);
+  checkMetadata(reflectClass(B), [const Annotation(B.foo)]);
+  checkMetadata(reflectClass(B).declarations[#T]!, [const Annotation(B.foo)]);
+  checkMetadata(reflectClass(B).declarations[#foo]!, [const Annotation(B.foo)]);
+  checkMetadata(reflectClass(B).declarations[#bar]!, [const Annotation(B.foo)]);
+  // The top-level function baz, not C.baz.
+  checkMetadata(reflectClass(C), [const Annotation(baz)]);
+  // C.baz, not the top-level function baz.
+  checkMetadata(reflectClass(C).declarations[#T]!, [const Annotation(C.baz)]);
+  checkMetadata(reflectClass(C).declarations[#baz]!, [const Annotation(C.baz)]);
+}
diff --git a/tests/lib/mirrors/metadata_symbol_literal_test.dart b/tests/lib/mirrors/metadata_symbol_literal_test.dart
new file mode 100644
index 0000000..129d4cd
--- /dev/null
+++ b/tests/lib/mirrors/metadata_symbol_literal_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class T {
+  const T(this.symbol);
+  final Symbol symbol;
+}
+
+class U {
+  @T(#x)
+  int field;
+}
+
+main() {
+  final field = reflectClass(U).declarations[#field] as VariableMirror;
+  final metadata = field.metadata;
+  Expect.identical((metadata.first.reflectee as T).symbol, const Symbol('x'));
+}
diff --git a/tests/lib/mirrors/metadata_test.dart b/tests/lib/mirrors/metadata_test.dart
new file mode 100644
index 0000000..d574bc1
--- /dev/null
+++ b/tests/lib/mirrors/metadata_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.metadata_test;
+
+import 'dart:mirrors';
+
+const string = 'a metadata string';
+
+const symbol = const Symbol('symbol');
+
+const hest = 'hest';
+
+@symbol
+@string
+class MyClass {
+  @hest
+  @hest
+  @symbol
+  var x;
+  var y;
+
+  @string
+  @symbol
+  @string
+  myMethod() => 1;
+  myOtherMethod() => 2;
+}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  List metadata = mirror.metadata.map((m) => m.reflectee).toList();
+  if (metadata == null) {
+    throw 'Null metadata on $mirror';
+  }
+  int expectedLength = expectedMetadata.length;
+  int actualLength = metadata.length;
+  if (expectedLength != actualLength) {
+    throw 'Expected length = $expectedLength, but got length = $actualLength.';
+  }
+  for (int i = 0; i < expectedLength; i++) {
+    if (metadata[i] != expectedMetadata[i]) {
+      throw '${metadata[i]} is not "${expectedMetadata[i]}"'
+          ' in $mirror at index $i';
+    }
+  }
+  print(metadata);
+}
+
+@symbol
+@string
+@symbol
+main() {
+  if (MirrorSystem.getName(symbol) != 'symbol') {
+    // This happened in dart2js due to how early library metadata is
+    // computed.
+    throw 'Bad constant: $symbol';
+  }
+
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror myClassMirror = reflectClass(MyClass);
+  checkMetadata(myClassMirror, [symbol, string]);
+  LibraryMirror lib = mirrors.findLibrary(#test.metadata_test);
+  MethodMirror function = lib.declarations[#main] as MethodMirror;
+  checkMetadata(function, [symbol, string, symbol]);
+  MethodMirror method = myClassMirror.declarations[#myMethod] as MethodMirror;
+  checkMetadata(method, [string, symbol, string]);
+  method = myClassMirror.declarations[#myOtherMethod] as MethodMirror;
+  checkMetadata(method, []);
+
+  VariableMirror xMirror = myClassMirror.declarations[#x] as VariableMirror;
+  checkMetadata(xMirror, [hest, hest, symbol]);
+
+  VariableMirror yMirror = myClassMirror.declarations[#y] as VariableMirror;
+  checkMetadata(yMirror, []);
+
+  // TODO(ahe): Test local functions.
+}
diff --git a/tests/lib/mirrors/metadata_type_literal_test.dart b/tests/lib/mirrors/metadata_type_literal_test.dart
new file mode 100644
index 0000000..4d567a6
--- /dev/null
+++ b/tests/lib/mirrors/metadata_type_literal_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Foo {}
+
+class Annotation {
+  final Object bindings;
+  const Annotation(this.bindings);
+}
+
+@Annotation(Foo)
+class Annotated {}
+
+main(List<String> args) {
+  ClassMirror mirror = reflectType(Annotated) as ClassMirror;
+  Expect.equals("ClassMirror on 'Annotated'", mirror.toString());
+
+  var bindings = mirror.metadata[0].reflectee.bindings;
+  Expect.equals('Foo', bindings.toString());
+}
diff --git a/tests/lib/mirrors/method_mirror_extension_test.dart b/tests/lib/mirrors/method_mirror_extension_test.dart
new file mode 100644
index 0000000..2d68474
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_extension_test.dart
@@ -0,0 +1,126 @@
+// 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.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+library lib;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class C<T> {
+  static int tracefunc() {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+    return 10;
+  }
+}
+
+extension ext<T> on C<T> {
+  func() {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  get prop {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  set prop(value) {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  operator +(val) {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  operator -(val) {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  static int sfld = C.tracefunc();
+  static sfunc() {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  static get sprop {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+
+  static set sprop(value) {
+    try {
+      throw "producing a stack trace";
+    } catch (e, s) {
+      print(s);
+    }
+  }
+}
+
+checkExtensionKind(closure, kind, name) {
+  var closureMirror = reflect(closure) as ClosureMirror;
+  var methodMirror = closureMirror.function;
+  Expect.isTrue(methodMirror.simpleName.toString().contains(name));
+  Expect.equals(kind, methodMirror.isExtensionMember, "isExtension");
+}
+
+void testExtension(sym, mirror) {
+  if (mirror is MethodMirror) {
+    var methodMirror = mirror as MethodMirror;
+    if (MirrorSystem.getName(sym).startsWith('ext', 0)) {
+      Expect.equals(true, methodMirror.isExtensionMember, "isExtension");
+      Expect.isTrue(methodMirror.simpleName.toString().contains('ext.'));
+    } else {
+      Expect.equals(false, methodMirror.isExtensionMember, "isExtension");
+    }
+  } else if (mirror is VariableMirror) {
+    var variableMirror = mirror as VariableMirror;
+    if (MirrorSystem.getName(sym).startsWith('ext', 0)) {
+      Expect.equals(true, variableMirror.isExtensionMember, "isExtension");
+    } else {
+      Expect.equals(false, variableMirror.isExtensionMember, "isExtension");
+    }
+  }
+}
+
+main() {
+  checkExtensionKind(C.tracefunc, false, 'tracefunc');
+
+  C c = new C();
+  checkExtensionKind(c.func, true, 'ext.func');
+  checkExtensionKind(ext.sfunc, true, 'ext.sfunc');
+
+  var libraryMirror = reflectClass(C).owner as LibraryMirror;
+  libraryMirror.declarations.forEach(testExtension);
+}
diff --git a/tests/lib/mirrors/method_mirror_location_other.dart b/tests/lib/mirrors/method_mirror_location_other.dart
new file mode 100644
index 0000000..1747eb9
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_location_other.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of test.method_location;
+
+class ClassInOtherFile {
+  ClassInOtherFile();
+
+  method() {}
+}
+
+topLevelInOtherFile() {}
+
+  spaceIdentedInOtherFile() {}
+
+	tabIdentedInOtherFile() {}
diff --git a/tests/lib/mirrors/method_mirror_location_test.dart b/tests/lib/mirrors/method_mirror_location_test.dart
new file mode 100644
index 0000000..f7c3845
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_location_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2014, 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 test.method_location;
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+part 'method_mirror_location_other.dart';
+
+// We only check for a suffix of the uri because the test might be run from
+// any number of absolute paths.
+expectLocation(Mirror mirror, String uriSuffix, int line, int column) {
+  MethodMirror methodMirror;
+  if (mirror is ClosureMirror) {
+    methodMirror = mirror.function;
+  } else {
+    methodMirror = mirror as MethodMirror;
+  }
+  Expect.isTrue(methodMirror is MethodMirror);
+  final location = methodMirror.location!;
+  final uri = location.sourceUri;
+  Expect.isTrue(uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri");
+  Expect.equals(line, location.line, "line");
+  Expect.equals(column, location.column, "column");
+}
+
+class ClassInMainFile {
+
+  ClassInMainFile();
+
+  method() {}
+}
+
+void topLevelInMainFile() {}
+  spaceIdentedInMainFile() {}
+	tabIdentedInMainFile() {}
+
+class HasImplicitConstructor {}
+
+typedef bool Predicate(num n);
+
+main() {
+  localFunction(x) {
+    return x;
+  }
+
+  String mainSuffix = 'method_mirror_location_test.dart';
+  String otherSuffix = 'method_mirror_location_other.dart';
+
+  // This file.
+  expectLocation(reflectClass(ClassInMainFile).declarations[#ClassInMainFile]!,
+      mainSuffix, 31, 3);
+  expectLocation(
+      reflectClass(ClassInMainFile).declarations[#method]!, mainSuffix, 33, 3);
+  expectLocation(reflect(topLevelInMainFile), mainSuffix, 36, 1);
+  expectLocation(reflect(spaceIdentedInMainFile), mainSuffix, 37, 3);
+  expectLocation(reflect(tabIdentedInMainFile), mainSuffix, 38, 2);
+  expectLocation(reflect(localFunction), mainSuffix, 45, 3);
+
+  // Another part.
+  expectLocation(reflectClass(ClassInOtherFile).declarations[#ClassInOtherFile]!,
+      otherSuffix, 8, 3);
+  expectLocation(
+      reflectClass(ClassInOtherFile).declarations[#method]!, otherSuffix, 10, 3);
+  expectLocation(reflect(topLevelInOtherFile), otherSuffix, 13, 1);
+  expectLocation(reflect(spaceIdentedInOtherFile), otherSuffix, 15, 3);
+  expectLocation(reflect(tabIdentedInOtherFile), otherSuffix, 17, 2);
+
+  // Synthetic methods.
+  Expect.isNull(reflectClass(HasImplicitConstructor)
+      .declarations[#HasImplicitConstructor]!
+      .location);
+  Expect.isNull(
+      (reflectType(Predicate) as TypedefMirror).referent.callMethod.location);
+}
diff --git a/tests/lib/mirrors/method_mirror_name_test.dart b/tests/lib/mirrors/method_mirror_name_test.dart
new file mode 100644
index 0000000..c428da7
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_name_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+import "stringify.dart";
+
+doNothing42() {}
+
+main() {
+  // Regression test for http://www.dartbug.com/6335
+  var closureMirror = reflect(doNothing42) as ClosureMirror;
+  Expect.equals(
+      stringifySymbol(closureMirror.function.simpleName), "s(doNothing42)");
+}
diff --git a/tests/lib/mirrors/method_mirror_properties_test.dart b/tests/lib/mirrors/method_mirror_properties_test.dart
new file mode 100644
index 0000000..d2262f1
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_properties_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+doNothing42() {}
+
+int _x = 5;
+int get topGetter => _x;
+void set topSetter(x) {
+  _x = x;
+}
+
+abstract class AbstractC {
+  AbstractC();
+
+  void bar();
+  get priv;
+  set priv(value);
+}
+
+abstract class C extends AbstractC {
+  static foo() {}
+
+  C();
+  C.other();
+  C.other2() : this.other();
+
+  var _priv;
+  get priv => _priv;
+  set priv(value) => _priv = value;
+}
+
+checkKinds(method, kinds) {
+  Expect.equals(kinds[0], method.isStatic, "isStatic");
+  Expect.equals(kinds[1], method.isAbstract, "isAbstract");
+  Expect.equals(kinds[2], method.isGetter, "isGetter");
+  Expect.equals(kinds[3], method.isSetter, "isSetter");
+  Expect.equals(kinds[4], method.isConstructor, "isConstructor");
+  Expect.equals(false, method.isExtensionMember, "isExtension");
+}
+
+main() {
+  // Top level functions should be static.
+  var closureMirror = reflect(doNothing42) as ClosureMirror;
+  checkKinds(closureMirror.function, [true, false, false, false, false]);
+  var libraryMirror = reflectClass(C).owner as LibraryMirror;
+  checkKinds(libraryMirror.declarations[#topGetter],
+      [true, false, true, false, false]);
+  checkKinds(libraryMirror.declarations[const Symbol("topSetter=")],
+      [true, false, false, true, false]);
+  var classMirror;
+  classMirror = reflectClass(C);
+  checkKinds(
+      classMirror.declarations[#foo], [true, false, false, false, false]);
+  checkKinds(
+      classMirror.declarations[#priv], [false, false, true, false, false]);
+  checkKinds(classMirror.declarations[const Symbol("priv=")],
+      [false, false, false, true, false]);
+  checkKinds(classMirror.declarations[#C], [false, false, false, false, true]);
+  checkKinds(
+      classMirror.declarations[#C.other], [false, false, false, false, true]);
+  checkKinds(
+      classMirror.declarations[#C.other2], [false, false, false, false, true]);
+  classMirror = reflectClass(AbstractC);
+  checkKinds(
+      classMirror.declarations[#AbstractC], [false, false, false, false, true]);
+  checkKinds(
+      classMirror.declarations[#bar], [false, true, false, false, false]);
+  checkKinds(
+      classMirror.declarations[#priv], [false, true, true, false, false]);
+  checkKinds(classMirror.declarations[const Symbol("priv=")],
+      [false, true, false, true, false]);
+}
diff --git a/tests/lib/mirrors/method_mirror_returntype_test.dart b/tests/lib/mirrors/method_mirror_returntype_test.dart
new file mode 100644
index 0000000..f16b44f
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_returntype_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+void voidFunc() {}
+
+dynamicFunc1() {}
+
+dynamic dynamicFunc2() {}
+
+int intFunc() => 0;
+
+class C<E> {
+  E getE(E v) => v;
+}
+
+main() {
+  MethodMirror mm;
+
+  mm = (reflect(intFunc) as ClosureMirror).function;
+  Expect.equals(true, mm.returnType is TypeMirror);
+  Expect.equals(#int, mm.returnType.simpleName);
+  Expect.equals(true, mm.returnType.owner is LibraryMirror);
+
+  mm = (reflect(dynamicFunc1) as ClosureMirror).function;
+  Expect.equals(true, mm.returnType is TypeMirror);
+  Expect.equals(#dynamic, mm.returnType.simpleName);
+
+  mm = (reflect(dynamicFunc2) as ClosureMirror).function;
+  Expect.equals(true, mm.returnType is TypeMirror);
+  Expect.equals(#dynamic, mm.returnType.simpleName);
+
+  mm = (reflect(voidFunc) as ClosureMirror).function;
+  Expect.equals(true, mm.returnType is TypeMirror);
+  Expect.equals(const Symbol("void"), mm.returnType.simpleName);
+
+  ClassMirror cm = reflectClass(C);
+  mm = cm.declarations[#getE] as MethodMirror;
+  Expect.equals(true, mm.returnType is TypeMirror);
+  // The spec for this is ambiguous and needs to be updated before it is clear
+  // what has to be returned.
+  //Expect.equals("E", _n(mm.returnType.simpleName));
+  Expect.equals(true, mm.owner is ClassMirror);
+  Expect.equals(#C, mm.owner!.simpleName);
+}
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
new file mode 100755
index 0000000..45533d4
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
Binary files differ
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
new file mode 100755
index 0000000..d93615c
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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.

+

+// Note: This test relies on CRLF line endings in the source file.

+

+library line_endings.crlf;

+

+oneLineCRLF(x) => x;

+multiLineCRLF(y) {

+  return y + 1;

+}

+c

+(){

+}

diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
new file mode 100755
index 0000000..b805a75
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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.
+
+// Note: This test relies on LF line endings in the source file.
+
+library line_endings.lf;
+
+oneLineLF(x) => x;
+multiLineLF(y) {
+  return y + 1;
+}
+a
+(){
+}
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
new file mode 100644
index 0000000..735151a
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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.
+
+// Note: These tests rely on specific line endings in the source files.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+import "method_mirror_source_line_ending_lf.dart";
+import "method_mirror_source_line_ending_cr.dart";
+import "method_mirror_source_line_ending_crlf.dart";
+
+main() {
+  String sourceOf(Function f) => (reflect(f) as ClosureMirror).function.source!;
+
+  // Source does not cross line breaks.
+  Expect.stringEquals('oneLineLF(x) => x;', sourceOf(oneLineLF));
+  Expect.stringEquals('oneLineCR(x) => x;', sourceOf(oneLineCR));
+  Expect.stringEquals('oneLineCRLF(x) => x;', sourceOf(oneLineCRLF));
+
+  // Source includes line breaks.
+  Expect.stringEquals(
+      'multiLineLF(y) {\n  return y + 1;\n}', sourceOf(multiLineLF));
+  Expect.stringEquals(
+      'multiLineCR(y) {\r  return y + 1;\r}', sourceOf(multiLineCR));
+  Expect.stringEquals(
+      'multiLineCRLF(y) {\r\n  return y + 1;\r\n}', sourceOf(multiLineCRLF));
+
+  // First and last characters separated from middle by line breaks.
+  Expect.stringEquals('a\n(){\n}', sourceOf(a));
+  Expect.stringEquals('b\r(){\r}', sourceOf(b));
+  Expect.stringEquals('c\r\n(){\r\n}', sourceOf(c));
+}
diff --git a/tests/lib/mirrors/method_mirror_source_other.dart b/tests/lib/mirrors/method_mirror_source_other.dart
new file mode 100644
index 0000000..37151b6
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_other.dart
@@ -0,0 +1,8 @@
+main() {
+  print("Blah");
+}
+// This function must be on the first line.
+
+class SomethingInOther {}
+
+// Note: This test relies on LF line endings in the source file.
diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart
new file mode 100644
index 0000000..a55fbc7
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Note: This test relies on LF line endings in the source file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+import "method_mirror_source_other.dart";
+
+expectSource(Mirror mirror, String source) {
+  MethodMirror methodMirror;
+  if (mirror is ClosureMirror) {
+    methodMirror = mirror.function;
+  } else {
+    methodMirror = mirror as MethodMirror;
+  }
+  Expect.isTrue(methodMirror is MethodMirror);
+  Expect.equals(source, methodMirror.source);
+}
+
+foo1() {}
+doSomething(e) => e;
+
+int get x => 42;
+set x(value) { }
+
+class S {}
+
+class C extends S {
+
+  var _x;
+  var _y;
+
+  C(this._x, y)
+    : _y = y,
+      super();
+
+  factory C.other(num z) {}
+  factory C.other2() {}
+  factory C.other3() = C.other2;
+
+  static dynamic foo() {
+    // Happy foo.
+  }
+
+  // Some comment.
+
+  void bar() { /* Not so happy bar. */ }
+
+  num get someX =>
+    181;
+
+  set someX(v) {
+    // Discard this one.
+  }
+}
+
+
+main() {
+  // Top-level members
+  LibraryMirror lib = reflectClass(C).owner as LibraryMirror;
+  expectSource(lib.declarations[#foo1]!,
+      "foo1() {}");
+  expectSource(lib.declarations[#x]!,
+      "int get x => 42;");
+  expectSource(lib.declarations[const Symbol("x=")]!,
+      "set x(value) { }");
+
+  // Class members
+  ClassMirror cm = reflectClass(C);
+  expectSource(cm.declarations[#foo]!,
+      "static dynamic foo() {\n"
+      "    // Happy foo.\n"
+      "  }");
+  expectSource(cm.declarations[#bar]!,
+      "void bar() { /* Not so happy bar. */ }");
+  expectSource(cm.declarations[#someX]!,
+      "num get someX =>\n"
+      "    181;");
+  expectSource(cm.declarations[const Symbol("someX=")]!,
+      "set someX(v) {\n"
+      "    // Discard this one.\n"
+      "  }");
+  expectSource(cm.declarations[#C]!,
+      "C(this._x, y)\n"
+      "    : _y = y,\n"
+      "      super();");
+  expectSource(cm.declarations[#C.other]!,
+      "factory C.other(num z) {}");
+  expectSource(cm.declarations[#C.other3]!,
+      "factory C.other3() = C.other2;");
+
+  // Closures
+  expectSource(reflect((){}), "(){}");
+  expectSource(reflect((x,y,z) { return x*y*z; }), "(x,y,z) { return x*y*z; }");
+  expectSource(reflect((e) => doSomething(e)), "(e) => doSomething(e)");
+
+  namedClosure(x,y,z) => 1;
+  var a = () {};
+  expectSource(reflect(namedClosure), "namedClosure(x,y,z) => 1;");
+  expectSource(reflect(a), "() {}");
+
+  // Function at first line.
+  LibraryMirror otherLib = reflectClass(SomethingInOther).owner as LibraryMirror;
+  expectSource(otherLib.declarations[#main]!,
+"""main() {
+  print("Blah");
+}""");
+}
diff --git a/tests/lib/mirrors/mirror_in_static_init_test.dart b/tests/lib/mirrors/mirror_in_static_init_test.dart
new file mode 100644
index 0000000..4de3ef6
--- /dev/null
+++ b/tests/lib/mirrors/mirror_in_static_init_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Error in class finalization triggered via mirror in a static initializer.
+// Simply check that we do not crash.
+// This is a regression test for the VM.
+
+library mirror_in_static_init_test;
+
+import 'dart:mirrors';
+
+// This class is only loaded during initialization of `staticField`.
+abstract class C {
+  int _a;
+  // This is a syntax error on purpose.
+  C([this._a: 0]); //# 01: compile-time error
+}
+
+final int staticField = () {
+  var lib = currentMirrorSystem().findLibrary(#mirror_in_static_init_test);
+  var c = lib.declarations[#C] as ClassMirror;
+  var lst = new List.from(c.declarations.values);
+  return 42;
+}();
+
+main() {
+  return staticField;
+}
diff --git a/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart b/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart
new file mode 100644
index 0000000..2a3637b
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.mirrors_nsm_mismatch;
+
+import 'dart:mirrors';
+import 'mirrors_nsm_test.dart';
+
+topLevelMethod({missing}) {}
+
+class C {
+  C.constructor({missing});
+  factory C.redirecting({missing}) = C.constructor;
+  static staticMethod({missing}) {}
+  instanceMethod({missing}) {}
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  var libMirror = mirrors.findLibrary(#test.mirrors_nsm_mismatch);
+  expectMatchingErrors(() => libMirror.invoke(#topLevelMethod, [], {#extra: 1}),
+      () => topLevelMethod(extra: 1));
+  expectMatchingErrors(() => libMirror.invoke(#topLevelMethod, ['positional']),
+      () => topLevelMethod('positional'));
+
+  var classMirror = reflectClass(C);
+  expectMatchingErrors(
+      () => classMirror.newInstance(#constructor, [], {#extra: 1}),
+      () => new C.constructor(extra: 1));
+  expectMatchingErrors(
+      () => classMirror.newInstance(#redirecting, [], {#extra: 1}),
+      () => new C.redirecting(extra: 1));
+  expectMatchingErrors(() => classMirror.invoke(#staticMethod, [], {#extra: 1}),
+      () => C.staticMethod(extra: 1));
+  expectMatchingErrors(
+      () => classMirror.newInstance(#constructor, ['positional']),
+      () => new C.constructor('positional'));
+  expectMatchingErrors(
+      () => classMirror.newInstance(#redirecting, ['positional']),
+      () => new C.redirecting('positional'));
+  expectMatchingErrors(() => classMirror.invoke(#staticMethod, ['positional']),
+      () => C.staticMethod('positional'));
+
+  var instanceMirror = reflect(new C.constructor());
+  expectMatchingErrors(
+      () => instanceMirror.invoke(#instanceMethod, [], {#extra: 1}),
+      () => instanceMirror.reflectee.instanceMethod(extra: 1));
+  expectMatchingErrors(
+      () => instanceMirror.invoke(#instanceMethod, ['positional']),
+      () => instanceMirror.reflectee.instanceMethod('positional'));
+}
diff --git a/tests/lib/mirrors/mirrors_nsm_test.dart b/tests/lib/mirrors/mirrors_nsm_test.dart
new file mode 100644
index 0000000..d7a7729
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_nsm_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2011, 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 MirrorsTest;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+bool isNSMContainingFieldName(e, String fieldName, bool isSetter) {
+  if (e is! NoSuchMethodError) return false;
+  String needle = fieldName;
+  if (isSetter) needle += "=";
+  return "$e".contains(needle) && !"$e".contains(needle + "=");
+}
+
+final finalTopLevel = 0;
+
+class A {
+  final finalInstance = 0;
+  static final finalStatic = 0;
+}
+
+class B {
+  B(a, b);
+  factory B.fac(a, b) => new B(a, b);
+}
+
+testMessageContents() {
+  var mirrors = currentMirrorSystem();
+  var libMirror = mirrors.findLibrary(#MirrorsTest);
+  Expect.throws(() => libMirror.invoke(#foo, []),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => libMirror.getField(#foo),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => libMirror.setField(#foo, null),
+      (e) => isNSMContainingFieldName(e, "foo", true));
+  Expect.throws(() => libMirror.setField(#finalTopLevel, null),
+      (e) => isNSMContainingFieldName(e, "finalTopLevel", true));
+
+  var classMirror = reflectClass(A);
+  Expect.throws(() => classMirror.invoke(#foo, []),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => classMirror.getField(#foo),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => classMirror.setField(#foo, null),
+      (e) => isNSMContainingFieldName(e, "foo", true));
+  Expect.throws(() => classMirror.setField(#finalStatic, null),
+      (e) => isNSMContainingFieldName(e, "finalStatic", true));
+
+  var instanceMirror = reflect(new A());
+  Expect.throws(() => instanceMirror.invoke(#foo, []),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => instanceMirror.getField(#foo),
+      (e) => isNSMContainingFieldName(e, "foo", false));
+  Expect.throws(() => instanceMirror.setField(#foo, null),
+      (e) => isNSMContainingFieldName(e, "foo", true));
+  Expect.throws(() => instanceMirror.setField(#finalInstance, null),
+      (e) => isNSMContainingFieldName(e, "finalInstance", true));
+}
+
+expectMatchingErrors(reflectiveAction, baseAction) {
+  var reflectiveError, baseError;
+  try {
+    reflectiveAction();
+  } catch (e) {
+    reflectiveError = e;
+  }
+
+  try {
+    baseAction();
+  } catch (e) {
+    baseError = e;
+  }
+
+  if (baseError.toString() != reflectiveError.toString()) {
+    print("\n==Base==\n $baseError");
+    print("\n==Reflective==\n $reflectiveError");
+    throw "Expected matching errors";
+  }
+}
+
+testMatchingMessages() {
+  var mirrors = currentMirrorSystem();
+  var libMirror = mirrors.findLibrary(#MirrorsTest);
+  expectMatchingErrors(() => libMirror.invoke(#foo, []), () => foo());
+  expectMatchingErrors(() => libMirror.getField(#foo), () => foo);
+  expectMatchingErrors(() => libMirror.setField(#foo, null), () => foo = null);
+  expectMatchingErrors(() => libMirror.setField(#finalTopLevel, null),
+      () => finalTopLevel = null);
+
+  var classMirror = reflectClass(A);
+  expectMatchingErrors(() => classMirror.invoke(#foo, []), () => A.foo());
+  expectMatchingErrors(() => classMirror.getField(#foo), () => A.foo);
+  expectMatchingErrors(
+      () => classMirror.setField(#foo, null), () => A.foo = null);
+  expectMatchingErrors(() => classMirror.setField(#finalStatic, null),
+      () => A.finalStatic = null);
+  expectMatchingErrors(() => classMirror.newInstance(#constructor, [1, 2, 3]),
+      () => new A.constructor(1, 2, 3));
+
+  var instanceMirror = reflect(new A());
+  expectMatchingErrors(
+      () => instanceMirror.invoke(#foo, []), () => new A().foo());
+  expectMatchingErrors(() => instanceMirror.getField(#foo), () => new A().foo);
+  expectMatchingErrors(
+      () => instanceMirror.setField(#foo, null), () => new A().foo = null);
+  expectMatchingErrors(() => instanceMirror.setField(#finalInstance, null),
+      () => new A().finalInstance = null);
+}
+
+main() {
+  testMessageContents();
+  testMatchingMessages(); //# dart2js: ok
+}
diff --git a/tests/lib/mirrors/mirrors_reader.dart b/tests/lib/mirrors/mirrors_reader.dart
new file mode 100644
index 0000000..d3a0bde
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_reader.dart
@@ -0,0 +1,261 @@
+// Copyright (c) 2014, 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 LICESNE file.
+
+library mirrors.reader;
+
+import 'dart:mirrors';
+import 'mirrors_visitor.dart';
+
+class ReadError {
+  final String tag;
+  final exception;
+  final StackTrace? stackTrace;
+
+  ReadError(this.tag, this.exception, this.stackTrace);
+}
+
+class MirrorsReader extends MirrorsVisitor {
+  /// Produce verbose output.
+  final bool verbose;
+
+  /// Include stack trace in the error report.
+  final bool includeStackTrace;
+
+  bool fatalError = false;
+  Set<Mirror> visited = new Set<Mirror>();
+  Set<TypeMirror> declarations = new Set<TypeMirror>();
+  Set<TypeMirror> instantiations = new Set<TypeMirror>();
+  List<ReadError> errors = <ReadError>[];
+  List<Mirror> queue = <Mirror>[];
+
+  MirrorsReader({this.verbose: false, this.includeStackTrace: false});
+
+  void checkMirrorSystem(MirrorSystem mirrorSystem) {
+    visitMirrorSystem(mirrorSystem);
+    if (!errors.isEmpty) {
+      Set<String> errorMessages = new Set<String>();
+      for (ReadError error in errors) {
+        String text = 'Mirrors read error: ${error.tag}=${error.exception}';
+        if (includeStackTrace) {
+          text = '$text\n${error.stackTrace}';
+        }
+        if (errorMessages.add(text)) {
+          print(text);
+        }
+      }
+      throw 'Unexpected errors occurred reading mirrors.';
+    }
+  }
+
+  // Skip mirrors so that each mirror is only visited once.
+  bool skipMirror(Mirror mirror) {
+    if (fatalError) return true;
+    if (mirror is TypeMirror) {
+      if (mirror.isOriginalDeclaration) {
+        // Visit the declaration once.
+        return !declarations.add(mirror);
+      } else {
+        // Visit only one instantiation.
+        return !instantiations.add(mirror.originalDeclaration);
+      }
+    }
+    return !visited.add(mirror);
+  }
+
+  reportError(var receiver, String tag, var exception, StackTrace? stackTrace) {
+    String errorTag = '${receiver.runtimeType}.$tag';
+    errors.add(new ReadError(errorTag, exception, stackTrace));
+  }
+
+  visitUnsupported(var receiver, String tag, UnsupportedError? exception,
+      StackTrace stackTrace) {
+    if (verbose) print('visitUnsupported:$receiver.$tag:$exception');
+    if (!expectUnsupported(receiver, tag, exception) &&
+        !allowUnsupported(receiver, tag, exception)) {
+      reportError(receiver, tag, exception, stackTrace);
+    }
+  }
+
+  /// Override to specify that access is expected to be unsupported.
+  bool expectUnsupported(
+          var receiver, String tag, UnsupportedError? exception) =>
+      false;
+
+  /// Override to allow unsupported access.
+  bool allowUnsupported(
+          var receiver, String tag, UnsupportedError? exception) =>
+      false;
+
+  /// Evaluates the function [f]. Subclasses can override this to handle
+  /// specific exceptions.
+  dynamic evaluate(dynamic f) => f();
+
+  visit(var receiver, String tag, var value) {
+    if (value is Function) {
+      try {
+        var result = evaluate(value);
+        if (expectUnsupported(receiver, tag, null)) {
+          reportError(receiver, tag, 'Expected UnsupportedError.', null);
+        }
+        return visit(receiver, tag, result);
+      } on UnsupportedError catch (e, s) {
+        visitUnsupported(receiver, tag, e, s);
+      } on OutOfMemoryError catch (e, s) {
+        reportError(receiver, tag, e, s);
+        fatalError = true;
+      } on StackOverflowError catch (e, s) {
+        reportError(receiver, tag, e, s);
+        fatalError = true;
+      } catch (e, s) {
+        reportError(receiver, tag, e, s);
+      }
+    } else {
+      if (value is Mirror) {
+        if (!skipMirror(value)) {
+          if (verbose) print('visit:$receiver.$tag=$value');
+          bool drain = queue.isEmpty;
+          queue.add(value);
+          if (drain) {
+            while (!queue.isEmpty) {
+              visitMirror(queue.removeLast());
+            }
+          }
+        }
+      } else if (value is MirrorSystem) {
+        visitMirrorSystem(value);
+      } else if (value is SourceLocation) {
+        visitSourceLocation(value);
+      } else if (value is Iterable) {
+        // TODO(johnniwinther): Merge with `immutable_collections_test.dart`.
+        value.forEach((e) {
+          visit(receiver, tag, e);
+        });
+      } else if (value is Map) {
+        value.forEach((k, v) {
+          visit(receiver, tag, k);
+          visit(receiver, tag, v);
+        });
+      }
+    }
+    return value;
+  }
+
+  visitMirrorSystem(MirrorSystem mirrorSystem) {
+    visit(mirrorSystem, 'dynamicType', () => mirrorSystem.dynamicType);
+    visit(mirrorSystem, 'voidType', () => mirrorSystem.voidType);
+    visit(mirrorSystem, 'libraries', () => mirrorSystem.libraries);
+  }
+
+  visitClassMirror(ClassMirror mirror) {
+    super.visitClassMirror(mirror);
+    visit(mirror, 'declarations', () => mirror.declarations);
+    bool hasReflectedType =
+        visit(mirror, 'hasReflectedType', () => mirror.hasReflectedType);
+    visit(mirror, 'instanceMembers', () => mirror.instanceMembers);
+    visit(mirror, 'mixin', () => mirror.mixin);
+    if (hasReflectedType) {
+      visit(mirror, 'reflectedType', () => mirror.reflectedType);
+    }
+    visit(mirror, 'staticMembers', () => mirror.staticMembers);
+    visit(mirror, 'superclass', () => mirror.superclass);
+    visit(mirror, 'superinterfaces', () => mirror.superinterfaces);
+  }
+
+  visitDeclarationMirror(DeclarationMirror mirror) {
+    super.visitDeclarationMirror(mirror);
+    visit(mirror, 'isPrivate', () => mirror.isPrivate);
+    visit(mirror, 'isTopLevel', () => mirror.isTopLevel);
+    visit(mirror, 'location', () => mirror.location);
+    visit(mirror, 'metadata', () => mirror.metadata);
+    visit(mirror, 'owner', () => mirror.owner);
+    visit(mirror, 'qualifiedName', () => mirror.qualifiedName);
+    visit(mirror, 'simpleName', () => mirror.simpleName);
+  }
+
+  visitFunctionTypeMirror(FunctionTypeMirror mirror) {
+    super.visitFunctionTypeMirror(mirror);
+    visit(mirror, 'callMethod', () => mirror.callMethod);
+    visit(mirror, 'parameters', () => mirror.parameters);
+    visit(mirror, 'returnType', () => mirror.returnType);
+  }
+
+  visitInstanceMirror(InstanceMirror mirror) {
+    super.visitInstanceMirror(mirror);
+    bool hasReflectee =
+        visit(mirror, 'hasReflectee', () => mirror.hasReflectee);
+    if (hasReflectee) {
+      visit(mirror, 'reflectee', () => mirror.reflectee);
+    }
+    visit(mirror, 'type', () => mirror.type);
+  }
+
+  visitLibraryMirror(LibraryMirror mirror) {
+    super.visitLibraryMirror(mirror);
+    visit(mirror, 'declarations', () => mirror.declarations);
+    visit(mirror, 'uri', () => mirror.uri);
+  }
+
+  visitMethodMirror(MethodMirror mirror) {
+    super.visitMethodMirror(mirror);
+    visit(mirror, 'constructorName', () => mirror.constructorName);
+    visit(mirror, 'isAbstract', () => mirror.isAbstract);
+    visit(mirror, 'isConstConstructor', () => mirror.isConstConstructor);
+    visit(mirror, 'isConstructor', () => mirror.isConstructor);
+    visit(mirror, 'isFactoryConstructor', () => mirror.isFactoryConstructor);
+    visit(mirror, 'isGenerativeConstructor',
+        () => mirror.isGenerativeConstructor);
+    visit(mirror, 'isGetter', () => mirror.isGetter);
+    visit(mirror, 'isOperator', () => mirror.isOperator);
+    visit(mirror, 'isRedirectingConstructor',
+        () => mirror.isRedirectingConstructor);
+    visit(mirror, 'isRegularMethod', () => mirror.isRegularMethod);
+    visit(mirror, 'isSetter', () => mirror.isSetter);
+    visit(mirror, 'isStatic', () => mirror.isStatic);
+    visit(mirror, 'isSynthetic', () => mirror.isSynthetic);
+    visit(mirror, 'parameters', () => mirror.parameters);
+    visit(mirror, 'returnType', () => mirror.returnType);
+    visit(mirror, 'source', () => mirror.source);
+  }
+
+  visitParameterMirror(ParameterMirror mirror) {
+    super.visitParameterMirror(mirror);
+    bool hasDefaultValue =
+        visit(mirror, 'hasDefaultValue', () => mirror.hasDefaultValue);
+    if (hasDefaultValue) {
+      visit(mirror, 'defaultValue', () => mirror.defaultValue);
+    }
+    visit(mirror, 'isNamed', () => mirror.isNamed);
+    visit(mirror, 'isOptional', () => mirror.isOptional);
+    visit(mirror, 'type', () => mirror.type);
+  }
+
+  visitSourceLocation(SourceLocation location) {}
+
+  visitTypedefMirror(TypedefMirror mirror) {
+    super.visitTypedefMirror(mirror);
+    visit(mirror, 'referent', () => mirror.referent);
+  }
+
+  visitTypeMirror(TypeMirror mirror) {
+    super.visitTypeMirror(mirror);
+    visit(mirror, 'isOriginalDeclaration', () => mirror.isOriginalDeclaration);
+    visit(mirror, 'originalDeclaration', () => mirror.originalDeclaration);
+    visit(mirror, 'typeArguments', () => mirror.typeArguments);
+    visit(mirror, 'typeVariables', () => mirror.typeVariables);
+  }
+
+  visitTypeVariableMirror(TypeVariableMirror mirror) {
+    super.visitTypeVariableMirror(mirror);
+    visit(mirror, 'upperBound', () => mirror.upperBound);
+    visit(mirror, 'isStatic', () => mirror.isStatic);
+  }
+
+  visitVariableMirror(VariableMirror mirror) {
+    super.visitVariableMirror(mirror);
+    visit(mirror, 'isConst', () => mirror.isConst);
+    visit(mirror, 'isFinal', () => mirror.isFinal);
+    visit(mirror, 'isStatic', () => mirror.isStatic);
+    visit(mirror, 'type', () => mirror.type);
+  }
+}
diff --git a/tests/lib/mirrors/mirrors_reader_test.dart b/tests/lib/mirrors/mirrors_reader_test.dart
new file mode 100644
index 0000000..659c4e0
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_reader_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that everything reachable from a [MirrorSystem] can be accessed.
+
+library test.mirrors.reader;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'mirrors_reader.dart';
+
+class RuntimeMirrorsReader extends MirrorsReader {
+  final MirrorSystem mirrorSystem;
+  final String mirrorSystemType;
+
+  RuntimeMirrorsReader(MirrorSystem mirrorSystem,
+      {bool verbose: false, bool includeStackTrace: false})
+      : this.mirrorSystem = mirrorSystem,
+        this.mirrorSystemType = '${mirrorSystem.runtimeType}',
+        super(verbose: verbose, includeStackTrace: includeStackTrace);
+
+  visitLibraryMirror(LibraryMirror mirror) {
+    super.visitLibraryMirror(mirror);
+    Expect.equals(mirror, mirrorSystem.libraries[mirror.uri]);
+  }
+
+  visitClassMirror(ClassMirror mirror) {
+    super.visitClassMirror(mirror);
+    Expect.isNotNull(mirror.owner);
+  }
+
+  bool allowUnsupported(var receiver, String tag, UnsupportedError? exception) {
+    if (mirrorSystemType == '_MirrorSystem') {
+      // VM mirror system.
+      if (tag.endsWith('location')) {
+        return receiver is ParameterMirror;
+      }
+    } else if (mirrorSystemType == 'JsMirrorSystem') {
+      // Dart2js runtime mirror system.
+      if (tag.endsWith('.metadata')) {
+        return true; // Issue 10905.
+      }
+    }
+    return false;
+  }
+
+  bool expectUnsupported(
+      var receiver, String tag, UnsupportedError? exception) {
+    // [DeclarationMirror.location] is intentionally not supported in runtime
+    // mirrors.
+
+    if (mirrorSystemType == '_MirrorSystem') {
+      // VM mirror system.
+    } else if (mirrorSystemType == 'JsMirrorSystem') {
+      // Dart2js runtime mirror system.
+      if (receiver is DeclarationMirror && tag == 'location') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+void main([List<String> arguments = const <String>[]]) {
+  MirrorSystem mirrors = currentMirrorSystem();
+  MirrorsReader reader = new RuntimeMirrorsReader(mirrors,
+      verbose: arguments.contains('-v'),
+      includeStackTrace: arguments.contains('-s'));
+  reader.checkMirrorSystem(mirrors);
+}
diff --git a/tests/lib/mirrors/mirrors_resolve_fields_test.dart b/tests/lib/mirrors/mirrors_resolve_fields_test.dart
new file mode 100644
index 0000000..b914dda
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_resolve_fields_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not resolve instance
+// fields when a class is only instantiated through mirrors.
+
+library lib;
+
+import "package:expect/expect.dart";
+
+import 'dart:mirrors';
+
+class A {
+  static const int _STATE_INITIAL = 0;
+  int _state = _STATE_INITIAL;
+  A();
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  var classMirror = reflectClass(A);
+  var instanceMirror = classMirror.newInstance(Symbol.empty, []);
+  Expect.equals(A._STATE_INITIAL, instanceMirror.reflectee._state);
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
new file mode 100644
index 0000000..1d8a204
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -0,0 +1,247 @@
+// Copyright (c) 2011, 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 MirrorsTest;
+
+import 'dart:mirrors';
+
+import '../../light_unittest.dart';
+
+bool isDart2js = false; // TODO(ahe): Remove this field.
+
+var topLevelField;
+u(a, b, c) => {"a": a, "b": b, "c": c};
+_v(a, b) => a + b;
+
+class Class<T> {
+  Class() {
+    this.field = "default value";
+  }
+  Class.withInitialValue(this.field);
+  var field;
+
+  Class.generative(this.field);
+  Class.redirecting(y) : this.generative(y * 2);
+  factory Class.faktory(y) => new Class.withInitialValue(y * 3);
+  factory Class.redirectingFactory(y) = Class<T>.faktory;
+
+  m(a, b, c) => {"a": a, "b": b, "c": c};
+  _n(a, b) => a + b;
+  noSuchMethod(invocation) => "DNU";
+
+  static var staticField;
+  static s(a, b, c) => {"a": a, "b": b, "c": c};
+  static _t(a, b) => a + b;
+}
+
+typedef Typedef();
+
+testInvoke(mirrors) {
+  var instance = new Class();
+  var instMirror = reflect(instance);
+
+  expect(instMirror.invoke(#m, ['A', 'B', instance]).reflectee,
+      equals({"a": 'A', "b": 'B', "c": instance}));
+  expect(instMirror.invoke(#notDefined, []).reflectee, equals("DNU"));
+  expect(instMirror.invoke(#m, []).reflectee, equals("DNU")); // Wrong arity.
+
+  var classMirror = instMirror.type;
+  expect(classMirror.invoke(#s, ['A', 'B', instance]).reflectee,
+      equals({"a": 'A', "b": 'B', "c": instance}));
+  expect(() => classMirror.invoke(#notDefined, []).reflectee, throws);
+  expect(() => classMirror.invoke(#s, []).reflectee, throws); // Wrong arity.
+
+  var libMirror = classMirror.owner as LibraryMirror;
+  expect(libMirror.invoke(#u, ['A', 'B', instance]).reflectee,
+      equals({"a": 'A', "b": 'B', "c": instance}));
+  expect(() => libMirror.invoke(#notDefined, []).reflectee, throws);
+  expect(() => libMirror.invoke(#u, []).reflectee, throws); // Wrong arity.
+}
+
+/// In dart2js, lists, numbers, and other objects are treated special
+/// and their methods are invoked through a techique called interceptors.
+testIntercepted(mirrors) {
+  {
+    var instance = 1;
+    var instMirror = reflect(instance);
+
+    expect(instMirror.invoke(#toString, []).reflectee, equals('1'));
+  }
+
+  var instance = [];
+  var instMirror = reflect(instance);
+  instMirror.setField(#length, 44);
+  var resultMirror = instMirror.getField(#length);
+  expect(resultMirror.reflectee, equals(44));
+  expect(instance.length, equals(44));
+
+  expect(
+      instMirror.invoke(#toString, []).reflectee,
+      equals('[null, null, null, null, null, null, null, null, null, null,'
+          ' null, null, null, null, null, null, null, null, null, null,'
+          ' null, null, null, null, null, null, null, null, null, null,'
+          ' null, null, null, null, null, null, null, null, null, null,'
+          ' null, null, null, null]'));
+}
+
+testFieldAccess(mirrors) {
+  var instance = new Class();
+
+  var libMirror = mirrors.findLibrary(#MirrorsTest);
+  var classMirror = libMirror.declarations[#Class];
+  var instMirror = reflect(instance);
+  var fieldMirror = classMirror.declarations[#field];
+  var future;
+
+  expect(fieldMirror is VariableMirror, isTrue);
+  expect(fieldMirror.type, equals(mirrors.dynamicType));
+
+  libMirror.setField(#topLevelField, [91]);
+  expect(libMirror.getField(#topLevelField).reflectee, equals([91]));
+  expect(topLevelField, equals([91]));
+}
+
+testClosureMirrors(mirrors) {
+  // TODO(ahe): Test optional parameters (named or not).
+  var closure = (x, y, z) {
+    return x + y + z;
+  };
+
+  var mirror = reflect(closure) as ClosureMirror;
+
+  var funcMirror = (mirror.function) as MethodMirror;
+  expect(funcMirror.parameters.length, equals(3));
+
+  expect(mirror.apply([7, 8, 9]).reflectee, equals(24));
+}
+
+testInvokeConstructor(mirrors) {
+  var classMirror = reflectClass(Class);
+
+  var instanceMirror = classMirror.newInstance(Symbol.empty, []);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals("default value"));
+
+  instanceMirror = classMirror.newInstance(#withInitialValue, [45]);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(45));
+
+  instanceMirror = classMirror.newInstance(#generative, [7]);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(7));
+
+  instanceMirror = classMirror.newInstance(#redirecting, [8]);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(16));
+
+  instanceMirror = classMirror.newInstance(#faktory, [9]);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(27));
+
+  instanceMirror = classMirror.newInstance(#redirectingFactory, [10]);
+  expect(instanceMirror.reflectee is Class, equals(true));
+  expect(instanceMirror.reflectee.field, equals(30));
+}
+
+testReflectClass(mirrors) {
+  var classMirror = reflectClass(Class);
+  expect(classMirror is ClassMirror, equals(true));
+  var symbolClassMirror = reflectClass(Symbol);
+  var symbolMirror =
+      symbolClassMirror.newInstance(Symbol.empty, ['withInitialValue']);
+  var objectMirror = classMirror.newInstance(symbolMirror.reflectee, [1234]);
+  expect(objectMirror.reflectee is Class, equals(true));
+  expect(objectMirror.reflectee.field, equals(1234));
+}
+
+testNames(mirrors) {
+  var libMirror = mirrors.findLibrary(#MirrorsTest);
+  var classMirror = libMirror.declarations[#Class];
+  var typedefMirror = libMirror.declarations[#Typedef];
+  var methodMirror = libMirror.declarations[#testNames];
+  var variableMirror = classMirror.declarations[#field];
+
+  expect(libMirror.simpleName, equals(#MirrorsTest));
+  expect(libMirror.qualifiedName, equals(#MirrorsTest));
+
+  expect(classMirror.simpleName, equals(#Class));
+  expect(classMirror.qualifiedName, equals(#MirrorsTest.Class));
+
+  TypeVariableMirror typeVariable = classMirror.typeVariables.single;
+  expect(typeVariable.simpleName, equals(#T));
+  expect(
+      typeVariable.qualifiedName, equals(const Symbol('MirrorsTest.Class.T')));
+
+  if (!isDart2js) {
+    // TODO(ahe): Implement this in dart2js.
+    expect(typedefMirror.simpleName, equals(#Typedef));
+    expect(typedefMirror.qualifiedName,
+        equals(const Symbol('MirrorsTest.Typedef')));
+
+    var typedefMirrorDeNovo = reflectType(Typedef);
+    expect(typedefMirrorDeNovo.simpleName, equals(#Typedef));
+    expect(typedefMirrorDeNovo.qualifiedName,
+        equals(const Symbol('MirrorsTest.Typedef')));
+  }
+
+  expect(methodMirror.simpleName, equals(#testNames));
+  expect(methodMirror.qualifiedName,
+      equals(const Symbol('MirrorsTest.testNames')));
+
+  expect(variableMirror.simpleName, equals(#field));
+  expect(variableMirror.qualifiedName,
+      equals(const Symbol('MirrorsTest.Class.field')));
+}
+
+testLibraryUri(var value, bool check(Uri uri)) {
+  var valueMirror = reflect(value);
+  ClassMirror valueClass = valueMirror.type;
+  LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
+  Uri uri = valueLibrary.uri;
+  if (uri.scheme != "https" ||
+      uri.host != "dartlang.org" ||
+      uri.path != "/dart2js-stripped-uri") {
+    expect(check(uri), isTrue);
+  }
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  test("Test reflective method invocation", () {
+    testInvoke(mirrors);
+  });
+  test('Test intercepted objects', () {
+    testIntercepted(mirrors);
+  });
+  test("Test field access", () {
+    testFieldAccess(mirrors);
+  });
+  test("Test closure mirrors", () {
+    testClosureMirrors(mirrors);
+  });
+  test("Test invoke constructor", () {
+    testInvokeConstructor(mirrors);
+  });
+  test("Test current library uri", () {
+    testLibraryUri(
+        new Class(),
+        // TODO(floitsch): change this to "/mirrors_test.dart" when
+        // dart2js_mirrors_test.dart has been removed.
+        (Uri uri) => uri.path.endsWith('mirrors_test.dart'));
+  });
+  test("Test dart library uri", () {
+    testLibraryUri("test", (Uri uri) {
+      if (uri == Uri.parse('dart:core')) return true;
+      // TODO(floitsch): do we want to fake the interceptors to
+      // be in dart:core?
+      return (uri == Uri.parse('dart:_interceptors'));
+    });
+  });
+  test("Test simple and qualifiedName", () {
+    testNames(mirrors);
+  });
+  test("Test reflect type", () {
+    testReflectClass(mirrors);
+  });
+}
diff --git a/tests/lib/mirrors/mirrors_visitor.dart b/tests/lib/mirrors/mirrors_visitor.dart
new file mode 100644
index 0000000..a78b7ec
--- /dev/null
+++ b/tests/lib/mirrors/mirrors_visitor.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, 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 mirrors.visitor;
+
+import 'dart:mirrors';
+
+abstract class MirrorsVisitor {
+  visitMirror(Mirror mirror) {
+    if (mirror == null) return;
+
+    if (mirror is FunctionTypeMirror) {
+      visitFunctionTypeMirror(mirror);
+    } else if (mirror is ClassMirror) {
+      visitClassMirror(mirror);
+    } else if (mirror is TypedefMirror) {
+      visitTypedefMirror(mirror);
+    } else if (mirror is TypeVariableMirror) {
+      visitTypeVariableMirror(mirror);
+    } else if (mirror is TypeMirror) {
+      visitTypeMirror(mirror);
+    } else if (mirror is ParameterMirror) {
+      visitParameterMirror(mirror);
+    } else if (mirror is VariableMirror) {
+      visitVariableMirror(mirror);
+    } else if (mirror is MethodMirror) {
+      visitMethodMirror(mirror);
+    } else if (mirror is LibraryMirror) {
+      visitLibraryMirror(mirror);
+    } else if (mirror is InstanceMirror) {
+      visitInstanceMirror(mirror);
+    } else if (mirror is ObjectMirror) {
+      visitObjectMirror(mirror);
+    } else if (mirror is DeclarationMirror) {
+      visitDeclarationMirror(mirror);
+    } else {
+      throw new StateError(
+          'Unexpected mirror kind ${mirror.runtimeType}: $mirror');
+    }
+  }
+
+  visitClassMirror(ClassMirror mirror) {
+    visitObjectMirror(mirror);
+    visitTypeMirror(mirror);
+  }
+
+  visitDeclarationMirror(DeclarationMirror mirror) {}
+
+  visitFunctionTypeMirror(FunctionTypeMirror mirror) {
+    visitClassMirror(mirror);
+  }
+
+  visitInstanceMirror(InstanceMirror mirror) {
+    visitObjectMirror(mirror);
+  }
+
+  visitLibraryMirror(LibraryMirror mirror) {
+    visitObjectMirror(mirror);
+    visitDeclarationMirror(mirror);
+  }
+
+  visitMethodMirror(MethodMirror mirror) {
+    visitDeclarationMirror(mirror);
+  }
+
+  visitObjectMirror(ObjectMirror mirror) {}
+
+  visitParameterMirror(ParameterMirror mirror) {
+    visitVariableMirror(mirror);
+  }
+
+  visitTypedefMirror(TypedefMirror mirror) {
+    visitTypeMirror(mirror);
+  }
+
+  visitTypeMirror(TypeMirror mirror) {
+    visitDeclarationMirror(mirror);
+  }
+
+  visitTypeVariableMirror(TypeVariableMirror mirror) {
+    visitTypeMirror(mirror);
+  }
+
+  visitVariableMirror(VariableMirror mirror) {
+    visitDeclarationMirror(mirror);
+  }
+}
diff --git a/tests/lib/mirrors/mixin_application_test.dart b/tests/lib/mirrors/mixin_application_test.dart
new file mode 100644
index 0000000..ccefda2
--- /dev/null
+++ b/tests/lib/mirrors/mixin_application_test.dart
@@ -0,0 +1,332 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test uses the multi-test "ok" feature to create two positive tests from
+// one file. One of these tests fail on dart2js, but pass on the VM, or vice
+// versa.
+// TODO(ahe): When both implementations agree, remove the multi-test parts.
+
+library test.mixin_application_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'model.dart';
+import 'stringify.dart';
+
+class Mixin {
+  int i = 0;
+  m() {}
+}
+
+class Mixin2 {
+  int i2 = 0;
+  m2() {}
+}
+
+class MixinApplication = C with Mixin;
+class MixinApplicationA = C with Mixin, Mixin2;
+
+class UnusedMixinApplication = C with Mixin;
+
+class Subclass extends C with Mixin {
+  f() {}
+}
+
+class Subclass2 extends MixinApplication {
+  g() {}
+}
+
+class SubclassA extends C with Mixin, Mixin2 {
+  fa() {}
+}
+
+class Subclass2A extends MixinApplicationA {
+  ga() {}
+}
+
+membersOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && !v.isConstructor) result[k] = v;
+    if (v is VariableMirror) result[k] = v;
+  });
+  return result;
+}
+
+constructorsOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isConstructor) result[k] = v;
+  });
+  return result;
+}
+
+checkClass(Type type, List<String> expectedSuperclasses) {
+  int i = 0;
+  for (ClassMirror? cls = reflectClass(type);
+      cls != null;
+      cls = cls.superclass) {
+    expect(expectedSuperclasses[i++], cls);
+  }
+  Expect.equals(i, expectedSuperclasses.length, '$type');
+}
+
+expectSame(ClassMirror a, ClassMirror b) {
+  Expect.equals(a, b);
+  expect(stringify(a), b);
+  expect(stringify(b), a);
+}
+
+testMixin() {
+  checkClass(Mixin, [
+    'Class(s(Mixin) in s(test.mixin_application_test), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect(
+      '{i: Variable(s(i) in s(Mixin)),'
+      ' m: Method(s(m) in s(Mixin))}',
+      membersOf(reflectClass(Mixin)));
+
+  expect('{Mixin: Method(s(Mixin) in s(Mixin), constructor)}',
+      constructorsOf(reflectClass(Mixin)));
+}
+
+testMixin2() {
+  checkClass(Mixin2, [
+    'Class(s(Mixin2) in s(test.mixin_application_test), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect(
+      '{i2: Variable(s(i2) in s(Mixin2)),'
+      ' m2: Method(s(m2) in s(Mixin2))}',
+      membersOf(reflectClass(Mixin2)));
+
+  expect('{Mixin2: Method(s(Mixin2) in s(Mixin2), constructor)}',
+      constructorsOf(reflectClass(Mixin2)));
+}
+
+testMixinApplication() {
+  checkClass(MixinApplication, [
+    'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  String owner = 'Mixin';
+  expect(
+      '{i: Variable(s(i) in s($owner)),'
+      ' m: Method(s(m) in s($owner))}',
+      membersOf(reflectClass(MixinApplication)));
+
+  expect(
+      '{MixinApplication: Method(s(MixinApplication) in s(MixinApplication),'
+      ' constructor)}',
+      constructorsOf(reflectClass(MixinApplication)));
+
+  expectSame(reflectClass(C), reflectClass(MixinApplication).superclass!);
+}
+
+testMixinApplicationA() {
+  String owner = ' in s(test.mixin_application_test)';
+  checkClass(MixinApplicationA, [
+    'Class(s(MixinApplicationA)'
+        ' in s(test.mixin_application_test), top-level)',
+    'Class(s(test.model.C with test.mixin_application_test.Mixin)'
+        '$owner, top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  owner = 'Mixin2';
+  expect(
+      '{i2: Variable(s(i2) in s($owner)),'
+      ' m2: Method(s(m2) in s($owner))}',
+      membersOf(reflectClass(MixinApplicationA)));
+
+  expect(
+      '{MixinApplicationA: Method(s(MixinApplicationA) in s(MixinApplicationA),'
+      ' constructor)}',
+      constructorsOf(reflectClass(MixinApplicationA)));
+
+  expect(
+      '{i: Variable(s(i) in s(Mixin)),'
+      ' m: Method(s(m) in s(Mixin))}',
+      membersOf(reflectClass(MixinApplicationA).superclass!));
+
+  String name = 'test.model.C with test.mixin_application_test.Mixin';
+  expect(
+      '{$name:'
+      ' Method(s($name)'
+      ' in s($name), constructor)}',
+      constructorsOf(reflectClass(MixinApplicationA).superclass!));
+
+  expectSame(
+      reflectClass(C), reflectClass(MixinApplicationA).superclass!.superclass!);
+}
+
+testUnusedMixinApplication() {
+  checkClass(UnusedMixinApplication, [
+    'Class(s(UnusedMixinApplication) in s(test.mixin_application_test),'
+        ' top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  String owner = 'Mixin';
+  expect(
+      '{i: Variable(s(i) in s($owner)),'
+      ' m: Method(s(m) in s($owner))}',
+      membersOf(reflectClass(UnusedMixinApplication)));
+
+  expect(
+      '{UnusedMixinApplication: Method(s(UnusedMixinApplication)'
+      ' in s(UnusedMixinApplication), constructor)}',
+      constructorsOf(reflectClass(UnusedMixinApplication)));
+
+  expectSame(reflectClass(C), reflectClass(UnusedMixinApplication).superclass!);
+}
+
+testSubclass() {
+  String owner = ' in s(test.mixin_application_test)';
+  checkClass(Subclass, [
+    'Class(s(Subclass) in s(test.mixin_application_test), top-level)',
+    'Class(s(test.model.C with test.mixin_application_test.Mixin)'
+        '$owner, top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect('{f: Method(s(f) in s(Subclass))}', membersOf(reflectClass(Subclass)));
+
+  expect('{Subclass: Method(s(Subclass) in s(Subclass), constructor)}',
+      constructorsOf(reflectClass(Subclass)));
+
+  expect(
+      '{i: Variable(s(i) in s(Mixin)),'
+      ' m: Method(s(m) in s(Mixin))}',
+      membersOf(reflectClass(Subclass).superclass!));
+
+  String name = 'test.model.C with test.mixin_application_test.Mixin';
+  expect(
+      '{$name:'
+      ' Method(s($name)'
+      ' in s($name), constructor)}',
+      constructorsOf(reflectClass(Subclass).superclass!));
+
+  expectSame(reflectClass(C), reflectClass(Subclass).superclass!.superclass!);
+}
+
+testSubclass2() {
+  checkClass(Subclass2, [
+    'Class(s(Subclass2) in s(test.mixin_application_test), top-level)',
+    'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect(
+      '{g: Method(s(g) in s(Subclass2))}', membersOf(reflectClass(Subclass2)));
+
+  expect('{Subclass2: Method(s(Subclass2) in s(Subclass2), constructor)}',
+      constructorsOf(reflectClass(Subclass2)));
+
+  expectSame(
+      reflectClass(MixinApplication), reflectClass(Subclass2).superclass!);
+}
+
+testSubclassA() {
+  String owner = ' in s(test.mixin_application_test)';
+  checkClass(SubclassA, [
+    'Class(s(SubclassA) in s(test.mixin_application_test), top-level)',
+    'Class(s(test.model.C with test.mixin_application_test.Mixin,'
+        ' test.mixin_application_test.Mixin2)$owner, top-level)',
+    'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,'
+        ' top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect('{fa: Method(s(fa) in s(SubclassA))}',
+      membersOf(reflectClass(SubclassA)));
+
+  expect('{SubclassA: Method(s(SubclassA) in s(SubclassA), constructor)}',
+      constructorsOf(reflectClass(SubclassA)));
+
+  expect(
+      '{i2: Variable(s(i2) in s(Mixin2)),'
+      ' m2: Method(s(m2) in s(Mixin2))}',
+      membersOf(reflectClass(SubclassA).superclass!));
+
+  String name = 'test.model.C with test.mixin_application_test.Mixin,'
+      ' test.mixin_application_test.Mixin2';
+  expect('{$name: Method(s($name) in s($name), constructor)}',
+      constructorsOf(reflectClass(SubclassA).superclass!));
+
+  expect(
+      '{i: Variable(s(i) in s(Mixin)),'
+      ' m: Method(s(m) in s(Mixin))}',
+      membersOf(reflectClass(SubclassA).superclass!.superclass!));
+
+  name = 'test.model.C with test.mixin_application_test.Mixin';
+  expect(
+      '{$name:'
+      ' Method(s($name)'
+      ' in s($name), constructor)}',
+      constructorsOf(reflectClass(SubclassA).superclass!.superclass!));
+
+  expectSame(reflectClass(C),
+      reflectClass(SubclassA).superclass!.superclass!.superclass!);
+}
+
+testSubclass2A() {
+  String owner = ' in s(test.mixin_application_test)';
+  checkClass(Subclass2A, [
+    'Class(s(Subclass2A) in s(test.mixin_application_test), top-level)',
+    'Class(s(MixinApplicationA) in s(test.mixin_application_test),'
+        ' top-level)',
+    'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,'
+        ' top-level)',
+    'Class(s(C) in s(test.model), top-level)',
+    'Class(s(B) in s(test.model), top-level)',
+    'Class(s(A) in s(test.model), top-level)',
+    'Class(s(Object) in s(dart.core), top-level)',
+  ]);
+
+  expect('{ga: Method(s(ga) in s(Subclass2A))}',
+      membersOf(reflectClass(Subclass2A)));
+
+  expect('{Subclass2A: Method(s(Subclass2A) in s(Subclass2A), constructor)}',
+      constructorsOf(reflectClass(Subclass2A)));
+
+  expectSame(
+      reflectClass(MixinApplicationA), reflectClass(Subclass2A).superclass!);
+}
+
+main() {
+  testMixin();
+  testMixin2();
+  testMixinApplication();
+  testMixinApplicationA();
+  testUnusedMixinApplication();
+  testSubclass();
+  testSubclass2();
+  testSubclassA();
+  testSubclass2A();
+}
diff --git a/tests/lib/mirrors/mixin_members_test.dart b/tests/lib/mirrors/mixin_members_test.dart
new file mode 100644
index 0000000..76670b0
--- /dev/null
+++ b/tests/lib/mirrors/mixin_members_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mixin_members_test;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+import 'stringify.dart';
+
+abstract class Fooer {
+  foo1();
+}
+
+class S implements Fooer {
+  foo1() {}
+  foo2() {}
+}
+
+class M1 {
+  bar1() {}
+  bar2() {}
+}
+
+class M2 {
+  baz1() {}
+  baz2() {}
+}
+
+class C extends S with M1, M2 {}
+
+membersOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && !v.isConstructor) result[k] = v;
+    if (v is VariableMirror) result[k] = v;
+  });
+  return result;
+}
+
+main() {
+  ClassMirror cm = reflectClass(C);
+  ClassMirror sM1M2 = cm.superclass!;
+  ClassMirror sM1 = sM1M2.superclass!;
+  ClassMirror s = sM1.superclass!;
+  expect('{}', membersOf(cm));
+  expect(
+      '[s(baz1), s(baz2)]',
+      // TODO(ahe): Shouldn't have to sort.
+      sort(membersOf(sM1M2).keys),
+      '(S with M1, M2).members');
+  expect('[s(M2)]', simpleNames(sM1M2.superinterfaces),
+      '(S with M1, M2).superinterfaces');
+  expect(
+      '[s(bar1), s(bar2)]',
+      // TODO(ahe): Shouldn't have to sort.
+      sort(membersOf(sM1).keys),
+      '(S with M1).members');
+  expect('[s(M1)]', simpleNames(sM1.superinterfaces),
+      '(S with M1).superinterfaces');
+  expect(
+      '[s(foo1), s(foo2)]',
+      // TODO(ahe): Shouldn't have to sort.
+      sort(membersOf(s).keys),
+      's.members');
+  expect('[s(Fooer)]', simpleNames(s.superinterfaces), 's.superinterfaces');
+  Expect.equals(s, reflectClass(S));
+}
diff --git a/tests/lib/mirrors/mixin_simple_test.dart b/tests/lib/mirrors/mixin_simple_test.dart
new file mode 100644
index 0000000..ee1c974
--- /dev/null
+++ b/tests/lib/mirrors/mixin_simple_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.mixin;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Super {}
+
+class Mixin {}
+
+class Mixin2 {}
+
+class Class extends Super with Mixin {}
+
+class MultipleMixins extends Class with Mixin2 {}
+
+main() {
+  Expect.equals(reflectClass(Class), reflectClass(Class).mixin);
+  Expect.equals(reflectClass(Mixin), reflectClass(Class).superclass!.mixin);
+  Expect.equals(
+      reflectClass(Super), reflectClass(Class).superclass!.superclass!.mixin);
+
+  Expect.equals(
+      reflectClass(MultipleMixins), reflectClass(MultipleMixins).mixin);
+  Expect.equals(
+      reflectClass(Mixin2), reflectClass(MultipleMixins).superclass!.mixin);
+  Expect.equals(reflectClass(Class),
+      reflectClass(MultipleMixins).superclass!.superclass!.mixin);
+  Expect.equals(reflectClass(Mixin),
+      reflectClass(MultipleMixins).superclass!.superclass!.superclass!.mixin);
+  Expect.equals(
+      reflectClass(Super),
+      reflectClass(MultipleMixins)
+          .superclass!
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin);
+}
diff --git a/tests/lib/mirrors/mixin_test.dart b/tests/lib/mirrors/mixin_test.dart
new file mode 100644
index 0000000..de9f330
--- /dev/null
+++ b/tests/lib/mirrors/mixin_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.mixin;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Super {}
+
+class Mixin {}
+
+class Mixin2 {}
+
+class Mixin3 {}
+
+class MixinApplication = Super with Mixin;
+
+class Class extends Super with Mixin {}
+
+class MultipleMixins extends Super with Mixin, Mixin2, Mixin3 {}
+
+main() {
+  Expect.equals(reflectClass(Mixin), reflectClass(MixinApplication).mixin);
+  Expect.equals(
+      reflectClass(Super), reflectClass(MixinApplication).superclass!.mixin);
+
+  Expect.equals(reflectClass(Class), reflectClass(Class).mixin);
+  Expect.equals(reflectClass(Mixin), reflectClass(Class).superclass!.mixin);
+  Expect.equals(
+      reflectClass(Super), reflectClass(Class).superclass!.superclass!.mixin);
+
+  Expect.equals(
+      reflectClass(MultipleMixins), reflectClass(MultipleMixins).mixin);
+  Expect.equals(
+      reflectClass(Mixin3), reflectClass(MultipleMixins).superclass!.mixin);
+  Expect.equals(reflectClass(Mixin2),
+      reflectClass(MultipleMixins).superclass!.superclass!.mixin);
+  Expect.equals(reflectClass(Mixin),
+      reflectClass(MultipleMixins).superclass!.superclass!.superclass!.mixin);
+  Expect.equals(
+      reflectClass(Super),
+      reflectClass(MultipleMixins)
+          .superclass!
+          .superclass!
+          .superclass!
+          .superclass!
+          .mixin);
+}
diff --git a/tests/lib/mirrors/model.dart b/tests/lib/mirrors/model.dart
new file mode 100644
index 0000000..508cbf2
--- /dev/null
+++ b/tests/lib/mirrors/model.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.model;
+
+var accessorA;
+
+var accessorB;
+
+var accessorC;
+
+var fieldC;
+
+class A {
+  var field;
+  instanceMethod(x) => 'A:instanceMethod($x)';
+  get accessor => 'A:get accessor';
+  set accessor(x) {
+    accessorA = x;
+  }
+
+  aMethod() => 'aMethod';
+}
+
+class B extends A {
+  get field => 'B:get field';
+  instanceMethod(x) => 'B:instanceMethod($x)';
+  get accessor => 'B:get accessor';
+  set accessor(x) {
+    accessorB = x;
+  }
+
+  bMethod() => 'bMethod';
+}
+
+class C extends B {
+  set field(x) {
+    fieldC = x;
+  }
+
+  instanceMethod(x) => 'C:instanceMethod($x)';
+  get accessor => 'C:get accessor';
+  set accessor(x) {
+    accessorC = x;
+  }
+
+  cMethod() => 'cMethod';
+}
diff --git a/tests/lib/mirrors/model_test.dart b/tests/lib/mirrors/model_test.dart
new file mode 100644
index 0000000..1e24901
--- /dev/null
+++ b/tests/lib/mirrors/model_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.model_test;
+
+import 'package:expect/expect.dart';
+
+import 'model.dart';
+
+main() {
+  dynamic a = new A();
+  dynamic b = new B();
+  dynamic c = new C();
+
+  Expect.isNull(a.field);
+  Expect.equals('B:get field', b.field);
+  Expect.equals('B:get field', c.field);
+
+  a.field = 42;
+  b.field = 87;
+  c.field = 89;
+  Expect.equals(42, a.field);
+  Expect.equals('B:get field', b.field);
+  Expect.equals('B:get field', c.field);
+  Expect.equals(89, fieldC);
+
+  Expect.equals('A:instanceMethod(7)', a.instanceMethod(7));
+  Expect.equals('B:instanceMethod(9)', b.instanceMethod(9));
+  Expect.equals('C:instanceMethod(13)', c.instanceMethod(13));
+
+  Expect.equals('A:get accessor', a.accessor);
+  Expect.equals('B:get accessor', b.accessor);
+  Expect.equals('C:get accessor', c.accessor);
+
+  a.accessor = 'foo';
+  b.accessor = 'bar';
+  c.accessor = 'baz';
+
+  Expect.equals('foo', accessorA);
+  Expect.equals('bar', accessorB);
+  Expect.equals('baz', accessorC);
+
+  Expect.equals('aMethod', a.aMethod());
+  Expect.equals('aMethod', b.aMethod());
+  Expect.equals('aMethod', c.aMethod());
+
+  Expect.throwsNoSuchMethodError(() => a.bMethod());
+  Expect.equals('bMethod', b.bMethod());
+  Expect.equals('bMethod', c.bMethod());
+
+  Expect.throwsNoSuchMethodError(() => a.cMethod());
+  Expect.throwsNoSuchMethodError(() => b.cMethod());
+  Expect.equals('cMethod', c.cMethod());
+}
diff --git a/tests/lib/mirrors/new_instance_optional_arguments_test.dart b/tests/lib/mirrors/new_instance_optional_arguments_test.dart
new file mode 100644
index 0000000..3d50f04
--- /dev/null
+++ b/tests/lib/mirrors/new_instance_optional_arguments_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2014, 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 mirror_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  var req1, opt1, opt2;
+  A.a0([opt1]) : this.opt1 = opt1;
+  A.b0([opt1, opt2])
+      : this.opt1 = opt1,
+        this.opt2 = opt2;
+  A.c0([opt1 = 499]) : this.opt1 = opt1;
+  A.d0([opt1 = 499, opt2 = 42])
+      : this.opt1 = opt1,
+        this.opt2 = opt2;
+  A.a1(req1, [opt1])
+      : this.req1 = req1,
+        this.opt1 = opt1;
+  A.b1(req1, [opt1, opt2])
+      : this.req1 = req1,
+        this.opt1 = opt1,
+        this.opt2 = opt2;
+  A.c1(req1, [opt1 = 499])
+      : this.req1 = req1,
+        this.opt1 = opt1;
+  A.d1(req1, [opt1 = 499, opt2 = 42])
+      : this.req1 = req1,
+        this.opt1 = opt1,
+        this.opt2 = opt2;
+}
+
+main() {
+  ClassMirror cm = reflectClass(A);
+
+  var o;
+  o = cm.newInstance(#a0, []).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(null, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#b0, []).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(null, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#c0, []).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(499, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#d0, []).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(499, o.opt1);
+  Expect.equals(42, o.opt2);
+
+  o = cm.newInstance(#a0, [77]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#b0, [77]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#c0, [77]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#d0, [77]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(42, o.opt2);
+
+  o = cm.newInstance(#b0, [77, 11]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(11, o.opt2);
+  o = cm.newInstance(#d0, [77, 11]).reflectee;
+  Expect.equals(null, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(11, o.opt2);
+
+  o = cm.newInstance(#a1, [123]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(null, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#b1, [123]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(null, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#c1, [123]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(499, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#d1, [123]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(499, o.opt1);
+  Expect.equals(42, o.opt2);
+
+  o = cm.newInstance(#a1, [123, 77]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#b1, [123, 77]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#c1, [123, 77]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(null, o.opt2);
+  o = cm.newInstance(#d1, [123, 77]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(42, o.opt2);
+
+  o = cm.newInstance(#b1, [123, 77, 11]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(11, o.opt2);
+  o = cm.newInstance(#d1, [123, 77, 11]).reflectee;
+  Expect.equals(123, o.req1);
+  Expect.equals(77, o.opt1);
+  Expect.equals(11, o.opt2);
+}
diff --git a/tests/lib/mirrors/new_instance_with_type_arguments_test.dart b/tests/lib/mirrors/new_instance_with_type_arguments_test.dart
new file mode 100644
index 0000000..820f47c
--- /dev/null
+++ b/tests/lib/mirrors/new_instance_with_type_arguments_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.new_instance_with_type_arguments_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  Type get t => T;
+}
+
+class B extends A<int> {}
+
+class C<S> extends A<num> {
+  Type get s => S;
+}
+
+main() {
+  ClassMirror cmA = reflectClass(A);
+  ClassMirror cmB = reflectClass(B);
+  ClassMirror cmC = reflectClass(C);
+
+  dynamic a_int = new A<int>();
+  dynamic a_dynamic = new A();
+  dynamic b = new B();
+  dynamic c_string = new C<String>();
+  dynamic c_dynamic = new C();
+
+  Expect.equals(int, a_int.t);
+  Expect.equals(dynamic, a_dynamic.t);
+  Expect.equals(int, b.t);
+  Expect.equals(num, c_string.t);
+  Expect.equals(num, c_dynamic.t);
+
+  Expect.equals(String, c_string.s);
+  Expect.equals(dynamic, c_dynamic.s);
+
+  dynamic reflective_a_int =
+      cmB.superclass!.newInstance(Symbol.empty, []).reflectee;
+  dynamic reflective_a_dynamic = cmA.newInstance(Symbol.empty, []).reflectee;
+  dynamic reflective_b = cmB.newInstance(Symbol.empty, []).reflectee;
+  dynamic reflective_c_dynamic = cmC.newInstance(Symbol.empty, []).reflectee;
+
+  Expect.equals(int, reflective_a_int.t);
+  Expect.equals(dynamic, reflective_a_dynamic.t);
+  Expect.equals(int, reflective_b.t);
+  Expect.equals(num, c_string.t);
+  Expect.equals(num, reflective_c_dynamic.t);
+
+  Expect.equals(String, c_string.s);
+  Expect.equals(dynamic, reflective_c_dynamic.s);
+
+  Expect.equals(a_int.runtimeType, reflective_a_int.runtimeType);
+  Expect.equals(a_dynamic.runtimeType, reflective_a_dynamic.runtimeType);
+  Expect.equals(b.runtimeType, reflective_b.runtimeType);
+  Expect.equals(c_dynamic.runtimeType, reflective_c_dynamic.runtimeType);
+}
diff --git a/tests/lib/mirrors/no_metadata_test.dart b/tests/lib/mirrors/no_metadata_test.dart
new file mode 100644
index 0000000..642dd83
--- /dev/null
+++ b/tests/lib/mirrors/no_metadata_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+class Foo {}
+
+main() {
+  expect('[]', reflectClass(Foo).metadata);
+}
diff --git a/tests/lib/mirrors/null2_test.dart b/tests/lib/mirrors/null2_test.dart
new file mode 100644
index 0000000..4c5590d
--- /dev/null
+++ b/tests/lib/mirrors/null2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.null_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  InstanceMirror nullMirror = reflect(null);
+  for (int i = 0; i < 10; i++) {
+    Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int);
+  }
+}
diff --git a/tests/lib/mirrors/null_test.dart b/tests/lib/mirrors/null_test.dart
new file mode 100644
index 0000000..cc19df8
--- /dev/null
+++ b/tests/lib/mirrors/null_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization-counter-threshold=5
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+void main() {
+  for (int i = 0; i < 10; i++) {
+    test();
+  }
+}
+
+void test() {
+  ClassMirror cm = reflectClass(Null);
+
+  InstanceMirror im1 = reflect(null);
+  Expect.equals(cm, im1.type);
+  Expect.isTrue(im1.invoke(const Symbol("=="), [null]).reflectee);
+  Expect.isFalse(im1.invoke(const Symbol("=="), [42]).reflectee);
+
+  var obj = confuse(null); // Null value that isn't known at compile-time.
+  InstanceMirror im2 = reflect(obj);
+  Expect.equals(cm, im2.type);
+  Expect.isTrue(im2.invoke(const Symbol("=="), [null]).reflectee);
+  Expect.isFalse(im2.invoke(const Symbol("=="), [42]).reflectee);
+
+  InstanceMirror nullMirror = reflect(null);
+  Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int);
+  Expect.equals(null.hashCode, nullMirror.getField(#hashCode).reflectee);
+  Expect.equals('Null', nullMirror.getField(#runtimeType).reflectee.toString());
+  Expect.isTrue(nullMirror.invoke(#==, [null]).reflectee);
+  Expect.isFalse(nullMirror.invoke(#==, [new Object()]).reflectee);
+  Expect.equals('null', nullMirror.invoke(#toString, []).reflectee);
+  Expect.throwsNoSuchMethodError(
+      () => nullMirror.invoke(#notDefined, []), 'noSuchMethod');
+
+  ClassMirror NullMirror = nullMirror.type;
+  Expect.equals(reflectClass(Null), NullMirror);
+  Expect.equals(#Null, NullMirror.simpleName);
+  Expect.equals(#Object, NullMirror.superclass!.simpleName);
+  Expect.equals(null, NullMirror.superclass!.superclass);
+  Expect.listEquals([], NullMirror.superinterfaces);
+  Map<Uri, LibraryMirror> libraries = currentMirrorSystem().libraries;
+  LibraryMirror? coreLibrary = libraries[Uri.parse('dart:core')];
+  if (coreLibrary == null) {
+    // In minified mode we don't preserve the URIs.
+    coreLibrary = libraries.values
+        .firstWhere((LibraryMirror lm) => lm.simpleName == #dart.core);
+    Uri uri = coreLibrary.uri;
+    Expect.equals("https", uri.scheme);
+    Expect.equals("dartlang.org", uri.host);
+    Expect.equals("/dart2js-stripped-uri", uri.path);
+  }
+  Expect.equals(coreLibrary, NullMirror.owner);
+}
+
+// Magic incantation to avoid the compiler recognizing the constant values
+// at compile time. If the result is computed at compile time, the dynamic code
+// will not be tested.
+confuse(x) {
+  try {
+    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
+    throw [x];
+  } catch (e) {
+    return e[0];
+  }
+  return 42;
+}
diff --git a/tests/lib/mirrors/operator_test.dart b/tests/lib/mirrors/operator_test.dart
new file mode 100644
index 0000000..a7fafbc
--- /dev/null
+++ b/tests/lib/mirrors/operator_test.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test operators.
+library test.operator_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+
+class Foo {
+  Foo operator ~() {}
+  Foo operator -() {}
+
+  bool operator ==(a) {}
+  Foo operator [](int a) {}
+  Foo operator *(Foo a) {}
+  Foo operator /(Foo a) {}
+  Foo operator %(Foo a) {}
+  Foo operator ~/(Foo a) {}
+  Foo operator +(Foo a) {}
+  Foo operator <<(Foo a) {}
+  Foo operator >>(Foo a) {}
+  Foo operator >=(Foo a) {}
+  Foo operator >(Foo a) {}
+  Foo operator <=(Foo a) {}
+  Foo operator <(Foo a) {}
+  Foo operator &(Foo a) {}
+  Foo operator ^(Foo a) {}
+  Foo operator |(Foo a) {}
+  Foo operator -(Foo a) {}
+
+  // TODO(ahe): use void when dart2js reifies that type.
+  operator []=(int a, Foo b) {}
+}
+
+void main() {
+  ClassMirror cls = reflectClass(Foo);
+  var operators = new Map<Symbol, MethodMirror>();
+  var operatorParameters = new Map<Symbol, List>();
+  var returnTypes = new Map<Symbol, Mirror>();
+  for (var method in cls.declarations.values) {
+    if (method is MethodMirror) {
+      if (!method.isConstructor) {
+        Expect.isTrue(method.isRegularMethod);
+        Expect.isTrue(method.isOperator);
+        Expect.isFalse(method.isGetter);
+        Expect.isFalse(method.isSetter);
+        Expect.isFalse(method.isAbstract);
+        operators[method.simpleName] = method;
+        operatorParameters[method.simpleName] = method.parameters;
+        returnTypes[method.simpleName] = method.returnType;
+      }
+    }
+  }
+  expect(OPERATORS, operators);
+  expect(PARAMETERS, operatorParameters);
+  expect(RETURN_TYPES, returnTypes);
+}
+
+const String OPERATORS = '{'
+    '%: Method(s(%) in s(Foo)), '
+    '&: Method(s(&) in s(Foo)), '
+    '*: Method(s(*) in s(Foo)), '
+    '+: Method(s(+) in s(Foo)), '
+    '-: Method(s(-) in s(Foo)), '
+    '/: Method(s(/) in s(Foo)), '
+    '<: Method(s(<) in s(Foo)), '
+    '<<: Method(s(<<) in s(Foo)), '
+    '<=: Method(s(<=) in s(Foo)), '
+    '==: Method(s(==) in s(Foo)), '
+    '>: Method(s(>) in s(Foo)), '
+    '>=: Method(s(>=) in s(Foo)), '
+    '>>: Method(s(>>) in s(Foo)), '
+    '[]: Method(s([]) in s(Foo)), '
+    '[]=: Method(s([]=) in s(Foo)), '
+    '^: Method(s(^) in s(Foo)), '
+    'unary-: Method(s(unary-) in s(Foo)), '
+    '|: Method(s(|) in s(Foo)), '
+    '~: Method(s(~) in s(Foo)), '
+    '~/: Method(s(~/) in s(Foo))'
+    '}';
+
+const String DYNAMIC = 'Type(s(dynamic), top-level)';
+
+const String FOO = 'Class(s(Foo) in s(test.operator_test), top-level)';
+
+const String INT = 'Class(s(int) in s(dart.core), top-level)';
+
+const String BOOL = 'Class(s(bool) in s(dart.core), top-level)';
+
+const String PARAMETERS = '{'
+    '%: [Parameter(s(a) in s(%), type = $FOO)], '
+    '&: [Parameter(s(a) in s(&), type = $FOO)], '
+    '*: [Parameter(s(a) in s(*), type = $FOO)], '
+    '+: [Parameter(s(a) in s(+), type = $FOO)], '
+    '-: [Parameter(s(a) in s(-), type = $FOO)], '
+    '/: [Parameter(s(a) in s(/), type = $FOO)], '
+    '<: [Parameter(s(a) in s(<), type = $FOO)], '
+    '<<: [Parameter(s(a) in s(<<), type = $FOO)], '
+    '<=: [Parameter(s(a) in s(<=), type = $FOO)], '
+    '==: [Parameter(s(a) in s(==), type = $DYNAMIC)], '
+    '>: [Parameter(s(a) in s(>), type = $FOO)], '
+    '>=: [Parameter(s(a) in s(>=), type = $FOO)], '
+    '>>: [Parameter(s(a) in s(>>), type = $FOO)], '
+    '[]: [Parameter(s(a) in s([]), type = $INT)], '
+    '[]=: [Parameter(s(a) in s([]=), type = $INT), '
+    'Parameter(s(b) in s([]=), type = $FOO)], '
+    '^: [Parameter(s(a) in s(^), type = $FOO)], '
+    'unary-: [], '
+    '|: [Parameter(s(a) in s(|), type = $FOO)], '
+    '~: [], '
+    '~/: [Parameter(s(a) in s(~/), type = $FOO)]'
+    '}';
+
+const String RETURN_TYPES = '{'
+    '%: $FOO, '
+    '&: $FOO, '
+    '*: $FOO, '
+    '+: $FOO, '
+    '-: $FOO, '
+    '/: $FOO, '
+    '<: $FOO, '
+    '<<: $FOO, '
+    '<=: $FOO, '
+    '==: $BOOL, '
+    '>: $FOO, '
+    '>=: $FOO, '
+    '>>: $FOO, '
+    '[]: $FOO, '
+    '[]=: $DYNAMIC, '
+    '^: $FOO, '
+    'unary-: $FOO, '
+    '|: $FOO, '
+    '~: $FOO, '
+    '~/: $FOO'
+    '}';
diff --git a/tests/lib/mirrors/optional_parameters_test.dart b/tests/lib/mirrors/optional_parameters_test.dart
new file mode 100644
index 0000000..10515dd
--- /dev/null
+++ b/tests/lib/mirrors/optional_parameters_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for http://dartbug.com/22987.
+// Ensure that functions whose signature only differs in optionality of
+// parameters are reflected correctly.
+
+library optional_parameter_test;
+
+import "dart:mirrors";
+import 'package:expect/expect.dart';
+
+class A {
+  foo(int x) => x;
+}
+
+class B {
+  foo([int x = -1]) => x + 1;
+}
+
+main() {
+  var x = {};
+  x["A"] = reflect(new A());
+  x["B"] = reflect(new B());
+
+  Expect.equals(1, x["A"].invoke(#foo, [1]).reflectee);
+  Expect.equals(2, x["B"].invoke(#foo, [1]).reflectee);
+}
diff --git a/tests/lib/mirrors/other_declarations_location_test.dart b/tests/lib/mirrors/other_declarations_location_test.dart
new file mode 100644
index 0000000..2c751a5
--- /dev/null
+++ b/tests/lib/mirrors/other_declarations_location_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_location;
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+import "library_without_declaration.dart";
+import "library_with_annotated_declaration.dart";
+
+const metadata = 'metadata';
+
+class C<S, @metadata T> {
+  var a;
+  final b = 2;
+  static var c;
+  static final d = 4;
+  @metadata
+  var e;
+  late List<C> f;
+}
+
+// We only check for a suffix of the uri because the test might be run from
+// any number of absolute paths.
+expectLocation(
+    DeclarationMirror mirror, String uriSuffix, int line, int column) {
+  SourceLocation location = mirror.location!;
+  Uri uri = location.sourceUri;
+  Expect.isTrue(
+      uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri");
+  Expect.equals(line, location.line, "line");
+  Expect.equals(column, location.column, "column");
+}
+
+main() {
+  String mainSuffix = 'other_declarations_location_test.dart';
+
+  // Fields.
+  expectLocation(reflectClass(C).declarations[#a]!, mainSuffix, 15, 7);
+  expectLocation(reflectClass(C).declarations[#b]!, mainSuffix, 16, 9);
+  expectLocation(reflectClass(C).declarations[#c]!, mainSuffix, 17, 14);
+  expectLocation(reflectClass(C).declarations[#d]!, mainSuffix, 18, 16);
+  expectLocation(reflectClass(C).declarations[#e]!, mainSuffix, 20, 7);
+  expectLocation(reflectClass(C).declarations[#f]!, mainSuffix, 21, 11);
+
+  // Type variables.
+  expectLocation(reflectClass(C).declarations[#S]!, mainSuffix, 14, 9);
+  expectLocation(reflectClass(C).declarations[#T]!, mainSuffix, 14, 12);
+
+  // Libraries.
+  expectLocation(reflectClass(C).owner!, mainSuffix, 5, 1);
+  expectLocation(reflectClass(ClassInLibraryWithoutDeclaration).owner!,
+      "library_without_declaration.dart", 1, 1);
+  expectLocation(reflectClass(ClassInLibraryWithAnnotatedDeclaration).owner!,
+      "library_with_annotated_declaration.dart", 5, 1);
+}
diff --git a/tests/lib/mirrors/other_library.dart b/tests/lib/mirrors/other_library.dart
new file mode 100644
index 0000000..c1e908f
--- /dev/null
+++ b/tests/lib/mirrors/other_library.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.other_library;
+
+topLevelMethod() => 42;
+get topLevelGetter => 42;
+set topLevelSetter(x) => 42;
+var topLevelField = 42;
+
+_topLevelMethod() => 42;
+get _topLevelGetter => 42;
+set _topLevelSetter(x) => 42;
+var _topLevelField = 42;
diff --git a/tests/lib/mirrors/parameter_abstract_test.dart b/tests/lib/mirrors/parameter_abstract_test.dart
new file mode 100644
index 0000000..cf2bd25
--- /dev/null
+++ b/tests/lib/mirrors/parameter_abstract_test.dart
@@ -0,0 +1,32 @@
+// 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:mirrors';
+
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+const X = 'X';
+const Y = 'Y';
+const Z = 'Z';
+
+abstract class C {
+  foo1({@X int x: 1, @Y int y: 2, @Z int z: 3});
+}
+
+main() {
+  ClassMirror cm = reflectClass(C);
+
+  MethodMirror foo1 = cm.declarations[#foo1] as MethodMirror;
+  expect('Method(s(foo1) in s(C), abstract)', foo1);
+  expect(
+      'Parameter(s(x) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
+      foo1.parameters[0]);
+  expect(
+      'Parameter(s(y) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
+      foo1.parameters[1]);
+  expect(
+      'Parameter(s(z) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
+      foo1.parameters[2]);
+}
diff --git a/tests/lib/mirrors/parameter_annotation_mirror_test.dart b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
new file mode 100644
index 0000000..ff4aaa6
--- /dev/null
+++ b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2014, 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:mirrors";
+
+import 'package:expect/expect.dart';
+
+class ParameterAnnotation {
+  final String value;
+  const ParameterAnnotation(this.value);
+}
+
+class Foo {
+  Foo(@ParameterAnnotation("vogel") p) {}
+  Foo.named(@ParameterAnnotation("hamster") p) {}
+  Foo.named2(
+      @ParameterAnnotation("hamster") p, @ParameterAnnotation("wurm") p2) {}
+
+  f1(@ParameterAnnotation("hest") p) {}
+  f2(@ParameterAnnotation("hest") @ParameterAnnotation("fisk") p) {}
+  f3(a, @ParameterAnnotation("fugl") p) {}
+  f4(@ParameterAnnotation("fisk") a, {@ParameterAnnotation("hval") p}) {}
+  f5(@ParameterAnnotation("fisk") a, [@ParameterAnnotation("hval") p]) {}
+  f6({@ParameterAnnotation("fisk") z, @ParameterAnnotation("hval") p}) {}
+
+  set s1(@ParameterAnnotation("cheval") p) {}
+}
+
+expectAnnotations(
+    Type type, Symbol method, int parameterIndex, List<String> expectedValues) {
+  MethodMirror mirror = reflectClass(type).declarations[method] as MethodMirror;
+  ParameterMirror parameter = mirror.parameters[parameterIndex];
+  List<InstanceMirror> annotations = parameter.metadata;
+  Expect.equals(annotations.length, expectedValues.length,
+      "wrong number of parameter annotations");
+  for (int i = 0; i < annotations.length; i++) {
+    Expect.equals(
+        expectedValues[i],
+        annotations[i].reflectee.value,
+        "annotation #$i of parameter #$parameterIndex "
+        "of $type.$method.");
+  }
+}
+
+main() {
+  expectAnnotations(Foo, #Foo, 0, ["vogel"]);
+  expectAnnotations(Foo, #Foo.named, 0, ["hamster"]);
+  expectAnnotations(Foo, #Foo.named2, 0, ["hamster"]);
+  expectAnnotations(Foo, #Foo.named2, 1, ["wurm"]);
+
+  expectAnnotations(Foo, #f1, 0, ["hest"]);
+  expectAnnotations(Foo, #f2, 0, ["hest", "fisk"]);
+  expectAnnotations(Foo, #f3, 0, []);
+  expectAnnotations(Foo, #f3, 1, ["fugl"]);
+  expectAnnotations(Foo, #f4, 0, ["fisk"]);
+  expectAnnotations(Foo, #f4, 1, ["hval"]);
+  expectAnnotations(Foo, #f5, 0, ["fisk"]);
+  expectAnnotations(Foo, #f5, 1, ["hval"]);
+  expectAnnotations(Foo, #f6, 0, ["fisk"]);
+  expectAnnotations(Foo, #f6, 1, ["hval"]);
+
+  expectAnnotations(Foo, const Symbol('s1='), 0, ["cheval"]);
+}
diff --git a/tests/lib/mirrors/parameter_is_const_test.dart b/tests/lib/mirrors/parameter_is_const_test.dart
new file mode 100644
index 0000000..c2739e5
--- /dev/null
+++ b/tests/lib/mirrors/parameter_is_const_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.parameter_is_const;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Class {
+  foo(
+  const //# 01: compile-time error
+      param) {}
+}
+
+main() {
+  MethodMirror mm = reflectClass(Class).declarations[#foo] as MethodMirror;
+  Expect.isFalse(mm.parameters.single.isConst);
+}
diff --git a/tests/lib/mirrors/parameter_metadata_test.dart b/tests/lib/mirrors/parameter_metadata_test.dart
new file mode 100644
index 0000000..f875983
--- /dev/null
+++ b/tests/lib/mirrors/parameter_metadata_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.parameter_metadata_test;
+
+import 'dart:mirrors';
+
+import 'metadata_test.dart';
+
+const m1 = 'm1';
+const m2 = #m2;
+const m3 = const CustomAnnotation(3);
+
+class CustomAnnotation {
+  final value;
+  const CustomAnnotation(this.value);
+  toString() => 'CustomAnnotation($value)';
+}
+
+class B {
+  B.foo(int x) {}
+  factory B.bar(@m3 @m2 int z, x) {}
+
+  baz(@m1 final int x, @m2 int y, @m3 final int z) {}
+  qux(int x, [@m3 @m2 @m1 int y = 3 + 1]) {}
+  quux(int x, {String str: "foo"}) {}
+  corge({@m1 int x: 3 * 17, @m2 String str: "bar"}) {}
+
+  set x(@m2 final value) {}
+}
+
+main() {
+  ClassMirror cm = reflectClass(B);
+  MethodMirror mm;
+
+  mm = cm.declarations[#B.foo] as MethodMirror;
+  checkMetadata(mm.parameters[0], []);
+
+  mm = cm.declarations[#B.bar] as MethodMirror;
+  checkMetadata(mm.parameters[0], [m3, m2]);
+  checkMetadata(mm.parameters[1], []);
+
+  mm = cm.declarations[#baz] as MethodMirror;
+  checkMetadata(mm.parameters[0], [m1]);
+  checkMetadata(mm.parameters[1], [m2]);
+  checkMetadata(mm.parameters[2], [m3]);
+
+  mm = cm.declarations[#qux] as MethodMirror;
+  checkMetadata(mm.parameters[0], []);
+  checkMetadata(mm.parameters[1], [m3, m2, m1]);
+
+  mm = cm.declarations[#quux] as MethodMirror;
+  checkMetadata(mm.parameters[0], []);
+  checkMetadata(mm.parameters[1], []);
+
+  mm = cm.declarations[#corge] as MethodMirror;
+  checkMetadata(mm.parameters[0], [m1]);
+  checkMetadata(mm.parameters[1], [m2]);
+
+  mm = cm.declarations[const Symbol('x=')] as MethodMirror;
+  checkMetadata(mm.parameters[0], [m2]);
+}
diff --git a/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart b/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart
new file mode 100644
index 0000000..c2baee9
--- /dev/null
+++ b/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2014, 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 test.parameter_of_mixin_app_constructor;
+
+import 'dart:mirrors';
+import 'stringify.dart';
+
+class MapView {
+  final _map;
+  MapView(map) : this._map = map;
+}
+
+abstract class UnmodifiableMapMixin {
+  someFunctionality() {}
+}
+
+class UnmodifiableMapView1 extends MapView with UnmodifiableMapMixin {
+  UnmodifiableMapView1(map1) : super(map1);
+}
+
+class UnmodifiableMapView2 = MapView with UnmodifiableMapMixin;
+
+class S {
+  S(int p1, String p2);
+}
+
+class M1 {}
+
+class M2 {}
+
+class M3 {}
+
+class MorePlumbing = S with M1, M2, M3;
+
+soleConstructorOf(ClassMirror cm) {
+  return cm.declarations.values
+      .where((dm) => dm is MethodMirror && dm.isConstructor)
+      .single;
+}
+
+main() {
+  ClassMirror umv1 = reflectClass(UnmodifiableMapView1);
+  expect(
+      '[Parameter(s(map1) in s(UnmodifiableMapView1),'
+      ' type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(umv1).parameters);
+  expect(
+      '[Parameter(s(map) in s(test.parameter_of_mixin_app_constructor.MapView'
+      ' with test.parameter_of_mixin_app_constructor.UnmodifiableMapMixin),'
+      ' final, type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(umv1.superclass!).parameters);
+  expect(
+      '[Parameter(s(map) in s(MapView),'
+      ' type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(umv1.superclass!.superclass!).parameters);
+  expect('[]',
+      soleConstructorOf(umv1.superclass!.superclass!.superclass!).parameters);
+
+  ClassMirror umv2 = reflectClass(UnmodifiableMapView2);
+  expect(
+      '[Parameter(s(map) in s(UnmodifiableMapView2),'
+      ' final, type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(umv2).parameters);
+  expect(
+      '[Parameter(s(map) in s(MapView),'
+      ' type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(umv2.superclass!).parameters);
+  expect('[]', soleConstructorOf(umv2.superclass!.superclass!).parameters);
+
+  ClassMirror mp = reflectClass(MorePlumbing);
+  expect(
+      '[Parameter(s(p1) in s(MorePlumbing),'
+      ' final, type = Type(s(dynamic), top-level)),'
+      ' Parameter(s(p2) in s(MorePlumbing),'
+      ' final, type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(mp).parameters);
+  expect(
+      '[Parameter(s(p1) in s(test.parameter_of_mixin_app_constructor.S'
+      ' with test.parameter_of_mixin_app_constructor.M1,'
+      ' test.parameter_of_mixin_app_constructor.M2),'
+      ' final, type = Type(s(dynamic), top-level)),'
+      ' Parameter(s(p2) in s(test.parameter_of_mixin_app_constructor.S'
+      ' with test.parameter_of_mixin_app_constructor.M1,'
+      ' test.parameter_of_mixin_app_constructor.M2),'
+      ' final, type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(mp.superclass!).parameters);
+  expect(
+      '[Parameter(s(p1) in s(test.parameter_of_mixin_app_constructor.S'
+      ' with test.parameter_of_mixin_app_constructor.M1),'
+      ' final, type = Type(s(dynamic), top-level)),'
+      ' Parameter(s(p2) in s(test.parameter_of_mixin_app_constructor.S'
+      ' with test.parameter_of_mixin_app_constructor.M1),'
+      ' final, type = Type(s(dynamic), top-level))]',
+      soleConstructorOf(mp.superclass!.superclass!).parameters);
+  expect(
+      '[Parameter(s(p1) in s(S),'
+      ' type = Class(s(int) in s(dart.core), top-level)),'
+      ' Parameter(s(p2) in s(S),'
+      ' type = Class(s(String) in s(dart.core), top-level))]',
+      soleConstructorOf(mp.superclass!.superclass!.superclass!).parameters);
+  expect(
+      '[]',
+      soleConstructorOf(mp.superclass!.superclass!.superclass!.superclass!)
+          .parameters);
+}
diff --git a/tests/lib/mirrors/parameter_optional_order_test.dart b/tests/lib/mirrors/parameter_optional_order_test.dart
new file mode 100644
index 0000000..a2fa3d4
--- /dev/null
+++ b/tests/lib/mirrors/parameter_optional_order_test.dart
@@ -0,0 +1,107 @@
+// 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:mirrors';
+
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+const X = 'X';
+const Y = 'Y';
+const Z = 'Z';
+
+class C {
+  positional1(u, v, w, [@X int x = 1, @Y int y = 2, @Z int z = 3]) {}
+  positional2(u, v, w, [@Y int y = 1, @Z int z = 2, @X int x = 3]) {}
+  positional3(u, v, w, [@Z int z = 1, @X int x = 2, @Y int y = 3]) {}
+
+  named1(u, v, w, {@X int x: 1, @Y int y: 2, @Z int z: 3}) {}
+  named2(u, v, w, {@Y int y: 1, @Z int z: 2, @X int x: 3}) {}
+  named3(u, v, w, {@Z int z: 1, @X int x: 2, @Y int y: 3}) {}
+}
+
+testPositional() {
+  ClassMirror cm = reflectClass(C);
+
+  MethodMirror positional1 = cm.declarations[#positional1] as MethodMirror;
+  expect('Method(s(positional1) in s(C))', positional1);
+  expect(
+      'Parameter(s(x) in s(positional1), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      positional1.parameters[3]);
+  expect(
+      'Parameter(s(y) in s(positional1), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      positional1.parameters[4]);
+  expect(
+      'Parameter(s(z) in s(positional1), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      positional1.parameters[5]);
+
+  MethodMirror positional2 = cm.declarations[#positional2] as MethodMirror;
+  expect('Method(s(positional2) in s(C))', positional2);
+  expect(
+      'Parameter(s(y) in s(positional2), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      positional2.parameters[3]);
+  expect(
+      'Parameter(s(z) in s(positional2), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      positional2.parameters[4]);
+  expect(
+      'Parameter(s(x) in s(positional2), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      positional2.parameters[5]);
+
+  MethodMirror positional3 = cm.declarations[#positional3] as MethodMirror;
+  expect('Method(s(positional3) in s(C))', positional3);
+  expect(
+      'Parameter(s(z) in s(positional3), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      positional3.parameters[3]);
+  expect(
+      'Parameter(s(x) in s(positional3), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      positional3.parameters[4]);
+  expect(
+      'Parameter(s(y) in s(positional3), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      positional3.parameters[5]);
+}
+
+testNamed() {
+  ClassMirror cm = reflectClass(C);
+
+  MethodMirror named1 = cm.declarations[#named1] as MethodMirror;
+  expect('Method(s(named1) in s(C))', named1);
+  expect(
+      'Parameter(s(x) in s(named1), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      named1.parameters[3]);
+  expect(
+      'Parameter(s(y) in s(named1), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      named1.parameters[4]);
+  expect(
+      'Parameter(s(z) in s(named1), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      named1.parameters[5]);
+
+  MethodMirror named2 = cm.declarations[#named2] as MethodMirror;
+  expect('Method(s(named2) in s(C))', named2);
+  expect(
+      'Parameter(s(y) in s(named2), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      named2.parameters[3]);
+  expect(
+      'Parameter(s(z) in s(named2), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      named2.parameters[4]);
+  expect(
+      'Parameter(s(x) in s(named2), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      named2.parameters[5]);
+
+  MethodMirror named3 = cm.declarations[#named3] as MethodMirror;
+  expect('Method(s(named3) in s(C))', named3);
+  expect(
+      'Parameter(s(z) in s(named3), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+      named3.parameters[3]);
+  expect(
+      'Parameter(s(x) in s(named3), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+      named3.parameters[4]);
+  expect(
+      'Parameter(s(y) in s(named3), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+      named3.parameters[5]);
+}
+
+main() {
+  testPositional();
+  testNamed();
+}
diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart
new file mode 100644
index 0000000..d096711
--- /dev/null
+++ b/tests/lib/mirrors/parameter_test.dart
@@ -0,0 +1,203 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This tests uses the multi-test "ok" feature:
+// none: Desired behaviour, passing on the VM.
+// 01: Trimmed version for dart2js.
+//
+// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.
+
+/** Test of [ParameterMirror]. */
+library test.parameter_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+
+class B {
+  B();
+  B.foo(int x);
+  B.bar(int z, x);
+
+  // TODO(6490): Currently only supported by the VM.
+  B.baz(final int x, int y, final int z);
+  B.qux(int x, [int y = 3 + 1]);
+  B.quux(int x, {String str: "foo"});
+  B.corge({int x: 3 * 17, String str: "bar"});
+
+  var _x;
+  get x => _x;
+  set x(final value) {
+    _x = value;
+  }
+
+  grault([int x = 0]) {}
+  garply({int y = 0}) {}
+  waldo(int z) {}
+}
+
+class C<S extends int, T> {
+  // TODO(6490): Currently only supported by the VM.
+  foo(int a, S b) => b;
+  bar(S a, T b, num c) {}
+}
+
+main() {
+  ClassMirror cm = reflectClass(B);
+  var constructors = new Map<Symbol, MethodMirror>();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isConstructor) constructors[k] = v;
+  });
+
+  List<Symbol> constructorKeys = [
+    #B,
+    #B.bar,
+    #B.baz,
+    #B.foo,
+    #B.quux,
+    #B.qux,
+    #B.corge
+  ];
+  Expect.setEquals(constructorKeys, constructors.keys);
+
+  MethodMirror unnamedConstructor = constructors[#B] as MethodMirror;
+  expect('Method(s(B) in s(B), constructor)', unnamedConstructor);
+  expect('[]', unnamedConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      unnamedConstructor.returnType);
+
+  MethodMirror fooConstructor = constructors[#B.foo] as MethodMirror;
+  expect('Method(s(B.foo) in s(B), constructor)', fooConstructor);
+  expect(
+      '[Parameter(s(x) in s(B.foo),'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      fooConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      fooConstructor.returnType);
+
+  MethodMirror barConstructor = constructors[#B.bar] as MethodMirror;
+  expect('Method(s(B.bar) in s(B), constructor)', barConstructor);
+  expect(
+      '[Parameter(s(z) in s(B.bar),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(x) in s(B.bar),'
+      ' type = Type(s(dynamic), top-level))]',
+      barConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      barConstructor.returnType);
+
+  // dart2js stops testing here.
+  return; // //# 01: ok
+
+  MethodMirror bazConstructor = constructors[#B.baz] as MethodMirror;
+  expect('Method(s(B.baz) in s(B), constructor)', bazConstructor);
+  expect(
+      '[Parameter(s(x) in s(B.baz), final,'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(y) in s(B.baz),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(z) in s(B.baz), final,'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      bazConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      bazConstructor.returnType);
+
+  MethodMirror quxConstructor = constructors[#B.qux] as MethodMirror;
+  expect('Method(s(B.qux) in s(B), constructor)', quxConstructor);
+  expect(
+      '[Parameter(s(x) in s(B.qux),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(y) in s(B.qux), optional,'
+      ' value = Instance(value = 4),'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      quxConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      quxConstructor.returnType);
+
+  MethodMirror quuxConstructor = constructors[#B.quux] as MethodMirror;
+  expect('Method(s(B.quux) in s(B), constructor)', quuxConstructor);
+  expect(
+      '[Parameter(s(x) in s(B.quux),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(str) in s(B.quux), optional, named,'
+      ' value = Instance(value = foo),'
+      ' type = Class(s(String) in s(dart.core), top-level))]',
+      quuxConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      quuxConstructor.returnType);
+
+  MethodMirror corgeConstructor = constructors[#B.corge] as MethodMirror;
+  expect('Method(s(B.corge) in s(B), constructor)', corgeConstructor);
+  expect(
+      '[Parameter(s(x) in s(B.corge), optional, named,'
+      ' value = Instance(value = 51),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(str) in s(B.corge), optional, named,'
+      ' value = Instance(value = bar),'
+      ' type = Class(s(String) in s(dart.core), top-level))]',
+      corgeConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+      corgeConstructor.returnType);
+
+  MethodMirror xGetter = cm.declarations[#x] as MethodMirror;
+  expect('Method(s(x) in s(B), getter)', xGetter);
+  expect('[]', xGetter.parameters);
+
+  MethodMirror xSetter = cm.declarations[const Symbol('x=')] as MethodMirror;
+  expect('Method(s(x=) in s(B), setter)', xSetter);
+  expect(
+      '[Parameter(s(value) in s(x=), final,'
+      ' type = Type(s(dynamic), top-level))]',
+      xSetter.parameters);
+
+  MethodMirror grault = cm.declarations[#grault] as MethodMirror;
+  expect('Method(s(grault) in s(B))', grault);
+  expect(
+      '[Parameter(s(x) in s(grault), optional, value = Instance(value = 0),'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      grault.parameters);
+  expect('Instance(value = 0)', grault.parameters[0].defaultValue);
+
+  MethodMirror garply = cm.declarations[#garply] as MethodMirror;
+  expect('Method(s(garply) in s(B))', garply);
+  expect(
+      '[Parameter(s(y) in s(garply), optional, named, value = Instance(value = 0),'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      garply.parameters);
+  expect('Instance(value = 0)', garply.parameters[0].defaultValue);
+
+  MethodMirror waldo = cm.declarations[#waldo] as MethodMirror;
+  expect('Method(s(waldo) in s(B))', waldo);
+  expect(
+      '[Parameter(s(z) in s(waldo),'
+      ' type = Class(s(int) in s(dart.core), top-level))]',
+      waldo.parameters);
+  expect('<null>', waldo.parameters[0].defaultValue);
+
+  cm = reflectClass(C);
+
+  MethodMirror fooInC = cm.declarations[#foo] as MethodMirror;
+  expect('Method(s(foo) in s(C))', fooInC);
+  expect(
+      '[Parameter(s(a) in s(foo),'
+      ' type = Class(s(int) in s(dart.core), top-level)), '
+      'Parameter(s(b) in s(foo),'
+      ' type = TypeVariable(s(S) in s(C),'
+      ' upperBound = Class(s(int) in s(dart.core), top-level)))]',
+      fooInC.parameters);
+
+  MethodMirror barInC = cm.declarations[#bar] as MethodMirror;
+  expect('Method(s(bar) in s(C))', barInC);
+  expect(
+      '[Parameter(s(a) in s(bar),'
+      ' type = TypeVariable(s(S) in s(C),'
+      ' upperBound = Class(s(int) in s(dart.core), top-level))), '
+      'Parameter(s(b) in s(bar),'
+      ' type = TypeVariable(s(T) in s(C),'
+      ' upperBound = Class(s(Object) in s(dart.core), top-level))), '
+      'Parameter(s(c) in s(bar),'
+      ' type = Class(s(num) in s(dart.core), top-level))]',
+      barInC.parameters);
+}
diff --git a/tests/lib/mirrors/private_class_field_other.dart b/tests/lib/mirrors/private_class_field_other.dart
new file mode 100644
index 0000000..1a30354
--- /dev/null
+++ b/tests/lib/mirrors/private_class_field_other.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+  static var _privateField = 42;
+}
+
+get privateFieldSymbolInOther => #_privateField;
diff --git a/tests/lib/mirrors/private_class_field_test.dart b/tests/lib/mirrors/private_class_field_test.dart
new file mode 100644
index 0000000..ae963e87
--- /dev/null
+++ b/tests/lib/mirrors/private_class_field_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test a private field name doesn't match the equivalent private name from
+// another library.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'private_class_field_other.dart';
+
+void main() {
+  var classMirror = reflectClass(C);
+  // The symbol is private w/r/t the wrong library.
+  Expect.throwsNoSuchMethodError(() => classMirror.getField(#_privateField));
+
+  Expect.equals(42, classMirror.getField(privateFieldSymbolInOther).reflectee);
+}
diff --git a/tests/lib/mirrors/private_field_helper.dart b/tests/lib/mirrors/private_field_helper.dart
new file mode 100644
index 0000000..df4636e
--- /dev/null
+++ b/tests/lib/mirrors/private_field_helper.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.mixin;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Bar {
+  String _field = "hello";
+  String get field => _field;
+}
+
+var privateSymbol2 = #_field;
+var publicSymbol2 = #field;
diff --git a/tests/lib/mirrors/private_field_test.dart b/tests/lib/mirrors/private_field_test.dart
new file mode 100644
index 0000000..ae830a9
--- /dev/null
+++ b/tests/lib/mirrors/private_field_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.mixin;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'private_field_helper.dart';
+
+class Foo extends Bar {
+  int _field = 42;
+
+  static int _staticField = 99;
+}
+
+var privateSymbol = #_field;
+var publicSymbol = #field;
+
+main() {
+  Expect.equals(publicSymbol, publicSymbol2);
+  Expect.notEquals(privateSymbol, privateSymbol2);
+
+  var foo = new Foo();
+  var m = reflect(foo);
+  m.setField(privateSymbol, 38);
+  Expect.equals(38, foo._field);
+  m.setField(privateSymbol2, "world");
+  Expect.equals("world", foo.field);
+  Expect.equals("world", m.getField(publicSymbol).reflectee);
+
+  var type = reflectClass(Foo);
+  Expect.equals(99, type.getField(#_staticField).reflectee);
+}
diff --git a/tests/lib/mirrors/private_symbol_mangling_lib.dart b/tests/lib/mirrors/private_symbol_mangling_lib.dart
new file mode 100644
index 0000000..8d9c93b
--- /dev/null
+++ b/tests/lib/mirrors/private_symbol_mangling_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2014, 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 other;
+
+var _privateGlobalField = 3;
+
+_privateGlobalMethod() => 11;
+
+class C2 {
+  var _privateField = 1;
+  _privateMethod() => 3;
+}
diff --git a/tests/lib/mirrors/private_symbol_mangling_test.dart b/tests/lib/mirrors/private_symbol_mangling_test.dart
new file mode 100644
index 0000000..514b10b
--- /dev/null
+++ b/tests/lib/mirrors/private_symbol_mangling_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, 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 main;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+import 'private_symbol_mangling_lib.dart';
+
+var _privateGlobalField = 1;
+
+_privateGlobalMethod() => 9;
+
+class C1 {
+  var _privateField = 0;
+  _privateMethod() => 2;
+}
+
+getPrivateGlobalFieldValue(LibraryMirror lib) {
+  for (Symbol symbol in lib.declarations.keys) {
+    DeclarationMirror decl = lib.declarations[symbol]!;
+    if (decl is VariableMirror && decl.isPrivate) {
+      return lib.getField(symbol).reflectee;
+    }
+  }
+}
+
+getPrivateFieldValue(InstanceMirror cls) {
+  for (Symbol symbol in cls.type.declarations.keys) {
+    DeclarationMirror decl = cls.type.declarations[symbol]!;
+    if (decl is VariableMirror && decl.isPrivate) {
+      return cls.getField(symbol).reflectee;
+    }
+  }
+}
+
+getPrivateGlobalMethodValue(LibraryMirror lib) {
+  for (Symbol symbol in lib.declarations.keys) {
+    DeclarationMirror decl = lib.declarations[symbol]!;
+    if (decl is MethodMirror && decl.isRegularMethod && decl.isPrivate) {
+      return lib.invoke(symbol, []).reflectee;
+    }
+  }
+}
+
+getPrivateMethodValue(InstanceMirror cls) {
+  for (Symbol symbol in cls.type.declarations.keys) {
+    DeclarationMirror decl = cls.type.declarations[symbol]!;
+    if (decl is MethodMirror && decl.isRegularMethod && decl.isPrivate) {
+      return cls.invoke(symbol, []).reflectee;
+    }
+  }
+}
+
+main() {
+  LibraryMirror libmain = currentMirrorSystem().findLibrary(#main);
+  LibraryMirror libother = currentMirrorSystem().findLibrary(#other);
+  Expect.equals(1, getPrivateGlobalFieldValue(libmain));
+  Expect.equals(3, getPrivateGlobalFieldValue(libother));
+  Expect.equals(9, getPrivateGlobalMethodValue(libmain));
+  Expect.equals(11, getPrivateGlobalMethodValue(libother));
+
+  var c1 = reflect(new C1());
+  var c2 = reflect(new C2());
+  Expect.equals(0, getPrivateFieldValue(c1));
+  Expect.equals(1, getPrivateFieldValue(c2));
+  Expect.equals(2, getPrivateMethodValue(c1));
+  Expect.equals(3, getPrivateMethodValue(c2));
+}
diff --git a/tests/lib/mirrors/private_symbol_test.dart b/tests/lib/mirrors/private_symbol_test.dart
new file mode 100644
index 0000000..b6e74af
--- /dev/null
+++ b/tests/lib/mirrors/private_symbol_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+typedef int _F(int i);
+
+class _C<_T> {
+  get g {}
+  set s(x) {}
+  m(_p) {}
+  get _g {}
+  set _s(x) {}
+  _m() {}
+}
+
+main() {
+  // Test private symbols are distinct across libraries, and the same within a
+  // library when created multiple ways. Test the string can be properly
+  // extracted.
+  LibraryMirror libcore = currentMirrorSystem().findLibrary(#dart.core);
+  LibraryMirror libmath = currentMirrorSystem().findLibrary(#dart.math);
+  LibraryMirror libtest = currentMirrorSystem().findLibrary(#test);
+
+  Symbol corefoo = MirrorSystem.getSymbol('foo', libcore);
+  Symbol mathfoo = MirrorSystem.getSymbol('foo', libmath);
+  Symbol testfoo = MirrorSystem.getSymbol('foo', libtest);
+  Symbol nullfoo1 = MirrorSystem.getSymbol('foo');
+  Symbol nullfoo2 = MirrorSystem.getSymbol('foo', null);
+
+  Expect.equals(corefoo, mathfoo);
+  Expect.equals(mathfoo, testfoo);
+  Expect.equals(testfoo, corefoo);
+  Expect.equals(nullfoo1, corefoo);
+  Expect.equals(nullfoo2, corefoo);
+
+  Expect.equals('foo', MirrorSystem.getName(corefoo));
+  Expect.equals('foo', MirrorSystem.getName(mathfoo));
+  Expect.equals('foo', MirrorSystem.getName(testfoo));
+  Expect.equals('foo', MirrorSystem.getName(#foo));
+  Expect.equals('foo', MirrorSystem.getName(nullfoo1));
+  Expect.equals('foo', MirrorSystem.getName(nullfoo2));
+
+  Symbol core_foo = MirrorSystem.getSymbol('_foo', libcore);
+  Symbol math_foo = MirrorSystem.getSymbol('_foo', libmath);
+  Symbol test_foo = MirrorSystem.getSymbol('_foo', libtest);
+
+  Expect.equals('_foo', MirrorSystem.getName(core_foo));
+  Expect.equals('_foo', MirrorSystem.getName(math_foo));
+  Expect.equals('_foo', MirrorSystem.getName(test_foo));
+  Expect.equals('_foo', MirrorSystem.getName(#_foo));
+
+  Expect.notEquals(core_foo, math_foo);
+  Expect.notEquals(math_foo, test_foo);
+  Expect.notEquals(test_foo, core_foo);
+
+  Expect.notEquals(corefoo, core_foo);
+  Expect.notEquals(mathfoo, math_foo);
+  Expect.notEquals(testfoo, test_foo);
+
+  Expect.equals(test_foo, #_foo);
+
+  // Test interactions with the manglings for getters and setters, etc.
+  ClassMirror cm = reflectClass(_C);
+  Expect.equals(#_C, cm.simpleName);
+  Expect.equals('_C', MirrorSystem.getName(cm.simpleName));
+
+  MethodMirror mm = cm.declarations[#g] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isGetter);
+  Expect.equals(#g, mm.simpleName);
+  Expect.equals('g', MirrorSystem.getName(mm.simpleName));
+
+  mm = cm.declarations[const Symbol('s=')] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isSetter);
+  Expect.equals(const Symbol('s='), mm.simpleName);
+  Expect.equals('s=', MirrorSystem.getName(mm.simpleName));
+
+  mm = cm.declarations[#m] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isRegularMethod);
+  Expect.equals(#m, mm.simpleName);
+  Expect.equals('m', MirrorSystem.getName(mm.simpleName));
+
+  mm = cm.declarations[#_g] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isGetter);
+  Expect.equals(#_g, mm.simpleName);
+  Expect.equals('_g', MirrorSystem.getName(mm.simpleName));
+
+  mm = cm.declarations[MirrorSystem.getSymbol('_s=', libtest)] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isSetter);
+  Expect.equals(MirrorSystem.getSymbol('_s=', libtest), mm.simpleName);
+  Expect.equals('_s=', MirrorSystem.getName(mm.simpleName));
+
+  mm = cm.declarations[#_m] as MethodMirror;
+  Expect.isNotNull(mm);
+  Expect.isTrue(mm.isRegularMethod);
+  Expect.equals(#_m, mm.simpleName);
+  Expect.equals('_m', MirrorSystem.getName(mm.simpleName));
+
+  TypeVariableMirror tvm = cm.typeVariables[0];
+  Expect.isNotNull(tvm);
+  Expect.equals(#_T, tvm.simpleName);
+  Expect.equals('_T', MirrorSystem.getName(tvm.simpleName));
+
+  TypedefMirror tdm = reflectType(_F) as TypedefMirror;
+  Expect.equals(#_F, tdm.simpleName);
+  Expect.equals('_F', MirrorSystem.getName(tdm.simpleName));
+
+  ParameterMirror pm = (cm.declarations[#m] as MethodMirror).parameters[0];
+  Expect.equals(#_p, pm.simpleName);
+  Expect.equals('_p', MirrorSystem.getName(pm.simpleName));
+
+  // Private symbol without a library.
+  Expect.throwsArgumentError(() => MirrorSystem.getSymbol('_private'));
+}
diff --git a/tests/lib/mirrors/private_types_test.dart b/tests/lib/mirrors/private_types_test.dart
new file mode 100644
index 0000000..4d908e3
--- /dev/null
+++ b/tests/lib/mirrors/private_types_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, 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 test.private_types;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+typedef int _F(int i);
+
+class _C<_T> {}
+
+typedef int F(int i);
+
+class C<T> {}
+
+main() {
+  Expect.isTrue(reflectType(_F).isPrivate);
+  Expect.isFalse((reflectType(_F) as TypedefMirror).referent.isPrivate);
+  Expect.isTrue(reflectType(_C).isPrivate);
+  Expect.isTrue(reflectClass(_C).typeVariables.single.isPrivate);
+
+  Expect.isFalse(reflectType(F).isPrivate);
+  Expect.isFalse((reflectType(F) as TypedefMirror).referent.isPrivate);
+  Expect.isFalse(reflectType(C).isPrivate);
+  Expect.isFalse(reflectClass(C).typeVariables.single.isPrivate);
+
+  Expect.isFalse(reflectType(dynamic).isPrivate);
+  Expect.isFalse(currentMirrorSystem().dynamicType.isPrivate);
+  Expect.isFalse(currentMirrorSystem().voidType.isPrivate);
+}
diff --git a/tests/lib/mirrors/proxy_type_test.dart b/tests/lib/mirrors/proxy_type_test.dart
new file mode 100644
index 0000000..391970c
--- /dev/null
+++ b/tests/lib/mirrors/proxy_type_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.proxy_type;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+// This test is much longer that is strictly necessary to test
+// InstanceMirror.type in the face of a reflectee overriding runtimeType, but
+// shows a case where one might have legimate reason to override runtimeType.
+// See section 2.2 in Mark Miller's Robust Composition: Towards a Unified
+// Approach to Access Control and Concurrency Control.
+
+class Alice {
+  Bob bob = new Bob();
+  Carol carol = new Carol();
+  sayFooUnattenuated() {
+    bob.foo(carol);
+  }
+
+  sayFooAttenuated() {
+    bool enabled = true;
+    bool gate() => enabled;
+    bob.foo(new CarolCaretaker(carol, gate));
+    enabled = false; // Attenuate a capability
+  }
+
+  sayBar() {
+    bob.bar();
+  }
+}
+
+class Bob {
+  Carol? savedCarol;
+  foo(Carol carol) {
+    savedCarol = carol; // Store a capability
+    carol.foo();
+  }
+
+  bar() {
+    savedCarol!.foo();
+  }
+}
+
+class Carol {
+  foo() => 'c';
+}
+
+typedef bool Gate();
+
+class CarolCaretaker implements Carol {
+  final Carol _carol;
+  final Gate _gate;
+  CarolCaretaker(this._carol, this._gate);
+
+  foo() {
+    if (!_gate()) throw new NoSuchMethodError(this, #foo, [], {});
+    return _carol.foo();
+  }
+
+  Type get runtimeType => Carol;
+}
+
+main() {
+  Alice alice1 = new Alice();
+  alice1.sayFooUnattenuated();
+  alice1.sayBar(); // Bob still has authority to use Carol
+
+  Alice alice2 = new Alice();
+  alice2.sayFooAttenuated();
+  Expect.throwsNoSuchMethodError(() => alice2.sayBar(),
+      'Authority should have been attenuated');
+
+  // At the base level, a caretaker for a Carol masquerades as a Carol.
+  CarolCaretaker caretaker = new CarolCaretaker(new Carol(), () => true);
+  Expect.isTrue(caretaker is Carol);
+  Expect.equals(Carol, caretaker.runtimeType);
+
+  // At the reflective level, the caretaker is distinguishable.
+  Expect.equals(reflectClass(CarolCaretaker), reflect(caretaker).type);
+}
diff --git a/tests/lib/mirrors/raw_type_test.dart b/tests/lib/mirrors/raw_type_test.dart
new file mode 100644
index 0000000..c63e4bc
--- /dev/null
+++ b/tests/lib/mirrors/raw_type_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Foo<T> {}
+
+class Bar<T> extends Foo<T> {}
+
+main() {
+  var fooType = reflectType(Foo);
+  var fooDeclaration = fooType.originalDeclaration;
+  var barSupertype = reflect(new Bar()).type.superclass!;
+  var barSuperclass = barSupertype.originalDeclaration;
+  Expect.equals(fooDeclaration, barSuperclass, 'declarations');
+  Expect.equals(fooType, barSupertype, 'types'); //# 01: ok
+}
diff --git a/tests/lib/mirrors/redirecting_factory_different_type_test.dart b/tests/lib/mirrors/redirecting_factory_different_type_test.dart
new file mode 100644
index 0000000..cb23a9b
--- /dev/null
+++ b/tests/lib/mirrors/redirecting_factory_different_type_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mirror_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  factory A(
+    String //# 01: compile-time error
+    var    //# 02: compile-time error
+    int    //# none: ok
+      x) = B;
+  A._();
+}
+
+class B extends A {
+  var x;
+  B(int x)
+      : this.x = x,
+        super._();
+}
+
+main() {
+  var cm = reflectClass(A);
+  // The type-annotation in A's constructor must be ignored.
+  var b = cm.newInstance(Symbol.empty, [499]).reflectee;
+  Expect.equals(499, b.x);
+  Expect.throwsTypeError(() => cm.newInstance(Symbol.empty, ["str"]));
+}
diff --git a/tests/lib/mirrors/redirecting_factory_reflection_test.dart b/tests/lib/mirrors/redirecting_factory_reflection_test.dart
new file mode 100644
index 0000000..cf5d60b
--- /dev/null
+++ b/tests/lib/mirrors/redirecting_factory_reflection_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+  get t;
+  factory A() = B<T, A<T>>;
+}
+
+class B<X, Y> implements A<X> {
+  final t;
+  B() : t = Y;
+}
+
+main() {
+  ClassMirror m = reflectClass(A);
+  var i = m.newInstance(Symbol.empty, []).reflectee;
+  var s = i.t.toString();
+  Expect.isTrue(s == 'A' || s == 'A<dynamic>',
+      'mirrors should create the correct reified generic type');
+}
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
new file mode 100644
index 0000000..2f5e47a
--- /dev/null
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+import "stringify.dart";
+
+class Class<T1, T2> {
+  final field;
+  Class(this.field);
+
+  factory Class.factoryNoOptional(a, b) => new Class<T1, T2>(a - b);
+  factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional;
+
+  factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class<T1, T2>(a - b);
+  factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
+      Class.factoryUnnamedOptional;
+
+  factory Class.factoryNamedOptional(a, {b: 42}) {
+    return new Class<T1, T2>(a - b);
+  }
+
+  factory Class.redirectingFactoryNamedOptional(a, {b}) =
+      Class.factoryNamedOptional;
+
+  factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
+    return new Class<T1, T2>(a - b - c);
+  }
+
+  factory Class.redirectingFactoryMoreNamedOptional(a, {b}) =
+      Class<T1, T2>.factoryMoreNamedOptional;
+
+  factory Class.factoryMoreUnnamedOptional(a, [b = 0, c = 2]) {
+    return new Class<T1, T2>(a - b - c);
+  }
+
+  factory Class.redirectingFactoryMoreUnnamedOptional(a, [b]) =
+      Class<T1, T2>.factoryMoreUnnamedOptional;
+
+  factory Class.redirectingFactoryStringIntTypeParameters(a, b) = Class //
+      <String, int> //# 03: compile-time error
+      .factoryNoOptional;
+
+  factory Class.redirectingFactoryStringTypeParameters(a, b) = Class //
+      <String> //# 02: compile-time error
+      .factoryNoOptional;
+
+  factory Class.redirectingFactoryTypeParameters(a, b) =
+      Class<T1, T2>.factoryNoOptional;
+
+  factory Class.redirectingFactoryReversedTypeParameters(a, b) = Class //
+      <T2, T1> //# 04: compile-time error
+      .factoryNoOptional;
+}
+
+main() {
+  var classMirror = reflectClass(Class);
+
+  var instanceMirror = classMirror.newInstance(Symbol.empty, [2]);
+  Expect.equals(2, instanceMirror.reflectee.field);
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryNoOptional, [8, 6]);
+  Expect.equals(2, instanceMirror.reflectee.field);
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryUnnamedOptional, [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryMoreUnnamedOptional, [43, 1]);
+  Expect.equals(40, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror
+      .newInstance(#redirectingFactoryStringIntTypeParameters, [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryStringTypeParameters, [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, String>);
+  Expect.isTrue(instanceMirror.reflectee is Class<int, String>);
+
+  bool isDart2js = false;
+  isDart2js = true; //# 01: ok
+  if (isDart2js) return;
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryUnnamedOptional, [43]);
+  Expect.equals(1, instanceMirror.reflectee.field);
+
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryNamedOptional, [43]);
+  Expect.equals(1, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      #redirectingFactoryNamedOptional, [43], new Map()..[#b] = 1);
+  Expect.equals(42, instanceMirror.reflectee.field);
+
+  instanceMirror = classMirror.newInstance(
+      #redirectingFactoryMoreNamedOptional, [43], new Map()..[#b] = 1);
+  Expect.equals(40, instanceMirror.reflectee.field);
+
+  classMirror = reflect(new Class<String, int>(42)).type;
+  instanceMirror =
+      classMirror.newInstance(#redirectingFactoryTypeParameters, [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<String, int>);
+  Expect.isFalse(instanceMirror.reflectee is Class<int, String>);
+
+  instanceMirror = classMirror
+      .newInstance(#redirectingFactoryReversedTypeParameters, [43, 1]);
+  Expect.equals(42, instanceMirror.reflectee.field);
+  Expect.isTrue(instanceMirror.reflectee is Class<int, String>);
+  Expect.isFalse(instanceMirror.reflectee is Class<String, int>);
+}
diff --git a/tests/lib/mirrors/reflect_class_test.dart b/tests/lib/mirrors/reflect_class_test.dart
new file mode 100644
index 0000000..ca0b94d
--- /dev/null
+++ b/tests/lib/mirrors/reflect_class_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+typedef void FooFunction(int a, double b);
+
+main() {
+  Expect.throwsArgumentError(() => reflectClass(dynamic));
+  Expect.throwsArgumentError(() => reflectClass(1)); //# 01: compile-time error
+  Expect.throwsArgumentError(() => reflectClass("string")); //# 02: compile-time error
+  Expect.throwsArgumentError(() => reflectClass(FooFunction));
+}
diff --git a/tests/lib/mirrors/reflect_model_test.dart b/tests/lib/mirrors/reflect_model_test.dart
new file mode 100644
index 0000000..416f041
--- /dev/null
+++ b/tests/lib/mirrors/reflect_model_test.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.reflect_model_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'model.dart';
+import 'stringify.dart';
+
+variablesOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is VariableMirror) result[k] = v;
+  });
+  return result;
+}
+
+gettersOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isGetter) result[k] = v;
+  });
+  return result;
+}
+
+settersOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isSetter) result[k] = v;
+  });
+  return result;
+}
+
+methodsOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isRegularMethod) result[k] = v;
+  });
+  return result;
+}
+
+main() {
+  var unnamed = new Symbol('');
+  var field = new Symbol('field');
+  var instanceMethod = new Symbol('instanceMethod');
+  var accessor = new Symbol('accessor');
+  var aMethod = new Symbol('aMethod');
+  var bMethod = new Symbol('bMethod');
+  var cMethod = new Symbol('cMethod');
+
+  var aClass = reflectClass(A);
+  var bClass = reflectClass(B);
+  var cClass = reflectClass(C);
+  var a = aClass.newInstance(unnamed, []);
+  var b = bClass.newInstance(unnamed, []);
+  var c = cClass.newInstance(unnamed, []);
+
+  expect('{field: Variable(s(field) in s(A))}', variablesOf(aClass));
+  expect('{}', variablesOf(bClass));
+  expect('{}', variablesOf(cClass));
+
+  Expect.isNull(a.getField(field).reflectee);
+  Expect.equals('B:get field', b.getField(field).reflectee);
+  Expect.equals('B:get field', c.getField(field).reflectee);
+
+  Expect.equals(42, a.setField(field, 42).reflectee);
+  Expect.equals(87, b.setField(field, 87).reflectee);
+  Expect.equals(89, c.setField(field, 89).reflectee);
+
+  Expect.equals(42, a.getField(field).reflectee);
+  Expect.equals('B:get field', b.getField(field).reflectee);
+  Expect.equals('B:get field', c.getField(field).reflectee);
+  Expect.equals(89, fieldC);
+
+  expect(
+      '{accessor: Method(s(accessor) in s(A), getter)'
+      '}',
+      gettersOf(aClass));
+  expect(
+      '{accessor: Method(s(accessor) in s(B), getter)'
+      ', field: Method(s(field) in s(B), getter)}',
+      gettersOf(bClass));
+  expect('{accessor: Method(s(accessor) in s(C), getter)}', gettersOf(cClass));
+
+  expect(
+      '{accessor=: Method(s(accessor=) in s(A), setter)'
+      '}',
+      settersOf(aClass));
+  expect(
+      '{accessor=: Method(s(accessor=) in s(B), setter)}', settersOf(bClass));
+  expect(
+      '{accessor=: Method(s(accessor=) in s(C), setter)'
+      ', field=: Method(s(field=) in s(C), setter)}',
+      settersOf(cClass));
+
+  Expect.equals('A:instanceMethod(7)', a.invoke(instanceMethod, [7]).reflectee);
+  Expect.equals('B:instanceMethod(9)', b.invoke(instanceMethod, [9]).reflectee);
+  Expect.equals(
+      'C:instanceMethod(13)', c.invoke(instanceMethod, [13]).reflectee);
+
+  expect(
+      '{aMethod: Method(s(aMethod) in s(A))'
+      ', instanceMethod: Method(s(instanceMethod) in s(A))}',
+      methodsOf(aClass));
+
+  expect(
+      '{bMethod: Method(s(bMethod) in s(B))'
+      ', instanceMethod: Method(s(instanceMethod) in s(B))}',
+      methodsOf(bClass));
+  expect(
+      '{cMethod: Method(s(cMethod) in s(C))'
+      ', instanceMethod: Method(s(instanceMethod) in s(C))}',
+      methodsOf(cClass));
+
+  Expect.equals('A:get accessor', a.getField(accessor).reflectee);
+  Expect.equals('B:get accessor', b.getField(accessor).reflectee);
+  Expect.equals('C:get accessor', c.getField(accessor).reflectee);
+
+  Expect.equals('foo', a.setField(accessor, 'foo').reflectee);
+  Expect.equals('bar', b.setField(accessor, 'bar').reflectee);
+  Expect.equals('baz', c.setField(accessor, 'baz').reflectee);
+
+  Expect.equals('foo', accessorA);
+  Expect.equals('bar', accessorB);
+  Expect.equals('baz', accessorC);
+
+  Expect.equals('aMethod', a.invoke(aMethod, []).reflectee);
+  Expect.equals('aMethod', b.invoke(aMethod, []).reflectee);
+  Expect.equals('aMethod', c.invoke(aMethod, []).reflectee);
+
+  Expect.throwsNoSuchMethodError(() => a.invoke(bMethod, []));
+  Expect.equals('bMethod', b.invoke(bMethod, []).reflectee);
+  Expect.equals('bMethod', c.invoke(bMethod, []).reflectee);
+
+  Expect.throwsNoSuchMethodError(() => a.invoke(cMethod, []));
+  Expect.throwsNoSuchMethodError(() => b.invoke(cMethod, []));
+  Expect.equals('cMethod', c.invoke(cMethod, []).reflectee);
+}
diff --git a/tests/lib/mirrors/reflect_runtime_type_test.dart b/tests/lib/mirrors/reflect_runtime_type_test.dart
new file mode 100644
index 0000000..a5e96b6
--- /dev/null
+++ b/tests/lib/mirrors/reflect_runtime_type_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A simple test that ensure that reflection works on runtime types of
+// instantiated classes.
+
+import "dart:mirrors";
+
+class Foo {
+  int a = 0;
+}
+
+main() {
+  var m = reflectClass(new Foo().runtimeType);
+  var field = publicFields(m).single;
+  if (MirrorSystem.getName(field.simpleName) != 'a') {
+    throw 'Expected "a", but got "${MirrorSystem.getName(field.simpleName)}"';
+  }
+  print(field);
+}
+
+publicFields(ClassMirror mirror) => mirror.declarations.values
+    .where((x) => x is VariableMirror && !(x.isPrivate || x.isStatic));
diff --git a/tests/lib/mirrors/reflect_two_classes_test.dart b/tests/lib/mirrors/reflect_two_classes_test.dart
new file mode 100644
index 0000000..65f103b
--- /dev/null
+++ b/tests/lib/mirrors/reflect_two_classes_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a regression test for http://dartbug.com/23054
+
+library index;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+main() {
+  var bar = new Bar();
+  var barMirror = reflect(bar);
+  Expect.equals(42, barMirror.getField(#bar).reflectee, "bar field");
+  Expect.equals(42, barMirror.invoke(#getBar, []).reflectee, "getBar Method");
+
+  var foo = new Foo();
+  var fooMirror = reflect(foo);
+  Expect.equals(9, fooMirror.getField(#foo).reflectee, "foo field");
+  Expect.equals(9, fooMirror.invoke(#getFoo, []).reflectee, "getFoo Method");
+}
+
+class Bar {
+  int bar = 42;
+
+  int getBar() => bar;
+}
+
+class Foo {
+  int foo = 9;
+
+  int getFoo() => foo;
+}
diff --git a/tests/lib/mirrors/reflect_uninstantiated_class_test.dart b/tests/lib/mirrors/reflect_uninstantiated_class_test.dart
new file mode 100644
index 0000000..bfbdadb
--- /dev/null
+++ b/tests/lib/mirrors/reflect_uninstantiated_class_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A simple test that ensure that reflection works on uninstantiated classes.
+
+import "dart:mirrors";
+
+class Foo {
+  int a = 0;
+}
+
+main() {
+  // Do NOT instantiate Foo.
+  var m = reflectClass(Foo);
+  var field = publicFields(m).single;
+  if (MirrorSystem.getName(field.simpleName) != 'a') {
+    throw 'Expected "a", but got "${MirrorSystem.getName(field.simpleName)}"';
+  }
+  print(field);
+}
+
+publicFields(ClassMirror mirror) => mirror.declarations.values
+    .where((x) => x is VariableMirror && !(x.isPrivate || x.isStatic));
diff --git a/tests/lib/mirrors/reflected_type_classes_test.dart b/tests/lib/mirrors/reflected_type_classes_test.dart
new file mode 100644
index 0000000..a05b564
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_classes_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2014, 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 test.reflected_type_classes;
+
+import 'dart:mirrors';
+
+import 'reflected_type_helper.dart';
+
+class A<T> {}
+
+class B extends A {}
+
+class C extends A<num, int> {} // //# 01: compile-time error
+class D extends A<int> {}
+
+class E<S> extends A<S> {}
+
+class F<R> extends A<int> {}
+
+class G {}
+
+class H<A, B, C> {}
+
+main() {
+  // Declarations.
+  expectReflectedType(reflectClass(A), null);
+  expectReflectedType(reflectClass(B), B);
+  expectReflectedType(reflectClass(C), C); // //# 01: continued
+  expectReflectedType(reflectClass(D), D);
+  expectReflectedType(reflectClass(E), null);
+  expectReflectedType(reflectClass(F), null);
+  expectReflectedType(reflectClass(G), G);
+  expectReflectedType(reflectClass(H), null);
+
+  // Instantiations.
+  expectReflectedType(reflect(new A()).type, new A().runtimeType);
+  expectReflectedType(reflect(new B()).type, new B().runtimeType);
+  expectReflectedType(reflect(new C()).type, new C().runtimeType); // //# 01: continued
+  expectReflectedType(reflect(new D()).type, new D().runtimeType);
+  expectReflectedType(reflect(new E()).type, new E().runtimeType);
+  expectReflectedType(reflect(new F()).type, new F().runtimeType);
+  expectReflectedType(reflect(new G()).type, new G().runtimeType);
+  expectReflectedType(reflect(new H()).type, new H().runtimeType);
+
+  expectReflectedType(reflect(new A<num>()).type, new A<num>().runtimeType);
+  expectReflectedType(reflect(new B<num>()).type.superclass!, // //# 02: compile-time error
+                      new A<dynamic>().runtimeType); //          //# 02: continued
+  expectReflectedType(reflect(new C<num>()).type.superclass!, // //# 01: continued
+                      new A<dynamic>().runtimeType); //          //# 01: continued
+  expectReflectedType(reflect(new D<num>()).type.superclass!, // //# 03: compile-time error
+                      new A<int>().runtimeType); //              //# 03: continued
+  expectReflectedType(reflect(new E<num>()).type, new E<num>().runtimeType);
+  expectReflectedType(
+      reflect(new E<num>()).type.superclass!, new A<num>().runtimeType);
+  expectReflectedType(
+      reflect(new F<num>()).type.superclass!, new A<int>().runtimeType);
+  expectReflectedType(reflect(new F<num>()).type, new F<num>().runtimeType);
+  expectReflectedType(
+      reflect(new H<num, num, num>()).type, new H<num, num, num>().runtimeType);
+}
diff --git a/tests/lib/mirrors/reflected_type_function_type_test.dart b/tests/lib/mirrors/reflected_type_function_type_test.dart
new file mode 100644
index 0000000..53132a3
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_function_type_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, 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 test.reflected_type_function_types;
+
+import 'dart:mirrors';
+
+import 'reflected_type_helper.dart';
+
+typedef bool Predicate(num n);
+
+bool somePredicate(num n) => n < 0;
+
+main() {
+  FunctionTypeMirror numToBool1 =
+      reflect(somePredicate).type as FunctionTypeMirror;
+  FunctionTypeMirror numToBool2 =
+      (reflectType(Predicate) as TypedefMirror).referent;
+
+  expectReflectedType(numToBool1, somePredicate.runtimeType);
+  expectReflectedType(numToBool2, Predicate);
+}
diff --git a/tests/lib/mirrors/reflected_type_generics_test.dart b/tests/lib/mirrors/reflected_type_generics_test.dart
new file mode 100644
index 0000000..4e84300
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_generics_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.reflected_type_generics_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'reflected_type_helper.dart';
+
+class A<T> {}
+
+class P {}
+
+class B extends A<P> {}
+
+class C<K, V> {}
+
+class D<T> extends A<T> {}
+
+class E<K> extends C<K, int> {}
+
+class F<G> {}
+
+typedef bool Predicate<T>(T arg);
+
+class FBounded<S extends FBounded<S>> {}
+
+class Helper<T> {
+  Type get param => T;
+}
+
+class Mixin<T extends P> {}
+
+class Composite<K extends P, V> extends Object with Mixin<K> {}
+
+main() {
+  // "Happy" paths:
+  expectReflectedType(reflectType(A, [P]), new A<P>().runtimeType);
+  expectReflectedType(reflectType(C, [B, P]), new C<B, P>().runtimeType);
+  expectReflectedType(reflectType(D, [P]), new D<P>().runtimeType);
+  expectReflectedType(reflectType(E, [P]), new E<P>().runtimeType);
+  expectReflectedType(
+      reflectType(FBounded, [new FBounded<Null>().runtimeType]), new FBounded<FBounded<Null>>().runtimeType);
+
+  var predicateHelper = new Helper<Predicate<P>>();
+  expectReflectedType(reflectType(Predicate, [P]), predicateHelper.param); //# 01: ok
+  var composite = new Composite<P, int>();
+  expectReflectedType(reflectType(Composite, [P, int]), composite.runtimeType);
+
+  // Edge cases:
+  Expect.throws(
+      () => reflectType(P, []),
+      (e) => e is ArgumentError && e.invalidValue is List,
+      "Should throw an ArgumentError if reflecting not a generic class with "
+      "empty list of type arguments");
+  Expect.throws( //                                                             //# 03: ok
+      () => reflectType(P, [B]), //                                             //# 03: continued
+      (e) => e is Error, //                                                     //# 03: continued
+      "Should throw an ArgumentError if reflecting not a generic class with " //# 03: continued
+      "some type arguments"); //                                                //# 03: continued
+  Expect.throws(
+      () => reflectType(A, []),
+      (e) => e is ArgumentError && e.invalidValue is List,
+      "Should throw an ArgumentError if type argument list is empty for a "
+      "generic class");
+  Expect.throws( //                                                             //# 04: ok
+      () => reflectType(A, [P, B]), //                                          //# 04: continued
+      (e) => e is ArgumentError && e.invalidValue is List, //                   //# 04: continued
+      "Should throw an ArgumentError if number of type arguments is not " //    //# 04: continued
+      "correct"); //                                                            //# 04: continued
+  Expect.throws(() => reflectType(B, [P]), (e) => e is Error, //            //# 05: ok
+      "Should throw an ArgumentError for non-generic class extending " //   //# 05: continued
+      "generic one"); //                                                    //# 05: continued
+/*  Expect.throws(
+      () => reflectType(A, ["non-type"]),
+      (e) => e is ArgumentError && e.invalidValue is List,
+      "Should throw an ArgumentError when any of type arguments is not a
+      Type");*/
+  Expect.throws( //                                                                //# 06: ok
+      () => reflectType(A, [P, B]), //                                              //# 06: continued
+      (e) => e is ArgumentError && e.invalidValue is List, //                       //# 06: continued
+      "Should throw an ArgumentError if number of type arguments is not correct " //# 06: continued
+      "for generic extending another generic"); //                                  //# 06: continued
+  Expect.throws(
+      () => reflectType(reflectType(F).typeVariables[0].reflectedType, [int]));
+  Expect.throws(() => reflectType(FBounded, [int])); //# 02: ok
+  var boundedType =
+      reflectType(FBounded).typeVariables[0].upperBound.reflectedType;
+  Expect.throws(() => reflectType(boundedType, [int])); //# 02: ok
+  Expect.throws(() => reflectType(Composite, [int, int])); //# 02: ok
+
+  // Instantiation of a generic class preserves type information:
+  ClassMirror m = reflectType(A, [P]) as ClassMirror;
+  var instance = m.newInstance(Symbol.empty, []).reflectee;
+  Expect.equals(new A<P>().runtimeType, instance.runtimeType);
+}
diff --git a/tests/lib/mirrors/reflected_type_helper.dart b/tests/lib/mirrors/reflected_type_helper.dart
new file mode 100644
index 0000000..897dc6a
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_helper.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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 test.reflected_type_helper;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+expectReflectedType(TypeMirror typeMirror, Type? expectedType) {
+  if (expectedType == null) {
+    Expect.isFalse(typeMirror.hasReflectedType);
+    Expect.throwsUnsupportedError(() => typeMirror.reflectedType,
+        "Should not have a reflected type");
+  } else {
+    Expect.isTrue(typeMirror.hasReflectedType);
+    Expect.equals(expectedType, typeMirror.reflectedType);
+  }
+}
diff --git a/tests/lib/mirrors/reflected_type_special_types_test.dart b/tests/lib/mirrors/reflected_type_special_types_test.dart
new file mode 100644
index 0000000..4fe7261
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_special_types_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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 test.reflected_type_special_types;
+
+import 'dart:mirrors';
+
+import 'reflected_type_helper.dart';
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+  TypeMirror dynamicMirror2 = reflectType(dynamic);
+  TypeMirror voidMirror = currentMirrorSystem().voidType;
+
+  expectReflectedType(dynamicMirror, dynamic);
+  expectReflectedType(dynamicMirror2, dynamic);
+  expectReflectedType(voidMirror, null);
+}
diff --git a/tests/lib/mirrors/reflected_type_test.dart b/tests/lib/mirrors/reflected_type_test.dart
new file mode 100644
index 0000000..4b07e43
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.reflected_type_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class B extends A {}
+
+class C extends A<num, int> {} // //# 01: compile-time error
+class D extends A<int> {}
+
+class E<S> extends A<S> {}
+
+class F<R> extends A<int> {}
+
+class G {}
+
+class H<A, B, C> {}
+
+expectReflectedType(classMirror, expectedType) {
+  if (expectedType == null) {
+    Expect.isFalse(classMirror.hasReflectedType,
+        "$classMirror should not have a reflected type");
+    Expect.throwsUnsupportedError(() => classMirror.reflectedType);
+  } else {
+    Expect.isTrue(classMirror.hasReflectedType,
+        "$classMirror should have a reflected type");
+    Expect.equals(expectedType, classMirror.reflectedType);
+  }
+}
+
+main() {
+  // Basic non-generic types, including intercepted types.
+  expectReflectedType(reflectClass(Object), Object);
+  expectReflectedType(reflectClass(String), String);
+  expectReflectedType(reflectClass(int), int);
+  expectReflectedType(reflectClass(num), num);
+  expectReflectedType(reflectClass(double), double);
+  expectReflectedType(reflectClass(bool), bool);
+  expectReflectedType(reflectClass(Null), Null);
+
+  // Declarations.
+  expectReflectedType(reflectClass(A), null);
+  expectReflectedType(reflectClass(B), B);
+  expectReflectedType(reflectClass(C), C); // //# 01: continued
+  expectReflectedType(reflectClass(D), D);
+  expectReflectedType(reflectClass(E), null);
+  expectReflectedType(reflectClass(F), null);
+  expectReflectedType(reflectClass(G), G);
+  expectReflectedType(reflectClass(H), null);
+
+  // Instantiations.
+  expectReflectedType(reflect(new A()).type, new A().runtimeType);
+  expectReflectedType(reflect(new B()).type, new B().runtimeType);
+  expectReflectedType(reflect(new C()).type, new C().runtimeType); // //# 01: continued
+  expectReflectedType(reflect(new D()).type, new D().runtimeType);
+  expectReflectedType(reflect(new E()).type, new E().runtimeType);
+  expectReflectedType(reflect(new F()).type, new F().runtimeType);
+  expectReflectedType(reflect(new G()).type, new G().runtimeType);
+  expectReflectedType(reflect(new H()).type, new H().runtimeType);
+
+  expectReflectedType(reflect(new A<num>()).type, new A<num>().runtimeType);
+  expectReflectedType(reflect(new B<num>()).type.superclass, // //# 02: compile-time error
+                      new A<dynamic>().runtimeType); //         //# 02: continued
+  expectReflectedType(reflect(new C<num>()).type.superclass, // //# 01: continued
+                      new A<dynamic>().runtimeType); //         //# 01: continued
+  expectReflectedType(reflect(new D<num>()).type.superclass, // //# 03: compile-time error
+                      new A<int>().runtimeType); //             //# 03: continued
+  expectReflectedType(reflect(new E<num>()).type, new E<num>().runtimeType);
+  expectReflectedType(
+      reflect(new E<num>()).type.superclass, new A<num>().runtimeType);
+  expectReflectedType(
+      reflect(new F<num>()).type.superclass, new A<int>().runtimeType);
+  expectReflectedType(reflect(new F<num>()).type, new F<num>().runtimeType);
+  expectReflectedType(
+      reflect(new H<num, num, num>()).type, new H<num, num, num>().runtimeType);
+}
diff --git a/tests/lib/mirrors/reflected_type_typedefs_test.dart b/tests/lib/mirrors/reflected_type_typedefs_test.dart
new file mode 100644
index 0000000..03673d7
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_typedefs_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, 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 test.reflected_type_typedefs;
+
+import 'dart:mirrors';
+
+import 'reflected_type_helper.dart';
+
+typedef bool NonGenericPredicate(num n);
+typedef bool GenericPredicate<T>(T t);
+typedef S GenericTransform<S>(S s);
+
+main() {
+  final nonGenericPredicate = reflectType(NonGenericPredicate) as TypedefMirror;
+  final predicateOfDynamic = reflectType(GenericPredicate) as TypedefMirror;
+  final transformOfDynamic = reflectType(GenericTransform) as TypedefMirror;
+
+  final predicateDecl = predicateOfDynamic.originalDeclaration as TypedefMirror;
+  final transformDecl = transformOfDynamic.originalDeclaration as TypedefMirror;
+
+  expectReflectedType(nonGenericPredicate, NonGenericPredicate);
+  expectReflectedType(predicateOfDynamic, GenericPredicate);
+  expectReflectedType(transformOfDynamic, GenericTransform);
+  expectReflectedType(predicateDecl, null);
+  expectReflectedType(transformDecl, null);
+}
diff --git a/tests/lib/mirrors/reflected_type_typevars_test.dart b/tests/lib/mirrors/reflected_type_typevars_test.dart
new file mode 100644
index 0000000..a43c055
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_typevars_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, 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 test.reflected_type_type_variables;
+
+import 'dart:mirrors';
+
+import 'reflected_type_helper.dart';
+
+class Class<T> {}
+
+typedef bool Predicate<S>(S t);
+
+main() {
+  TypeVariableMirror tFromClass = reflectClass(Class).typeVariables[0];
+  TypeVariableMirror sFromPredicate = reflectType(Predicate).typeVariables[0];
+
+  expectReflectedType(tFromClass, null);
+  expectReflectedType(sFromPredicate, null);
+}
diff --git a/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
new file mode 100644
index 0000000..63cbb99
--- /dev/null
+++ b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Ensure that otherwise uninstantiated classes can be instantiated
+// reflectively.
+
+import "dart:mirrors";
+
+class Foo {
+  int a = 0;
+}
+
+main() {
+  // Do NOT instantiate Foo.
+  var m = reflectClass(Foo);
+  var instance = m.newInstance(Symbol.empty, []);
+  print(instance);
+  bool threw = false;
+  try {
+    m.newInstance(#noSuchConstructor, []);
+    throw 'Expected an exception';
+  } on NoSuchMethodError catch (e) {
+    print(e);
+    threw = true;
+  }
+  if (!threw) throw 'Expected a NoSuchMethodError';
+}
diff --git a/tests/lib/mirrors/regress_13462_0_test.dart b/tests/lib/mirrors/regress_13462_0_test.dart
new file mode 100644
index 0000000..b87bf1f
--- /dev/null
+++ b/tests/lib/mirrors/regress_13462_0_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+main() {
+  print(MirrorSystem.getName(#foo));
+}
diff --git a/tests/lib/mirrors/regress_13462_1_test.dart b/tests/lib/mirrors/regress_13462_1_test.dart
new file mode 100644
index 0000000..bffdd03
--- /dev/null
+++ b/tests/lib/mirrors/regress_13462_1_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+
+main() {
+  var name = MirrorSystem.getName(#foo);
+  if (name != 'foo') throw 'Wrong name: $name != foo';
+}
diff --git a/tests/lib/mirrors/regress_14304_test.dart b/tests/lib/mirrors/regress_14304_test.dart
new file mode 100644
index 0000000..293fcea
--- /dev/null
+++ b/tests/lib/mirrors/regress_14304_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for Issue 14304.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class A<T> {
+  T m() {}
+}
+
+main() {
+  ClassMirror a = reflectClass(A);
+  TypeVariableMirror t = a.typeVariables[0];
+  MethodMirror m = a.declarations[#m] as MethodMirror;
+
+  Expect.equals(t, m.returnType);
+}
diff --git a/tests/lib/mirrors/regress_16321_test.dart b/tests/lib/mirrors/regress_16321_test.dart
new file mode 100644
index 0000000..6ccf0b2
--- /dev/null
+++ b/tests/lib/mirrors/regress_16321_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for Issue 16321.
+// (Type errors in metadata crashed the VM in checked mode).
+
+import "dart:mirrors";
+
+class TypedBox {
+  final List<String> contents;
+  const TypedBox(this.contents);
+}
+
+@TypedBox('foo') //# 01: compile-time error
+@TypedBox(const ['foo'])
+class C {}
+
+main() {
+  reflectClass(C).metadata;
+}
diff --git a/tests/lib/mirrors/regress_18535_test.dart b/tests/lib/mirrors/regress_18535_test.dart
new file mode 100644
index 0000000..2abb964
--- /dev/null
+++ b/tests/lib/mirrors/regress_18535_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 18535.
+
+import 'dart:mirrors';
+import 'package:collection/collection.dart';
+
+void main() {
+  print(currentMirrorSystem().libraries);
+}
diff --git a/tests/lib/mirrors/regress_19731_test.dart b/tests/lib/mirrors/regress_19731_test.dart
new file mode 100644
index 0000000..358098e
--- /dev/null
+++ b/tests/lib/mirrors/regress_19731_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2014, 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.
+
+@metadata
+library regress_19731;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+@metadata
+const metadata = const Object();
+
+class OneField {
+  @metadata
+  var onlyClassField;
+
+  @metadata
+  method() {}
+}
+
+@metadata
+method() {}
+
+main() {
+  dynamic classMirror = reflectType(OneField);
+  var classFieldNames = classMirror.declarations.values
+      .where((v) => v is VariableMirror)
+      .map((v) => v.simpleName)
+      .toList();
+  Expect.setEquals([#onlyClassField], classFieldNames);
+
+  dynamic libraryMirror = classMirror.owner;
+  var libraryFieldNames = libraryMirror.declarations.values
+      .where((v) => v is VariableMirror)
+      .map((v) => v.simpleName)
+      .toList();
+  Expect.setEquals([#metadata], libraryFieldNames);
+}
diff --git a/tests/lib/mirrors/regress_26187_test.dart b/tests/lib/mirrors/regress_26187_test.dart
new file mode 100644
index 0000000..6c381c7
--- /dev/null
+++ b/tests/lib/mirrors/regress_26187_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class A {
+  const A();
+}
+
+class B {
+  const B();
+}
+
+typedef void f(@A() int, String);
+
+typedef void g(@B() int, String);
+
+main() {
+  ParameterMirror fParamMirror =
+      (reflectType(f) as TypedefMirror).referent.parameters[0];
+  ParameterMirror gParamMirror =
+      (reflectType(g) as TypedefMirror).referent.parameters[0];
+  Expect.equals(
+      '.A', MirrorSystem.getName(fParamMirror.metadata[0].type.qualifiedName));
+  Expect.equals(
+      '.B', MirrorSystem.getName(gParamMirror.metadata[0].type.qualifiedName));
+}
diff --git a/tests/lib/mirrors/regress_28255_test.dart b/tests/lib/mirrors/regress_28255_test.dart
new file mode 100644
index 0000000..b127045
--- /dev/null
+++ b/tests/lib/mirrors/regress_28255_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 28255
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Class {
+  noSuchMethod(i) => true;
+
+  foo() {
+    dynamic o = this;
+    Expect.isFalse(o.bar is Null);
+    Expect.isTrue(o.bar != null);
+    Expect.equals(true.runtimeType, o.bar.runtimeType);
+  }
+}
+
+main() {
+  reflectClass(Class).newInstance(Symbol.empty, []).reflectee.foo();
+}
diff --git a/tests/lib/mirrors/regress_33259_test.dart b/tests/lib/mirrors/regress_33259_test.dart
new file mode 100644
index 0000000..af2b4eb
--- /dev/null
+++ b/tests/lib/mirrors/regress_33259_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for http://dartbug.com/33259.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+void main() {
+  final foo = reflectClass(Thing).declarations[#foo] as VariableMirror;
+  Expect.isTrue(foo.metadata[0].reflectee is Sub);
+}
+
+class Thing {
+  @Sub()
+  String foo = "initialized";
+}
+
+class Base<T> {
+  const Base();
+}
+
+class Sub extends Base<String> {
+  const Sub();
+}
diff --git a/tests/lib/mirrors/regress_34982_test.dart b/tests/lib/mirrors/regress_34982_test.dart
new file mode 100644
index 0000000..f86df29
--- /dev/null
+++ b/tests/lib/mirrors/regress_34982_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Regression test for http://dartbug.com/34982
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+abstract class A {
+  int c();
+}
+
+class B implements A {
+  dynamic noSuchMethod(Invocation invocation) {}
+}
+
+void main() {
+  MethodMirror method1 = reflectClass(B).declarations[#c] as MethodMirror;
+  Expect.isTrue(method1.isSynthetic);
+
+  MethodMirror method2 =
+      reflectClass(B).declarations[#noSuchMethod] as MethodMirror;
+  Expect.isFalse(method2.isSynthetic);
+
+  MethodMirror method3 = reflectClass(A).declarations[#c] as MethodMirror;
+  Expect.isFalse(method3.isSynthetic);
+}
diff --git a/tests/lib/mirrors/regress_38035_test.dart b/tests/lib/mirrors/regress_38035_test.dart
new file mode 100644
index 0000000..4e6c25a
--- /dev/null
+++ b/tests/lib/mirrors/regress_38035_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/38035.
+//
+// Verifies that static tear-off has correct information about argument types.
+
+import 'package:expect/expect.dart';
+import 'dart:mirrors';
+
+class A {
+  static bool _defaultCheck([dynamic e]) => true;
+}
+
+main() {
+  Expect.equals('([dynamic]) -> dart.core.bool',
+      MirrorSystem.getName(reflect(A._defaultCheck).type.simpleName));
+}
diff --git a/tests/lib/mirrors/relation_assignable_test.dart b/tests/lib/mirrors/relation_assignable_test.dart
new file mode 100644
index 0000000..da4c13d
--- /dev/null
+++ b/tests/lib/mirrors/relation_assignable_test.dart
@@ -0,0 +1,328 @@
+// Copyright (c) 2014, 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 test.relation_assignable;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class Superclass {}
+
+class Subclass1 extends Superclass {}
+
+class Subclass2 extends Superclass {}
+
+typedef bool NumberPredicate(num x);
+typedef bool IntegerPredicate(int x);
+typedef bool DoublePredicate(double x);
+
+typedef num NumberGenerator();
+typedef int IntegerGenerator();
+typedef double DoubleGenerator();
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+class C<T extends num> {}
+
+test(MirrorSystem mirrors) {
+  LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core);
+  LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_assignable);
+
+  // Classes.
+  TypeMirror Super = thisLibrary.declarations[#Superclass] as TypeMirror;
+  TypeMirror Sub1 = thisLibrary.declarations[#Subclass1] as TypeMirror;
+  TypeMirror Sub2 = thisLibrary.declarations[#Subclass2] as TypeMirror;
+  TypeMirror Obj = coreLibrary.declarations[#Object] as TypeMirror;
+  TypeMirror Nul = coreLibrary.declarations[#Null] as TypeMirror;
+
+  Expect.isTrue(Obj.isAssignableTo(Obj));
+  Expect.isTrue(Super.isAssignableTo(Super));
+  Expect.isTrue(Sub1.isAssignableTo(Sub1));
+  Expect.isTrue(Sub2.isAssignableTo(Sub2));
+  Expect.isTrue(Nul.isAssignableTo(Nul));
+
+  Expect.isTrue(Sub1.isAssignableTo(Super));
+  Expect.isTrue(Super.isAssignableTo(Sub1));
+
+  Expect.isTrue(Sub2.isAssignableTo(Super));
+  Expect.isTrue(Super.isAssignableTo(Sub2));
+
+  Expect.isFalse(Sub2.isAssignableTo(Sub1));
+  Expect.isFalse(Sub1.isAssignableTo(Sub2));
+
+  Expect.isTrue(Sub1.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Sub1));
+
+  Expect.isTrue(Sub2.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Sub2));
+
+  Expect.isTrue(Super.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Super));
+
+  Expect.isTrue(Nul.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Nul));
+  Expect.isTrue(Nul.isAssignableTo(Super)); // Null type is bottom type.
+  Expect.isTrue(Super.isAssignableTo(Nul));
+
+  // Function typedef - argument type.
+  TypeMirror Func = coreLibrary.declarations[#Function] as TypeMirror;
+  TypedefMirror NumPred =
+      thisLibrary.declarations[#NumberPredicate] as TypedefMirror;
+  TypedefMirror IntPred =
+      thisLibrary.declarations[#IntegerPredicate] as TypedefMirror;
+  TypedefMirror DubPred =
+      thisLibrary.declarations[#DoublePredicate] as TypedefMirror;
+
+  Expect.isTrue(Func.isAssignableTo(Func));
+  Expect.isTrue(NumPred.isAssignableTo(NumPred));
+  Expect.isTrue(IntPred.isAssignableTo(IntPred));
+  Expect.isTrue(DubPred.isAssignableTo(DubPred));
+
+  Expect.isTrue(NumPred.isAssignableTo(Func));
+  Expect.isTrue(NumPred.isAssignableTo(IntPred));
+  Expect.isTrue(NumPred.isAssignableTo(DubPred));
+
+  Expect.isTrue(IntPred.isAssignableTo(Func));
+  Expect.isTrue(IntPred.isAssignableTo(NumPred));
+  Expect.isFalse(IntPred.isAssignableTo(DubPred));
+
+  Expect.isTrue(DubPred.isAssignableTo(Func));
+  Expect.isTrue(DubPred.isAssignableTo(NumPred));
+  Expect.isFalse(DubPred.isAssignableTo(IntPred));
+
+  Expect.isTrue(Func.isAssignableTo(Obj));
+  Expect.isTrue(NumPred.isAssignableTo(Obj));
+  Expect.isTrue(IntPred.isAssignableTo(Obj));
+  Expect.isTrue(DubPred.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Func));
+  Expect.isTrue(Obj.isAssignableTo(NumPred));
+  Expect.isTrue(Obj.isAssignableTo(IntPred));
+  Expect.isTrue(Obj.isAssignableTo(DubPred));
+
+  // Function typedef - return type.
+  TypedefMirror NumGen =
+      thisLibrary.declarations[#NumberGenerator] as TypedefMirror;
+  TypedefMirror IntGen =
+      thisLibrary.declarations[#IntegerGenerator] as TypedefMirror;
+  TypedefMirror DubGen =
+      thisLibrary.declarations[#DoubleGenerator] as TypedefMirror;
+
+  Expect.isTrue(NumGen.isAssignableTo(NumGen));
+  Expect.isTrue(IntGen.isAssignableTo(IntGen));
+  Expect.isTrue(DubGen.isAssignableTo(DubGen));
+
+  Expect.isTrue(NumGen.isAssignableTo(Func));
+  Expect.isTrue(NumGen.isAssignableTo(IntGen));
+  Expect.isTrue(NumGen.isAssignableTo(DubGen));
+
+  Expect.isTrue(IntGen.isAssignableTo(Func));
+  Expect.isTrue(IntGen.isAssignableTo(NumGen));
+  Expect.isFalse(IntGen.isAssignableTo(DubGen));
+
+  Expect.isTrue(DubGen.isAssignableTo(Func));
+  Expect.isTrue(DubGen.isAssignableTo(NumGen));
+  Expect.isFalse(DubGen.isAssignableTo(IntGen));
+
+  Expect.isTrue(Func.isAssignableTo(Obj));
+  Expect.isTrue(NumGen.isAssignableTo(Obj));
+  Expect.isTrue(IntGen.isAssignableTo(Obj));
+  Expect.isTrue(DubGen.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Func));
+  Expect.isTrue(Obj.isAssignableTo(NumGen));
+  Expect.isTrue(Obj.isAssignableTo(IntGen));
+  Expect.isTrue(Obj.isAssignableTo(DubGen));
+
+  // Function - argument type.
+  TypeMirror NumPredRef = NumPred.referent;
+  TypeMirror IntPredRef = IntPred.referent;
+  TypeMirror DubPredRef = DubPred.referent;
+
+  Expect.isTrue(Func.isAssignableTo(Func));
+  Expect.isTrue(NumPredRef.isAssignableTo(NumPredRef));
+  Expect.isTrue(IntPredRef.isAssignableTo(IntPredRef));
+  Expect.isTrue(DubPredRef.isAssignableTo(DubPredRef));
+
+  Expect.isTrue(NumPredRef.isAssignableTo(Func));
+  Expect.isTrue(NumPredRef.isAssignableTo(IntPredRef));
+  Expect.isTrue(NumPredRef.isAssignableTo(DubPredRef));
+
+  Expect.isTrue(IntPredRef.isAssignableTo(Func));
+  Expect.isTrue(IntPredRef.isAssignableTo(NumPredRef));
+  Expect.isFalse(IntPredRef.isAssignableTo(DubPredRef));
+
+  Expect.isTrue(DubPredRef.isAssignableTo(Func));
+  Expect.isTrue(DubPredRef.isAssignableTo(NumPredRef));
+  Expect.isFalse(DubPredRef.isAssignableTo(IntPredRef));
+
+  Expect.isTrue(Func.isAssignableTo(Obj));
+  Expect.isTrue(NumPredRef.isAssignableTo(Obj));
+  Expect.isTrue(IntPredRef.isAssignableTo(Obj));
+  Expect.isTrue(DubPredRef.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Func));
+  Expect.isTrue(Obj.isAssignableTo(NumPredRef));
+  Expect.isTrue(Obj.isAssignableTo(IntPredRef));
+  Expect.isTrue(Obj.isAssignableTo(DubPredRef));
+
+  // Function - return type.
+  TypeMirror NumGenRef = NumGen.referent;
+  TypeMirror IntGenRef = IntGen.referent;
+  TypeMirror DubGenRef = DubGen.referent;
+
+  Expect.isTrue(NumGenRef.isAssignableTo(NumGenRef));
+  Expect.isTrue(IntGenRef.isAssignableTo(IntGenRef));
+  Expect.isTrue(DubGenRef.isAssignableTo(DubGenRef));
+
+  Expect.isTrue(NumGenRef.isAssignableTo(Func));
+  Expect.isTrue(NumGenRef.isAssignableTo(IntGenRef));
+  Expect.isTrue(NumGenRef.isAssignableTo(DubGenRef));
+
+  Expect.isTrue(IntGenRef.isAssignableTo(Func));
+  Expect.isTrue(IntGenRef.isAssignableTo(NumGenRef));
+  Expect.isFalse(IntGenRef.isAssignableTo(DubGenRef));
+
+  Expect.isTrue(DubGenRef.isAssignableTo(Func));
+  Expect.isTrue(DubGenRef.isAssignableTo(NumGenRef));
+  Expect.isFalse(DubGenRef.isAssignableTo(IntGenRef));
+
+  Expect.isTrue(Func.isAssignableTo(Obj));
+  Expect.isTrue(NumGenRef.isAssignableTo(Obj));
+  Expect.isTrue(IntGenRef.isAssignableTo(Obj));
+  Expect.isTrue(DubGenRef.isAssignableTo(Obj));
+  Expect.isTrue(Obj.isAssignableTo(Func));
+  Expect.isTrue(Obj.isAssignableTo(NumGenRef));
+  Expect.isTrue(Obj.isAssignableTo(IntGenRef));
+  Expect.isTrue(Obj.isAssignableTo(DubGenRef));
+
+  // Function typedef / function.
+  Expect.isTrue(NumPred.isAssignableTo(NumPredRef));
+  Expect.isTrue(IntPred.isAssignableTo(IntPredRef));
+  Expect.isTrue(DubPred.isAssignableTo(DubPredRef));
+  Expect.isTrue(NumPredRef.isAssignableTo(NumPred));
+  Expect.isTrue(IntPredRef.isAssignableTo(IntPred));
+  Expect.isTrue(DubPredRef.isAssignableTo(DubPred));
+
+  // Function typedef / function.
+  Expect.isTrue(NumGen.isAssignableTo(NumGenRef));
+  Expect.isTrue(IntGen.isAssignableTo(IntGenRef));
+  Expect.isTrue(DubGen.isAssignableTo(DubGenRef));
+  Expect.isTrue(NumGenRef.isAssignableTo(NumGen));
+  Expect.isTrue(IntGenRef.isAssignableTo(IntGen));
+  Expect.isTrue(DubGenRef.isAssignableTo(DubGen));
+
+  // Type variable.
+  TypeMirror TFromA =
+      (thisLibrary.declarations[#A] as ClassMirror).typeVariables.single;
+  TypeMirror TFromB =
+      (thisLibrary.declarations[#B] as ClassMirror).typeVariables.single;
+  TypeMirror TFromC =
+      (thisLibrary.declarations[#C] as ClassMirror).typeVariables.single;
+
+  Expect.isTrue(TFromA.isAssignableTo(TFromA));
+  Expect.isTrue(TFromB.isAssignableTo(TFromB));
+  Expect.isTrue(TFromC.isAssignableTo(TFromC));
+
+  Expect.isFalse(TFromA.isAssignableTo(TFromB));
+  Expect.isFalse(TFromA.isAssignableTo(TFromC));
+  Expect.isFalse(TFromB.isAssignableTo(TFromA));
+  Expect.isFalse(TFromB.isAssignableTo(TFromC));
+  Expect.isFalse(TFromC.isAssignableTo(TFromA));
+  Expect.isFalse(TFromC.isAssignableTo(TFromB));
+
+  TypeMirror Num = coreLibrary.declarations[#num] as TypeMirror;
+  Expect.isTrue(TFromC.isAssignableTo(Num));
+  Expect.isTrue(Num.isAssignableTo(TFromC));
+
+  // dynamic & void.
+  TypeMirror Dynamic = mirrors.dynamicType;
+  Expect.isTrue(Dynamic.isAssignableTo(Dynamic));
+  Expect.isTrue(Obj.isAssignableTo(Dynamic));
+  Expect.isTrue(Super.isAssignableTo(Dynamic));
+  Expect.isTrue(Sub1.isAssignableTo(Dynamic));
+  Expect.isTrue(Sub2.isAssignableTo(Dynamic));
+  Expect.isTrue(NumPred.isAssignableTo(Dynamic));
+  Expect.isTrue(IntPred.isAssignableTo(Dynamic));
+  Expect.isTrue(DubPred.isAssignableTo(Dynamic));
+  Expect.isTrue(NumPredRef.isAssignableTo(Dynamic));
+  Expect.isTrue(IntPredRef.isAssignableTo(Dynamic));
+  Expect.isTrue(DubPredRef.isAssignableTo(Dynamic));
+  Expect.isTrue(NumGen.isAssignableTo(Dynamic));
+  Expect.isTrue(IntGen.isAssignableTo(Dynamic));
+  Expect.isTrue(DubGen.isAssignableTo(Dynamic));
+  Expect.isTrue(NumGenRef.isAssignableTo(Dynamic));
+  Expect.isTrue(IntGenRef.isAssignableTo(Dynamic));
+  Expect.isTrue(DubGenRef.isAssignableTo(Dynamic));
+  Expect.isTrue(TFromA.isAssignableTo(Dynamic));
+  Expect.isTrue(TFromB.isAssignableTo(Dynamic));
+  Expect.isTrue(TFromC.isAssignableTo(Dynamic));
+  Expect.isTrue(Dynamic.isAssignableTo(Obj));
+  Expect.isTrue(Dynamic.isAssignableTo(Super));
+  Expect.isTrue(Dynamic.isAssignableTo(Sub1));
+  Expect.isTrue(Dynamic.isAssignableTo(Sub2));
+  Expect.isTrue(Dynamic.isAssignableTo(NumPred));
+  Expect.isTrue(Dynamic.isAssignableTo(IntPred));
+  Expect.isTrue(Dynamic.isAssignableTo(DubPred));
+  Expect.isTrue(Dynamic.isAssignableTo(NumPredRef));
+  Expect.isTrue(Dynamic.isAssignableTo(IntPredRef));
+  Expect.isTrue(Dynamic.isAssignableTo(DubPredRef));
+  Expect.isTrue(Dynamic.isAssignableTo(NumGen));
+  Expect.isTrue(Dynamic.isAssignableTo(IntGen));
+  Expect.isTrue(Dynamic.isAssignableTo(DubGen));
+  Expect.isTrue(Dynamic.isAssignableTo(NumGenRef));
+  Expect.isTrue(Dynamic.isAssignableTo(IntGenRef));
+  Expect.isTrue(Dynamic.isAssignableTo(DubGenRef));
+  Expect.isTrue(Dynamic.isAssignableTo(TFromA));
+  Expect.isTrue(Dynamic.isAssignableTo(TFromB));
+  Expect.isTrue(Dynamic.isAssignableTo(TFromC));
+
+  TypeMirror Void = mirrors.voidType;
+  Expect.isTrue(Void.isAssignableTo(Void));
+  Expect.isFalse(Obj.isAssignableTo(Void));
+  Expect.isFalse(Super.isAssignableTo(Void));
+  Expect.isFalse(Sub1.isAssignableTo(Void));
+  Expect.isFalse(Sub2.isAssignableTo(Void));
+  Expect.isFalse(NumPred.isAssignableTo(Void));
+  Expect.isFalse(IntPred.isAssignableTo(Void));
+  Expect.isFalse(DubPred.isAssignableTo(Void));
+  Expect.isFalse(NumPredRef.isAssignableTo(Void));
+  Expect.isFalse(IntPredRef.isAssignableTo(Void));
+  Expect.isFalse(DubPredRef.isAssignableTo(Void));
+  Expect.isFalse(NumGen.isAssignableTo(Void));
+  Expect.isFalse(IntGen.isAssignableTo(Void));
+  Expect.isFalse(DubGen.isAssignableTo(Void));
+  Expect.isFalse(NumGenRef.isAssignableTo(Void));
+  Expect.isFalse(IntGenRef.isAssignableTo(Void));
+  Expect.isFalse(DubGenRef.isAssignableTo(Void));
+  Expect.isFalse(TFromA.isAssignableTo(Void));
+  Expect.isFalse(TFromB.isAssignableTo(Void));
+  Expect.isFalse(TFromC.isAssignableTo(Void));
+  Expect.isFalse(Void.isAssignableTo(Obj));
+  Expect.isFalse(Void.isAssignableTo(Super));
+  Expect.isFalse(Void.isAssignableTo(Sub1));
+  Expect.isFalse(Void.isAssignableTo(Sub2));
+  Expect.isFalse(Void.isAssignableTo(NumPred));
+  Expect.isFalse(Void.isAssignableTo(IntPred));
+  Expect.isFalse(Void.isAssignableTo(DubPred));
+  Expect.isFalse(Void.isAssignableTo(NumPredRef));
+  Expect.isFalse(Void.isAssignableTo(IntPredRef));
+  Expect.isFalse(Void.isAssignableTo(DubPredRef));
+  Expect.isFalse(Void.isAssignableTo(NumGen));
+  Expect.isFalse(Void.isAssignableTo(IntGen));
+  Expect.isFalse(Void.isAssignableTo(DubGen));
+  Expect.isFalse(Void.isAssignableTo(NumGenRef));
+  Expect.isFalse(Void.isAssignableTo(IntGenRef));
+  Expect.isFalse(Void.isAssignableTo(DubGenRef));
+  Expect.isFalse(Void.isAssignableTo(TFromA));
+  Expect.isFalse(Void.isAssignableTo(TFromB));
+  Expect.isFalse(Void.isAssignableTo(TFromC));
+
+  Expect.isTrue(Dynamic.isAssignableTo(Void));
+  Expect.isTrue(Void.isAssignableTo(Dynamic));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/relation_subclass_test.dart b/tests/lib/mirrors/relation_subclass_test.dart
new file mode 100644
index 0000000..7e83931
--- /dev/null
+++ b/tests/lib/mirrors/relation_subclass_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2014, 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 test.relation_subclass;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class Superclass {}
+
+class Subclass1 extends Superclass {}
+
+class Subclass2 extends Superclass {}
+
+typedef bool NumberPredicate(num x);
+typedef bool IntegerPredicate(int x);
+typedef bool DoublePredicate(double x);
+
+typedef num NumberGenerator();
+typedef int IntegerGenerator();
+typedef double DoubleGenerator();
+
+test(MirrorSystem mirrors) {
+  LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core);
+  LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_subclass);
+
+  ClassMirror Super = thisLibrary.declarations[#Superclass] as ClassMirror;
+  ClassMirror Sub1 = thisLibrary.declarations[#Subclass1] as ClassMirror;
+  ClassMirror Sub2 = thisLibrary.declarations[#Subclass2] as ClassMirror;
+  ClassMirror Obj = coreLibrary.declarations[#Object] as ClassMirror;
+  ClassMirror Nul = coreLibrary.declarations[#Null] as ClassMirror;
+
+  Expect.isTrue(Obj.isSubclassOf(Obj));
+  Expect.isTrue(Super.isSubclassOf(Super));
+  Expect.isTrue(Sub1.isSubclassOf(Sub1));
+  Expect.isTrue(Sub2.isSubclassOf(Sub2));
+  Expect.isTrue(Nul.isSubclassOf(Nul));
+
+  Expect.isTrue(Sub1.isSubclassOf(Super));
+  Expect.isFalse(Super.isSubclassOf(Sub1));
+
+  Expect.isTrue(Sub2.isSubclassOf(Super));
+  Expect.isFalse(Super.isSubclassOf(Sub2));
+
+  Expect.isFalse(Sub2.isSubclassOf(Sub1));
+  Expect.isFalse(Sub1.isSubclassOf(Sub2));
+
+  Expect.isTrue(Sub1.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Sub1));
+
+  Expect.isTrue(Sub2.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Sub2));
+
+  Expect.isTrue(Super.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Super));
+
+  Expect.isTrue(Nul.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Nul));
+  Expect.isFalse(Nul.isSubclassOf(Super));
+  Expect.isFalse(Super.isSubclassOf(Nul));
+
+  ClassMirror Func = coreLibrary.declarations[#Function] as ClassMirror;
+  Expect.isTrue(Func.isSubclassOf(Obj));
+  Expect.isFalse(Obj.isSubclassOf(Func));
+
+  // Function typedef.
+  dynamic NumPred = thisLibrary.declarations[#NumberPredicate];
+  dynamic IntPred = thisLibrary.declarations[#IntegerPredicate];
+  dynamic DubPred = thisLibrary.declarations[#DoublePredicate];
+  dynamic NumGen = thisLibrary.declarations[#NumberGenerator];
+  dynamic IntGen = thisLibrary.declarations[#IntegerGenerator];
+  dynamic DubGen = thisLibrary.declarations[#DoubleGenerator];
+
+  isArgumentOrTypeError(e) => e is ArgumentError || e is TypeError;
+  Expect.throws(() => Func.isSubclassOf(NumPred), isArgumentOrTypeError);
+  Expect.throws(() => Func.isSubclassOf(IntPred), isArgumentOrTypeError);
+  Expect.throws(() => Func.isSubclassOf(DubPred), isArgumentOrTypeError);
+  Expect.throws(() => Func.isSubclassOf(NumGen), isArgumentOrTypeError);
+  Expect.throws(() => Func.isSubclassOf(IntGen), isArgumentOrTypeError);
+  Expect.throws(() => Func.isSubclassOf(DubGen), isArgumentOrTypeError);
+
+  Expect.throwsNoSuchMethodError(() => NumPred.isSubclassOf(Func));
+  Expect.throwsNoSuchMethodError(() => IntPred.isSubclassOf(Func));
+  Expect.throwsNoSuchMethodError(() => DubPred.isSubclassOf(Func));
+  Expect.throwsNoSuchMethodError(() => NumGen.isSubclassOf(Func));
+  Expect.throwsNoSuchMethodError(() => IntGen.isSubclassOf(Func));
+  Expect.throwsNoSuchMethodError(() => DubGen.isSubclassOf(Func));
+
+  // Function type.
+  TypeMirror NumPredRef = (NumPred as TypedefMirror).referent;
+  TypeMirror IntPredRef = (IntPred as TypedefMirror).referent;
+  TypeMirror DubPredRef = (DubPred as TypedefMirror).referent;
+  TypeMirror NumGenRef = (NumGen as TypedefMirror).referent;
+  TypeMirror IntGenRef = (IntGen as TypedefMirror).referent;
+  TypeMirror DubGenRef = (DubGen as TypedefMirror).referent;
+
+  Expect.isFalse(Func.isSubclassOf(NumPredRef));
+  Expect.isFalse(Func.isSubclassOf(IntPredRef));
+  Expect.isFalse(Func.isSubclassOf(DubPredRef));
+  Expect.isFalse(Func.isSubclassOf(NumGenRef));
+  Expect.isFalse(Func.isSubclassOf(IntGenRef));
+  Expect.isFalse(Func.isSubclassOf(DubGenRef));
+
+  // The spec doesn't require these to be either value, only that they implement
+  // Function.
+  // NumPredRef.isSubclassOf(Func);
+  // IntPredRef.isSubclassOf(Func);
+  // DubPredRef.isSubclassOf(Func);
+  // NumGenRef.isSubclassOf(Func);
+  // IntGenRef.isSubclassOf(Func);
+  // DubGenRef.isSubclassOf(Func);
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/relation_subtype_test.dart b/tests/lib/mirrors/relation_subtype_test.dart
new file mode 100644
index 0000000..a9d165a
--- /dev/null
+++ b/tests/lib/mirrors/relation_subtype_test.dart
@@ -0,0 +1,312 @@
+// Copyright (c) 2014, 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 test.relation_subtype;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class Superclass {}
+
+class Subclass1 extends Superclass {}
+
+class Subclass2 extends Superclass {}
+
+typedef bool NumberPredicate(num x);
+typedef bool IntegerPredicate(int x);
+typedef bool DoublePredicate(double x);
+
+typedef num NumberGenerator();
+typedef int IntegerGenerator();
+typedef double DoubleGenerator();
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+class C<T extends num> {}
+
+test(MirrorSystem mirrors) {
+  LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core);
+  LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_subtype);
+
+  // Classes.
+  final Super = thisLibrary.declarations[#Superclass] as ClassMirror;
+  final Sub1 = thisLibrary.declarations[#Subclass1] as ClassMirror;
+  final Sub2 = thisLibrary.declarations[#Subclass2] as ClassMirror;
+  final Obj = coreLibrary.declarations[#Object] as ClassMirror;
+  final Nul = coreLibrary.declarations[#Null] as ClassMirror;
+
+  Expect.isTrue(Obj.isSubtypeOf(Obj));
+  Expect.isTrue(Super.isSubtypeOf(Super));
+  Expect.isTrue(Sub1.isSubtypeOf(Sub1));
+  Expect.isTrue(Sub2.isSubtypeOf(Sub2));
+  Expect.isTrue(Nul.isSubtypeOf(Nul));
+
+  Expect.isTrue(Sub1.isSubtypeOf(Super));
+  Expect.isFalse(Super.isSubtypeOf(Sub1));
+
+  Expect.isTrue(Sub2.isSubtypeOf(Super));
+  Expect.isFalse(Super.isSubtypeOf(Sub2));
+
+  Expect.isFalse(Sub2.isSubtypeOf(Sub1));
+  Expect.isFalse(Sub1.isSubtypeOf(Sub2));
+
+  Expect.isTrue(Sub1.isSubtypeOf(Obj));
+  Expect.isFalse(Obj.isSubtypeOf(Sub1));
+
+  Expect.isTrue(Sub2.isSubtypeOf(Obj));
+  Expect.isFalse(Obj.isSubtypeOf(Sub2));
+
+  Expect.isTrue(Super.isSubtypeOf(Obj));
+  Expect.isFalse(Obj.isSubtypeOf(Super));
+
+  Expect.isTrue(Nul.isSubtypeOf(Obj));
+  Expect.isFalse(Obj.isSubtypeOf(Nul));
+  Expect.isTrue(Nul.isSubtypeOf(Super)); // Null type is bottom type.
+  Expect.isFalse(Super.isSubtypeOf(Nul));
+
+  // Function typedef - argument type.
+  TypeMirror Func = coreLibrary.declarations[#Function] as TypeMirror;
+  TypedefMirror NumPred =
+      thisLibrary.declarations[#NumberPredicate] as TypedefMirror;
+  TypedefMirror IntPred =
+      thisLibrary.declarations[#IntegerPredicate] as TypedefMirror;
+  TypedefMirror DubPred =
+      thisLibrary.declarations[#DoublePredicate] as TypedefMirror;
+
+  Expect.isTrue(Func.isSubtypeOf(Func));
+  Expect.isTrue(NumPred.isSubtypeOf(NumPred));
+  Expect.isTrue(IntPred.isSubtypeOf(IntPred));
+  Expect.isTrue(DubPred.isSubtypeOf(DubPred));
+
+  Expect.isTrue(NumPred.isSubtypeOf(Func));
+  Expect.isTrue(NumPred.isSubtypeOf(IntPred));
+  Expect.isTrue(NumPred.isSubtypeOf(DubPred));
+
+  Expect.isTrue(IntPred.isSubtypeOf(Func));
+  Expect.isTrue(IntPred.isSubtypeOf(NumPred));
+  Expect.isFalse(IntPred.isSubtypeOf(DubPred));
+
+  Expect.isTrue(DubPred.isSubtypeOf(Func));
+  Expect.isTrue(DubPred.isSubtypeOf(NumPred));
+  Expect.isFalse(DubPred.isSubtypeOf(IntPred));
+
+  Expect.isTrue(Func.isSubtypeOf(Obj));
+  Expect.isTrue(NumPred.isSubtypeOf(Obj));
+  Expect.isTrue(IntPred.isSubtypeOf(Obj));
+  Expect.isTrue(DubPred.isSubtypeOf(Obj));
+
+  // Function typedef - return type.
+  TypedefMirror NumGen =
+      thisLibrary.declarations[#NumberGenerator] as TypedefMirror;
+  TypedefMirror IntGen =
+      thisLibrary.declarations[#IntegerGenerator] as TypedefMirror;
+  TypedefMirror DubGen =
+      thisLibrary.declarations[#DoubleGenerator] as TypedefMirror;
+
+  Expect.isTrue(NumGen.isSubtypeOf(NumGen));
+  Expect.isTrue(IntGen.isSubtypeOf(IntGen));
+  Expect.isTrue(DubGen.isSubtypeOf(DubGen));
+
+  Expect.isTrue(NumGen.isSubtypeOf(Func));
+  Expect.isTrue(NumGen.isSubtypeOf(IntGen));
+  Expect.isTrue(NumGen.isSubtypeOf(DubGen));
+
+  Expect.isTrue(IntGen.isSubtypeOf(Func));
+  Expect.isTrue(IntGen.isSubtypeOf(NumGen));
+  Expect.isFalse(IntGen.isSubtypeOf(DubGen));
+
+  Expect.isTrue(DubGen.isSubtypeOf(Func));
+  Expect.isTrue(DubGen.isSubtypeOf(NumGen));
+  Expect.isFalse(DubGen.isSubtypeOf(IntGen));
+
+  Expect.isTrue(Func.isSubtypeOf(Obj));
+  Expect.isTrue(NumGen.isSubtypeOf(Obj));
+  Expect.isTrue(IntGen.isSubtypeOf(Obj));
+  Expect.isTrue(DubGen.isSubtypeOf(Obj));
+
+  // Function - argument type.
+  TypeMirror NumPredRef = NumPred.referent;
+  TypeMirror IntPredRef = IntPred.referent;
+  TypeMirror DubPredRef = DubPred.referent;
+
+  Expect.isTrue(Func.isSubtypeOf(Func));
+  Expect.isTrue(NumPredRef.isSubtypeOf(NumPredRef));
+  Expect.isTrue(IntPredRef.isSubtypeOf(IntPredRef));
+  Expect.isTrue(DubPredRef.isSubtypeOf(DubPredRef));
+
+  Expect.isTrue(NumPredRef.isSubtypeOf(Func));
+  Expect.isTrue(NumPredRef.isSubtypeOf(IntPredRef));
+  Expect.isTrue(NumPredRef.isSubtypeOf(DubPredRef));
+
+  Expect.isTrue(IntPredRef.isSubtypeOf(Func));
+  Expect.isTrue(IntPredRef.isSubtypeOf(NumPredRef));
+  Expect.isFalse(IntPredRef.isSubtypeOf(DubPredRef));
+
+  Expect.isTrue(DubPredRef.isSubtypeOf(Func));
+  Expect.isTrue(DubPredRef.isSubtypeOf(NumPredRef));
+  Expect.isFalse(DubPredRef.isSubtypeOf(IntPredRef));
+
+  Expect.isTrue(Func.isSubtypeOf(Obj));
+  Expect.isTrue(NumPredRef.isSubtypeOf(Obj));
+  Expect.isTrue(IntPredRef.isSubtypeOf(Obj));
+  Expect.isTrue(DubPredRef.isSubtypeOf(Obj));
+
+  // Function - return type.
+  TypeMirror NumGenRef = NumGen.referent;
+  TypeMirror IntGenRef = IntGen.referent;
+  TypeMirror DubGenRef = DubGen.referent;
+
+  Expect.isTrue(NumGenRef.isSubtypeOf(NumGenRef));
+  Expect.isTrue(IntGenRef.isSubtypeOf(IntGenRef));
+  Expect.isTrue(DubGenRef.isSubtypeOf(DubGenRef));
+
+  Expect.isTrue(NumGenRef.isSubtypeOf(Func));
+  Expect.isTrue(NumGenRef.isSubtypeOf(IntGenRef));
+  Expect.isTrue(NumGenRef.isSubtypeOf(DubGenRef));
+
+  Expect.isTrue(IntGenRef.isSubtypeOf(Func));
+  Expect.isTrue(IntGenRef.isSubtypeOf(NumGenRef));
+  Expect.isFalse(IntGenRef.isSubtypeOf(DubGenRef));
+
+  Expect.isTrue(DubGenRef.isSubtypeOf(Func));
+  Expect.isTrue(DubGenRef.isSubtypeOf(NumGenRef));
+  Expect.isFalse(DubGenRef.isSubtypeOf(IntGenRef));
+
+  Expect.isTrue(Func.isSubtypeOf(Obj));
+  Expect.isTrue(NumGenRef.isSubtypeOf(Obj));
+  Expect.isTrue(IntGenRef.isSubtypeOf(Obj));
+  Expect.isTrue(DubGenRef.isSubtypeOf(Obj));
+
+  // Function typedef / function.
+  Expect.isTrue(NumPred.isSubtypeOf(NumPredRef));
+  Expect.isTrue(IntPred.isSubtypeOf(IntPredRef));
+  Expect.isTrue(DubPred.isSubtypeOf(DubPredRef));
+  Expect.isTrue(NumPredRef.isSubtypeOf(NumPred));
+  Expect.isTrue(IntPredRef.isSubtypeOf(IntPred));
+  Expect.isTrue(DubPredRef.isSubtypeOf(DubPred));
+
+  // Function typedef / function.
+  Expect.isTrue(NumGen.isSubtypeOf(NumGenRef));
+  Expect.isTrue(IntGen.isSubtypeOf(IntGenRef));
+  Expect.isTrue(DubGen.isSubtypeOf(DubGenRef));
+  Expect.isTrue(NumGenRef.isSubtypeOf(NumGen));
+  Expect.isTrue(IntGenRef.isSubtypeOf(IntGen));
+  Expect.isTrue(DubGenRef.isSubtypeOf(DubGen));
+
+  // Type variable.
+  TypeMirror TFromA =
+      (thisLibrary.declarations[#A] as ClassMirror).typeVariables.single;
+  TypeMirror TFromB =
+      (thisLibrary.declarations[#B] as ClassMirror).typeVariables.single;
+  TypeMirror TFromC =
+      (thisLibrary.declarations[#C] as ClassMirror).typeVariables.single;
+
+  Expect.isTrue(TFromA.isSubtypeOf(TFromA));
+  Expect.isTrue(TFromB.isSubtypeOf(TFromB));
+  Expect.isTrue(TFromC.isSubtypeOf(TFromC));
+
+  Expect.isFalse(TFromA.isSubtypeOf(TFromB));
+  Expect.isFalse(TFromA.isSubtypeOf(TFromC));
+  Expect.isFalse(TFromB.isSubtypeOf(TFromA));
+  Expect.isFalse(TFromB.isSubtypeOf(TFromC));
+  Expect.isFalse(TFromC.isSubtypeOf(TFromA));
+  Expect.isFalse(TFromC.isSubtypeOf(TFromB));
+
+  TypeMirror Num = coreLibrary.declarations[#num] as TypeMirror;
+  Expect.isTrue(TFromC.isSubtypeOf(Num));
+  Expect.isFalse(Num.isSubtypeOf(TFromC));
+
+  // dynamic & void.
+  TypeMirror Dynamic = mirrors.dynamicType;
+  Expect.isTrue(Dynamic.isSubtypeOf(Dynamic));
+  Expect.isTrue(Obj.isSubtypeOf(Dynamic));
+  Expect.isTrue(Super.isSubtypeOf(Dynamic));
+  Expect.isTrue(Sub1.isSubtypeOf(Dynamic));
+  Expect.isTrue(Sub2.isSubtypeOf(Dynamic));
+  Expect.isTrue(NumPred.isSubtypeOf(Dynamic));
+  Expect.isTrue(IntPred.isSubtypeOf(Dynamic));
+  Expect.isTrue(DubPred.isSubtypeOf(Dynamic));
+  Expect.isTrue(NumPredRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(IntPredRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(DubPredRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(NumGen.isSubtypeOf(Dynamic));
+  Expect.isTrue(IntGen.isSubtypeOf(Dynamic));
+  Expect.isTrue(DubGen.isSubtypeOf(Dynamic));
+  Expect.isTrue(NumGenRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(IntGenRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(DubGenRef.isSubtypeOf(Dynamic));
+  Expect.isTrue(TFromA.isSubtypeOf(Dynamic));
+  Expect.isTrue(TFromB.isSubtypeOf(Dynamic));
+  Expect.isTrue(TFromC.isSubtypeOf(Dynamic));
+  Expect.isTrue(Dynamic.isSubtypeOf(Obj));
+  Expect.isTrue(Dynamic.isSubtypeOf(Super));
+  Expect.isTrue(Dynamic.isSubtypeOf(Sub1));
+  Expect.isTrue(Dynamic.isSubtypeOf(Sub2));
+  Expect.isTrue(Dynamic.isSubtypeOf(NumPred));
+  Expect.isTrue(Dynamic.isSubtypeOf(IntPred));
+  Expect.isTrue(Dynamic.isSubtypeOf(DubPred));
+  Expect.isTrue(Dynamic.isSubtypeOf(NumPredRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(IntPredRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(DubPredRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(NumGen));
+  Expect.isTrue(Dynamic.isSubtypeOf(IntGen));
+  Expect.isTrue(Dynamic.isSubtypeOf(DubGen));
+  Expect.isTrue(Dynamic.isSubtypeOf(NumGenRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(IntGenRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(DubGenRef));
+  Expect.isTrue(Dynamic.isSubtypeOf(TFromA));
+  Expect.isTrue(Dynamic.isSubtypeOf(TFromB));
+  Expect.isTrue(Dynamic.isSubtypeOf(TFromC));
+
+  TypeMirror Void = mirrors.voidType;
+  Expect.isTrue(Void.isSubtypeOf(Void));
+  Expect.isFalse(Obj.isSubtypeOf(Void));
+  Expect.isFalse(Super.isSubtypeOf(Void));
+  Expect.isFalse(Sub1.isSubtypeOf(Void));
+  Expect.isFalse(Sub2.isSubtypeOf(Void));
+  Expect.isFalse(NumPred.isSubtypeOf(Void));
+  Expect.isFalse(IntPred.isSubtypeOf(Void));
+  Expect.isFalse(DubPred.isSubtypeOf(Void));
+  Expect.isFalse(NumPredRef.isSubtypeOf(Void));
+  Expect.isFalse(IntPredRef.isSubtypeOf(Void));
+  Expect.isFalse(DubPredRef.isSubtypeOf(Void));
+  Expect.isFalse(NumGen.isSubtypeOf(Void));
+  Expect.isFalse(IntGen.isSubtypeOf(Void));
+  Expect.isFalse(DubGen.isSubtypeOf(Void));
+  Expect.isFalse(NumGenRef.isSubtypeOf(Void));
+  Expect.isFalse(IntGenRef.isSubtypeOf(Void));
+  Expect.isFalse(DubGenRef.isSubtypeOf(Void));
+  Expect.isFalse(TFromA.isSubtypeOf(Void));
+  Expect.isFalse(TFromB.isSubtypeOf(Void));
+  Expect.isFalse(TFromC.isSubtypeOf(Void));
+  Expect.isFalse(Void.isSubtypeOf(Obj));
+  Expect.isFalse(Void.isSubtypeOf(Super));
+  Expect.isFalse(Void.isSubtypeOf(Sub1));
+  Expect.isFalse(Void.isSubtypeOf(Sub2));
+  Expect.isFalse(Void.isSubtypeOf(NumPred));
+  Expect.isFalse(Void.isSubtypeOf(IntPred));
+  Expect.isFalse(Void.isSubtypeOf(DubPred));
+  Expect.isFalse(Void.isSubtypeOf(NumPredRef));
+  Expect.isFalse(Void.isSubtypeOf(IntPredRef));
+  Expect.isFalse(Void.isSubtypeOf(DubPredRef));
+  Expect.isFalse(Void.isSubtypeOf(NumGen));
+  Expect.isFalse(Void.isSubtypeOf(IntGen));
+  Expect.isFalse(Void.isSubtypeOf(DubGen));
+  Expect.isFalse(Void.isSubtypeOf(NumGenRef));
+  Expect.isFalse(Void.isSubtypeOf(IntGenRef));
+  Expect.isFalse(Void.isSubtypeOf(DubGenRef));
+  Expect.isFalse(Void.isSubtypeOf(TFromA));
+  Expect.isFalse(Void.isSubtypeOf(TFromB));
+  Expect.isFalse(Void.isSubtypeOf(TFromC));
+
+  Expect.isTrue(Dynamic.isSubtypeOf(Void));
+  Expect.isTrue(Void.isSubtypeOf(Dynamic));
+}
+
+main() {
+  test(currentMirrorSystem());
+}
diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart
new file mode 100644
index 0000000..377cd51
--- /dev/null
+++ b/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib1;
+
+class _S {}
+
+class _M {}
+
+class _M2 {}
+
+class MA extends _S with _M {}
+
+class MA2 extends _S with _M, _M2 {}
diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart
new file mode 100644
index 0000000..36f9d8c
--- /dev/null
+++ b/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib2;
+
+class _S {}
+
+class _M {}
+
+class _M2 {}
+
+class MA extends _S with _M {}
+
+class MA2 extends _S with _M, _M2 {}
diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart
new file mode 100644
index 0000000..04f50b9
--- /dev/null
+++ b/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.repeated_private_anon_mixin_app;
+
+// Regression test for symbol mangling.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'repeated_private_anon_mixin_app1.dart' as lib1;
+import 'repeated_private_anon_mixin_app2.dart' as lib2;
+
+testMA() {
+  Symbol name1 = reflectClass(lib1.MA).superclass!.simpleName;
+  Symbol name2 = reflectClass(lib2.MA).superclass!.simpleName;
+
+  Expect.equals('lib._S with lib._M', MirrorSystem.getName(name1));
+  Expect.equals('lib._S with lib._M', MirrorSystem.getName(name2));
+
+  Expect.notEquals(name1, name2);
+  Expect.notEquals(name2, name1);
+}
+
+testMA2() {
+  Symbol name1 = reflectClass(lib1.MA2).superclass!.simpleName;
+  Symbol name2 = reflectClass(lib2.MA2).superclass!.simpleName;
+
+  Expect.equals('lib._S with lib._M, lib._M2', MirrorSystem.getName(name1));
+  Expect.equals('lib._S with lib._M, lib._M2', MirrorSystem.getName(name2));
+
+  Expect.notEquals(name1, name2);
+  Expect.notEquals(name2, name1);
+}
+
+main() {
+  testMA();
+  testMA2();
+}
diff --git a/tests/lib/mirrors/return_type_test.dart b/tests/lib/mirrors/return_type_test.dart
new file mode 100644
index 0000000..65115bd
--- /dev/null
+++ b/tests/lib/mirrors/return_type_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test of [MethodMirror.returnType].
+library test.return_type_test;
+
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+class B {
+  f() {}
+  int g() {}
+  List h() {}
+  B i() {}
+
+  // TODO(ahe): Test this when dart2js handles parameterized types.
+  // List<int> j() {}
+}
+
+methodsOf(ClassMirror cm) {
+  var result = new Map();
+  cm.declarations.forEach((k, v) {
+    if (v is MethodMirror && v.isRegularMethod) result[k] = v;
+  });
+  return result;
+}
+
+main() {
+  var methods = methodsOf(reflectClass(B));
+
+  expect(
+      '{f: Method(s(f) in s(B)), '
+      'g: Method(s(g) in s(B)), '
+      'h: Method(s(h) in s(B)), '
+      'i: Method(s(i) in s(B))}',
+      methods);
+
+  var f = methods[#f];
+  var g = methods[#g];
+  var h = methods[#h];
+  var i = methods[#i];
+
+  expect('Type(s(dynamic), top-level)', f.returnType);
+  expect('Class(s(int) in s(dart.core), top-level)', g.returnType);
+  expect('Class(s(List) in s(dart.core), top-level)', h.returnType);
+  expect('Class(s(B) in s(test.return_type_test), top-level)', i.returnType);
+}
diff --git a/tests/lib/mirrors/runtime_type_test.dart b/tests/lib/mirrors/runtime_type_test.dart
new file mode 100644
index 0000000..82c88b6
--- /dev/null
+++ b/tests/lib/mirrors/runtime_type_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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 test.runtime_type_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B {
+  get runtimeType => A;
+}
+
+main() {
+  Expect.equals(reflect(new B()).type, reflectClass(B));
+}
diff --git a/tests/lib/mirrors/set_field_with_final_inheritance_test.dart b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
new file mode 100644
index 0000000..4281227
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.set_field_with_final_inheritance;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class S {
+  var sideEffect = 0;
+
+  var mutableWithInheritedMutable = 1;
+  final mutableWithInheritedFinal = 2;
+  set mutableWithInheritedSetter(x) => sideEffect = 3;
+
+  var finalWithInheritedMutable = 4;
+  final finalWithInheritedFinal = 5;
+  set finalWithInheritedSetter(x) => sideEffect = 6;
+
+  var setterWithInheritedMutable = 7;
+  final setterWithInheritedFinal = 8;
+  set setterWithInheritedSetter(x) => sideEffect = 9;
+}
+
+class C extends S {
+  var mutableWithInheritedMutable = 10;
+  var mutableWithInheritedFinal = 11;
+  var mutableWithInheritedSetter = 12;
+
+  final finalWithInheritedMutable = 13;
+  final finalWithInheritedFinal = 14;
+  final finalWithInheritedSetter = 15;
+
+  set setterWithInheritedMutable(x) => sideEffect = 16;
+  set setterWithInheritedFinal(x) => sideEffect = 17;
+  set setterWithInheritedSetter(x) => sideEffect = 18;
+
+  get superMutableWithInheritedMutable => super.mutableWithInheritedMutable;
+  get superMutableWithInheritedFinal => super.mutableWithInheritedFinal;
+
+  get superFinalWithInheritedMutable => super.finalWithInheritedMutable;
+  get superFinalWithInheritedFinal => super.finalWithInheritedFinal;
+
+  get superSetterWithInheritedMutable => super.setterWithInheritedMutable;
+  get superSetterWithInheritedFinal => super.setterWithInheritedFinal;
+}
+
+main() {
+  C c;
+  InstanceMirror im;
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(19, im.setField(#mutableWithInheritedMutable, 19).reflectee);
+  Expect.equals(19, c.mutableWithInheritedMutable);
+  Expect.equals(1, c.superMutableWithInheritedMutable);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(20, im.setField(#mutableWithInheritedFinal, 20).reflectee);
+  Expect.equals(20, c.mutableWithInheritedFinal);
+  Expect.equals(2, c.superMutableWithInheritedFinal);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(21, im.setField(#mutableWithInheritedSetter, 21).reflectee);
+  Expect.equals(21, c.mutableWithInheritedSetter);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(22, im.setField(#finalWithInheritedMutable, 22).reflectee);
+  Expect.equals(13, c.finalWithInheritedMutable);
+  Expect.equals(22, c.superFinalWithInheritedMutable);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.throwsNoSuchMethodError(
+      () => im.setField(#finalWithInheritedFinal, 23));
+  Expect.equals(14, c.finalWithInheritedFinal);
+  Expect.equals(5, c.superFinalWithInheritedFinal);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(24, im.setField(#finalWithInheritedSetter, 24).reflectee);
+  Expect.equals(15, c.finalWithInheritedSetter);
+  Expect.equals(6, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(25, im.setField(#setterWithInheritedMutable, 25).reflectee);
+  Expect.equals(7, c.setterWithInheritedMutable);
+  Expect.equals(7, c.superSetterWithInheritedMutable);
+  Expect.equals(16, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(26, im.setField(#setterWithInheritedFinal, 26).reflectee);
+  Expect.equals(8, c.setterWithInheritedFinal);
+  Expect.equals(8, c.superSetterWithInheritedFinal);
+  Expect.equals(17, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(27, im.setField(#setterWithInheritedSetter, 27).reflectee);
+  Expect.equals(18, c.sideEffect);
+}
diff --git a/tests/lib/mirrors/set_field_with_final_test.dart b/tests/lib/mirrors/set_field_with_final_test.dart
new file mode 100644
index 0000000..d2515fd
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.set_field_with_final;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+  final instanceField = 1;
+  get instanceGetter => 2;
+  static final staticFinal = 3;
+  static get staticGetter => 4;
+}
+
+final toplevelFinal = 5;
+get toplevelGetter => 6;
+
+main() {
+  InstanceMirror im = reflect(new C());
+  Expect.throwsNoSuchMethodError(() => im.setField(#instanceField, 7));
+  Expect.throwsNoSuchMethodError(() => im.setField(#instanceGetter, 8));
+
+  ClassMirror cm = im.type;
+  Expect.throwsNoSuchMethodError(() => cm.setField(#staticFinal, 9));
+  Expect.throwsNoSuchMethodError(() => cm.setField(#staticGetter, 10));
+
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  Expect.throwsNoSuchMethodError(() => lm.setField(#toplevelFinal, 11));
+  Expect.throwsNoSuchMethodError(() => lm.setField(#toplevelGetter, 12));
+}
diff --git a/tests/lib/mirrors/spawn_function_root_library_test.dart b/tests/lib/mirrors/spawn_function_root_library_test.dart
new file mode 100644
index 0000000..f2d7f6c
--- /dev/null
+++ b/tests/lib/mirrors/spawn_function_root_library_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import 'dart:mirrors';
+import 'dart:isolate';
+import 'package:expect/expect.dart';
+
+child(SendPort port) {
+  LibraryMirror root = currentMirrorSystem().isolate.rootLibrary;
+  Expect.isNotNull(root);
+  port.send(root.uri.toString());
+}
+
+main() {
+  final port = new RawReceivePort();
+  port.handler = (String childRootUri) {
+    LibraryMirror root = currentMirrorSystem().isolate.rootLibrary;
+    Expect.isNotNull(root);
+    Expect.equals(root.uri.toString(), childRootUri);
+    port.close();
+  };
+
+  Isolate.spawn(child, port.sendPort);
+}
diff --git a/tests/lib/mirrors/static_const_field_test.dart b/tests/lib/mirrors/static_const_field_test.dart
new file mode 100644
index 0000000..cf8c283
--- /dev/null
+++ b/tests/lib/mirrors/static_const_field_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that static const fields are accessible by reflection.
+// Regression test for http://dartbug.com/23811.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class A {
+  static const ONE = 1;
+}
+
+main() {
+  Expect.equals(1, reflectClass(A).getField(#ONE).reflectee);
+}
diff --git a/tests/lib/mirrors/static_members_easier_test.dart b/tests/lib/mirrors/static_members_easier_test.dart
new file mode 100644
index 0000000..b050a3c
--- /dev/null
+++ b/tests/lib/mirrors/static_members_easier_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.static_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model_easier.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+  LibraryMirror lm = cm.owner as LibraryMirror;
+
+  Expect.setEquals([
+    #staticVariable,
+    const Symbol('staticVariable='),
+    #staticGetter,
+    const Symbol('staticSetter='),
+    #staticMethod,
+  ], selectKeys(cm.staticMembers, (dm) => true));
+
+  Expect.setEquals([#staticVariable, const Symbol('staticVariable=')],
+      selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+}
diff --git a/tests/lib/mirrors/static_members_test.dart b/tests/lib/mirrors/static_members_test.dart
new file mode 100644
index 0000000..f84bc53
--- /dev/null
+++ b/tests/lib/mirrors/static_members_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.static_members;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model.dart' as declarations_model;
+
+selectKeys(map, predicate) {
+  return map.keys.where((key) => predicate(map[key]));
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+  LibraryMirror lm = cm.owner as LibraryMirror;
+
+  Expect.setEquals([
+    #staticVariable,
+    const Symbol('staticVariable='),
+    #staticGetter,
+    const Symbol('staticSetter='),
+    #staticMethod,
+    MirrorSystem.getSymbol('_staticVariable', lm),
+    MirrorSystem.getSymbol('_staticVariable=', lm),
+    MirrorSystem.getSymbol('_staticGetter', lm),
+    MirrorSystem.getSymbol('_staticSetter=', lm),
+    MirrorSystem.getSymbol('_staticMethod', lm),
+  ], selectKeys(cm.staticMembers, (dm) => true));
+
+  Expect.setEquals([
+    #staticVariable,
+    const Symbol('staticVariable='),
+    MirrorSystem.getSymbol('_staticVariable', lm),
+    MirrorSystem.getSymbol('_staticVariable=', lm)
+  ], selectKeys(cm.staticMembers, (dm) => dm.isSynthetic));
+}
diff --git a/tests/lib/mirrors/static_metatarget_test.dart b/tests/lib/mirrors/static_metatarget_test.dart
new file mode 100644
index 0000000..8024db8
--- /dev/null
+++ b/tests/lib/mirrors/static_metatarget_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for the combined use of metatargets and static fields with
+// annotations.
+
+import 'dart:mirrors';
+
+class A {
+  @reflectable
+  var reflectableField = 0; //# 01: ok
+
+  @UsedOnlyAsMetadata()
+  var unreflectableField = 1; //# 02: ok
+
+  @reflectable
+  static var reflectableStaticField = 2; //# 03: ok
+
+  @UsedOnlyAsMetadata()
+  static var unreflectableStaticField = 3;
+}
+
+class Reflectable {
+  const Reflectable();
+}
+
+const Reflectable reflectable = const Reflectable();
+
+class UsedOnlyAsMetadata {
+  const UsedOnlyAsMetadata();
+}
+
+void main() {
+  print(new A());
+}
diff --git a/tests/lib/mirrors/static_test.dart b/tests/lib/mirrors/static_test.dart
new file mode 100644
index 0000000..6a2e4fe
--- /dev/null
+++ b/tests/lib/mirrors/static_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test static members.
+
+library lib;
+
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+class Foo {
+  static String bar = '...';
+  String aux = '';
+  static foo() {}
+  baz() {}
+}
+
+void main() {
+  expect('Variable(s(aux) in s(Foo))',
+      reflectClass(Foo).declarations[new Symbol('aux')]);
+  expect('Method(s(baz) in s(Foo))',
+      reflectClass(Foo).declarations[new Symbol('baz')]);
+  expect('<null>', reflectClass(Foo).declarations[new Symbol('aux=')]);
+  expect('Method(s(foo) in s(Foo), static)',
+      reflectClass(Foo).declarations[new Symbol('foo')]);
+  expect('Variable(s(bar) in s(Foo), static)',
+      reflectClass(Foo).declarations[new Symbol('bar')]);
+}
diff --git a/tests/lib/mirrors/stringify.dart b/tests/lib/mirrors/stringify.dart
new file mode 100644
index 0000000..25e2061
--- /dev/null
+++ b/tests/lib/mirrors/stringify.dart
@@ -0,0 +1,190 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Helper methods for converting a [Mirror] to a [String].
+library test.stringify;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+String name(DeclarationMirror? mirror) {
+  return (mirror == null) ? '<null>' : stringify(mirror.simpleName);
+}
+
+String stringifyMap(Map map) {
+  var buffer = new StringBuffer();
+  bool first = true;
+  var names = map.keys.map((s) => MirrorSystem.getName(s)).toList()..sort();
+  for (String key in names) {
+    if (!first) buffer.write(', ');
+    first = false;
+    buffer.write(key);
+    buffer.write(': ');
+    buffer.write(stringify(map[new Symbol(key)]));
+  }
+  return '{$buffer}';
+}
+
+String stringifyIterable(Iterable list) {
+  var buffer = new StringBuffer();
+  bool first = true;
+  for (String value in list.map(stringify)) {
+    if (!first) buffer.write(', ');
+    first = false;
+    buffer.write(value);
+  }
+  return '[$buffer]';
+}
+
+String stringifyInstance(InstanceMirror instance) {
+  var buffer = new StringBuffer();
+  if (instance.hasReflectee) {
+    buffer.write('value = ${stringify(instance.reflectee)}');
+  }
+  return 'Instance(${buffer})';
+}
+
+String stringifySymbol(Symbol symbol) => 's(${MirrorSystem.getName(symbol)})';
+
+void writeDeclarationOn(DeclarationMirror mirror, StringBuffer buffer) {
+  buffer.write(stringify(mirror.simpleName));
+  if (mirror.owner != null) {
+    buffer.write(' in ');
+    buffer.write(name(mirror.owner));
+  }
+  if (mirror.isPrivate) buffer.write(', private');
+  if (mirror.isTopLevel) buffer.write(', top-level');
+}
+
+void writeVariableOn(VariableMirror variable, StringBuffer buffer) {
+  writeDeclarationOn(variable, buffer);
+  if (variable.isStatic) buffer.write(', static');
+  if (variable.isFinal) buffer.write(', final');
+}
+
+String stringifyVariable(VariableMirror variable) {
+  var buffer = new StringBuffer();
+  writeVariableOn(variable, buffer);
+  return 'Variable($buffer)';
+}
+
+String stringifyParameter(ParameterMirror parameter) {
+  var buffer = new StringBuffer();
+  writeVariableOn(parameter, buffer);
+  if (parameter.isOptional) buffer.write(', optional');
+  if (parameter.isNamed) buffer.write(', named');
+  // TODO(6490): dart2js always returns false for hasDefaultValue.
+  if (parameter.hasDefaultValue) {
+    buffer.write(', value = ${stringify(parameter.defaultValue)}');
+  }
+  // TODO(ahe): Move to writeVariableOn.
+  buffer.write(', type = ${stringify(parameter.type)}');
+  return 'Parameter($buffer)';
+}
+
+String stringifyTypeVariable(TypeVariableMirror typeVariable) {
+  var buffer = new StringBuffer();
+  writeDeclarationOn(typeVariable, buffer);
+  buffer.write(', upperBound = ${stringify(typeVariable.upperBound)}');
+  return 'TypeVariable($buffer)';
+}
+
+String stringifyType(TypeMirror type) {
+  var buffer = new StringBuffer();
+  writeDeclarationOn(type, buffer);
+  return 'Type($buffer)';
+}
+
+String stringifyClass(ClassMirror cls) {
+  var buffer = new StringBuffer();
+  writeDeclarationOn(cls, buffer);
+  return 'Class($buffer)';
+}
+
+String stringifyMethod(MethodMirror method) {
+  var buffer = new StringBuffer();
+  writeDeclarationOn(method, buffer);
+  if (method.isAbstract) buffer.write(', abstract');
+  if (method.isSynthetic) buffer.write(', synthetic');
+  if (method.isStatic) buffer.write(', static');
+  if (method.isGetter) buffer.write(', getter');
+  if (method.isSetter) buffer.write(', setter');
+  if (method.isConstructor) buffer.write(', constructor');
+  return 'Method($buffer)';
+}
+
+String stringifyDependencies(LibraryMirror l) {
+  n(s) => s is Symbol ? MirrorSystem.getName(s) : s;
+  int compareDep(a, b) {
+    if (a.targetLibrary == b.targetLibrary) {
+      if ((a.prefix != null) && (b.prefix != null)) {
+        return n(a.prefix).compareTo(n(b.prefix));
+      }
+      return a.prefix == null ? 1 : -1;
+    }
+    return n(a.targetLibrary.simpleName)
+        .compareTo(n(b.targetLibrary.simpleName));
+  }
+
+  int compareCom(a, b) => n(a.identifier).compareTo(n(b.identifier));
+  int compareFirst(a, b) => a[0].compareTo(b[0]);
+  sortBy(c, p) => new List.from(c)..sort(p);
+
+  var buffer = new StringBuffer();
+  sortBy(l.libraryDependencies, compareDep).forEach((dep) {
+    if (dep.isImport) buffer.write('import ');
+    if (dep.isExport) buffer.write('export ');
+    buffer.write(n(dep.targetLibrary.simpleName));
+    if (dep.isDeferred) buffer.write(' deferred');
+    if (dep.prefix != null) buffer.write(' as ${n(dep.prefix)}');
+    buffer.write('\n');
+
+    List flattenedCombinators = new List();
+    dep.combinators.forEach((com) {
+      com.identifiers.forEach((ident) {
+        flattenedCombinators.add([n(ident), com.isShow, com.isHide]);
+      });
+    });
+    sortBy(flattenedCombinators, compareFirst).forEach((triple) {
+      buffer.write(' ');
+      if (triple[1]) buffer.write('show ');
+      if (triple[2]) buffer.write('hide ');
+      buffer.write(triple[0]);
+      buffer.write('\n');
+    });
+  });
+  return buffer.toString();
+}
+
+String stringify(value) {
+  if (value == null) return '<null>';
+  if (value is Map) return stringifyMap(value);
+  if (value is Iterable) return stringifyIterable(value);
+  if (value is InstanceMirror) return stringifyInstance(value);
+  if (value is ParameterMirror) return stringifyParameter(value);
+  if (value is VariableMirror) return stringifyVariable(value);
+  if (value is MethodMirror) return stringifyMethod(value);
+  if (value is num) return value.toString();
+  if (value is String) return value;
+  if (value is Symbol) return stringifySymbol(value);
+  if (value is ClassMirror) return stringifyClass(value);
+  if (value is TypeVariableMirror) return stringifyTypeVariable(value);
+  if (value is TypeMirror) return stringifyType(value);
+  throw 'Unexpected value: $value';
+}
+
+void expect(expected, actual, [String reason = ""]) {
+  Expect.stringEquals(expected, stringify(actual), reason);
+}
+
+int compareSymbols(Symbol a, Symbol b) {
+  return MirrorSystem.getName(a).compareTo(MirrorSystem.getName(b));
+}
+
+Iterable<Symbol> simpleNames(Iterable<Mirror> i) =>
+    i.map((e) => (e as DeclarationMirror).simpleName);
+
+List<Symbol> sort(Iterable<Symbol> symbols) =>
+    symbols.toList()..sort(compareSymbols);
diff --git a/tests/lib/mirrors/superclass2_test.dart b/tests/lib/mirrors/superclass2_test.dart
new file mode 100644
index 0000000..31fafc1
--- /dev/null
+++ b/tests/lib/mirrors/superclass2_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.superclass;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+checkSuperclassChain(ClassMirror? cm) {
+  ClassMirror? last;
+  do {
+    last = cm;
+    cm = cm!.superclass;
+  } while (cm != null);
+  Expect.equals(reflectClass(Object), last);
+}
+
+main() {
+  checkSuperclassChain(reflect(null).type);
+  checkSuperclassChain(reflect([]).type);
+  checkSuperclassChain(reflect(<int>[]).type);
+  checkSuperclassChain(reflect(0).type);
+  checkSuperclassChain(reflect(1.5).type);
+  checkSuperclassChain(reflect("str").type);
+  checkSuperclassChain(reflect(true).type);
+  checkSuperclassChain(reflect(false).type);
+}
diff --git a/tests/lib/mirrors/superclass_test.dart b/tests/lib/mirrors/superclass_test.dart
new file mode 100644
index 0000000..19aada8
--- /dev/null
+++ b/tests/lib/mirrors/superclass_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.superclass;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class MyClass {}
+
+main() {
+  var cls = reflectClass(MyClass);
+  Expect.isNotNull(cls, 'Failed to reflect on MyClass.');
+  var superclass = cls.superclass;
+  Expect.isNotNull(superclass, 'Failed to obtain superclass of MyClass.');
+  Expect.equals(
+      reflectClass(Object), superclass, 'Superclass of MyClass is not Object.');
+  Expect.isNull(superclass!.superclass, 'Superclass of Object is not null.');
+}
diff --git a/tests/lib/mirrors/symbol_validation_test.dart b/tests/lib/mirrors/symbol_validation_test.dart
new file mode 100644
index 0000000..11a7d94
--- /dev/null
+++ b/tests/lib/mirrors/symbol_validation_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library symbol_validation_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+validSymbol(String string) {
+  Expect.equals(string, MirrorSystem.getName(new Symbol(string)),
+      'Valid symbol "$string" should be invertable');
+  Expect.equals(string, MirrorSystem.getName(MirrorSystem.getSymbol(string)),
+      'Valid symbol "$string" should be invertable');
+}
+
+invalidSymbol(String string) {
+  Expect.throwsArgumentError(() => new Symbol(string),
+      'Invalid symbol "$string" should be rejected');
+  Expect.throwsArgumentError(() => MirrorSystem.getSymbol(string),
+      'Invalid symbol "$string" should be rejected');
+}
+
+validPrivateSymbol(String string) {
+  ClosureMirror closure = reflect(main) as ClosureMirror;
+  LibraryMirror library = closure.function.owner as LibraryMirror;
+  Expect.equals(
+      string,
+      MirrorSystem.getName(MirrorSystem.getSymbol(string, library)),
+      'Valid private symbol "$string" should be invertable');
+}
+
+main() {
+  // Operators that can be declared as class member operators.
+  // These are all valid as symbols.
+  var operators = [
+    '%',
+    '&',
+    '*',
+    '+',
+    '-',
+    '/',
+    '<',
+    '<<',
+    '<=',
+    '==',
+    '>',
+    '>=',
+    '>>',
+    '[]',
+    '[]=',
+    '^',
+    'unary-',
+    '|',
+    '~',
+    '~/'
+  ];
+  operators.expand((op) => [op, "x.$op"]).forEach(validSymbol);
+  operators
+      .expand((op) => [".$op", "$op.x", "x$op", "_x.$op"])
+      .forEach(invalidSymbol);
+  operators
+      .expand<String>((op) => operators.contains("$op=") ? [] : ["x.$op=", "$op="])
+      .forEach(invalidSymbol);
+
+  var simpleSymbols = [
+    'foo',
+    'bar_',
+    'baz.quz',
+    'fisk1',
+    'hest2fisk',
+    'a.b.c.d.e',
+    r'$',
+    r'foo$',
+    r'bar$bar',
+    r'$.$',
+    r'x6$_',
+    r'$6_',
+    r'x.$$6_',
+    'x_',
+    'x_.x_',
+    'unary',
+    'x.unary'
+  ];
+  simpleSymbols.expand((s) => [s, "s="]).forEach(validSymbol);
+
+  var nonSymbols = [
+    // Non-identifiers.
+    '6', '0foo', ',', 'S with M', '_invalid&private', "#foo", " foo", "foo ",
+    // Operator variants.
+    '+=', '()', 'operator+', 'unary+', '>>>', "&&", "||", "!", "@", "#", "[",
+    // Private symbols.
+    '_', '_x', 'x._y', 'x._',
+    // Empty parts of "qualified" symbols.
+    '.', 'x.', '.x', 'x..y'
+  ];
+  nonSymbols.forEach(invalidSymbol);
+
+  // Reserved words are not valid identifiers and therefore not valid symbols.
+  var reservedWords = [
+    "assert",
+    "break",
+    "case",
+    "catch",
+    "class",
+    "const",
+    "continue",
+    "default",
+    "do",
+    "else",
+    "enum",
+    "extends",
+    "false",
+    "final",
+    "finally",
+    "for",
+    "if",
+    "in",
+    "is",
+    "new",
+    "null",
+    "rethrow",
+    "return",
+    "super",
+    "switch",
+    "this",
+    "throw",
+    "true",
+    "try",
+    "var",
+    "void",
+    "while",
+    "with"
+  ];
+  reservedWords
+      .expand((w) => [w, "$w=", "x.$w", "$w.x", "x.$w.x"])
+      .forEach(invalidSymbol);
+  reservedWords
+      .expand((w) => ["${w}_", "${w}\$", "${w}q"])
+      .forEach(validSymbol);
+
+  // Built-in identifiers are valid identifiers that are restricted from being
+  // used in some cases, but they are all valid symbols.
+  var builtInIdentifiers = [
+    "abstract",
+    "as",
+    "dynamic",
+    "export",
+    "external",
+    "factory",
+    "get",
+    "implements",
+    "import",
+    "library",
+    "operator",
+    "part",
+    "set",
+    "static",
+    "typedef"
+  ];
+  builtInIdentifiers
+      .expand((w) => [w, "$w=", "x.$w", "$w.x", "x.$w.x", "$w=", "x.$w="])
+      .forEach(validSymbol);
+
+  var privateSymbols = ['_', '_x', 'x._y', 'x._', 'x.y._', 'x._.y', '_true'];
+  privateSymbols.forEach(invalidSymbol);
+  privateSymbols.forEach(validPrivateSymbol); //  //# 01: ok
+}
diff --git a/tests/lib/mirrors/syntax_error_test.dart b/tests/lib/mirrors/syntax_error_test.dart
new file mode 100644
index 0000000..227e791
--- /dev/null
+++ b/tests/lib/mirrors/syntax_error_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for Issue 15744
+// Also, tests that syntax errors in reflected classes are reported correctly.
+
+library lib;
+
+import 'dart:mirrors';
+
+class MD {
+  final String name;
+  const MD({this.name});
+}
+
+@MD(name: 'A')
+class A {}
+
+@MD(name: 'B')
+class B {
+  static x = { 0: 0; }; // //# 01: compile-time error
+}
+
+main() {
+  reflectClass(A).metadata;
+  reflectClass(B).newInstance(Symbol.empty, []);
+}
diff --git a/tests/lib/mirrors/synthetic_accessor_properties_test.dart b/tests/lib/mirrors/synthetic_accessor_properties_test.dart
new file mode 100644
index 0000000..9d1d6e3
--- /dev/null
+++ b/tests/lib/mirrors/synthetic_accessor_properties_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.synthetic_accessor_properties;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+
+class C {
+  String instanceField = "1";
+  final num finalInstanceField = 2;
+
+  static bool staticField = false;
+  static final int finalStaticField = 4;
+}
+
+String topLevelField = "5";
+final double finalTopLevelField = 6.0;
+
+main() {
+  ClassMirror cm = reflectClass(C);
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  MethodMirror mm;
+  ParameterMirror pm;
+
+  mm = cm.instanceMembers[#instanceField] as MethodMirror;
+  expect('Method(s(instanceField) in s(C), synthetic, getter)', mm);
+  Expect.equals(reflectClass(String), mm.returnType);
+  Expect.listEquals([], mm.parameters);
+
+  mm = cm.instanceMembers[const Symbol('instanceField=')] as MethodMirror;
+  expect('Method(s(instanceField=) in s(C), synthetic, setter)', mm);
+  Expect.equals(reflectClass(String), mm.returnType);
+  pm = mm.parameters.single;
+  expect(
+      'Parameter(s(instanceField) in s(instanceField=), final,'
+      ' type = Class(s(String) in s(dart.core), top-level))',
+      pm);
+
+  mm = cm.instanceMembers[#finalInstanceField] as MethodMirror;
+  expect('Method(s(finalInstanceField) in s(C), synthetic, getter)', mm);
+  Expect.equals(reflectClass(num), mm.returnType);
+  Expect.listEquals([], mm.parameters);
+
+  mm = cm.instanceMembers[const Symbol('finalInstanceField=')] as MethodMirror;
+  Expect.isNull(mm);
+
+  mm = cm.staticMembers[#staticField] as MethodMirror;
+  expect('Method(s(staticField) in s(C), synthetic, static, getter)', mm);
+  Expect.equals(reflectClass(bool), mm.returnType);
+  Expect.listEquals([], mm.parameters);
+
+  mm = cm.staticMembers[const Symbol('staticField=')] as MethodMirror;
+  expect('Method(s(staticField=) in s(C), synthetic, static, setter)', mm);
+  Expect.equals(reflectClass(bool), mm.returnType);
+  pm = mm.parameters.single;
+  expect(
+      'Parameter(s(staticField) in s(staticField=), final,'
+      ' type = Class(s(bool) in s(dart.core), top-level))',
+      pm);
+
+  mm = cm.staticMembers[#finalStaticField] as MethodMirror;
+  expect('Method(s(finalStaticField) in s(C), synthetic, static, getter)', mm);
+  Expect.equals(reflectClass(int), mm.returnType);
+  Expect.listEquals([], mm.parameters);
+
+  mm = cm.staticMembers[const Symbol('finalStaticField=')] as MethodMirror;
+  Expect.isNull(mm);
+}
diff --git a/tests/lib/mirrors/to_string_test.dart b/tests/lib/mirrors/to_string_test.dart
new file mode 100644
index 0000000..23a0499
--- /dev/null
+++ b/tests/lib/mirrors/to_string_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.to_string_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+expect(expected, actual) => Expect.stringEquals(expected, '$actual');
+
+class Foo {
+  var field;
+  method() {}
+}
+
+main() {
+  var mirrors = currentMirrorSystem();
+  expect("TypeMirror on 'dynamic'", mirrors.dynamicType);
+  expect("TypeMirror on 'void'", mirrors.voidType);
+  expect("LibraryMirror on 'test.to_string_test'",
+      mirrors.findLibrary(#test.to_string_test));
+  expect("InstanceMirror on 1", reflect(1));
+  expect("ClassMirror on 'Foo'", reflectClass(Foo));
+  expect("VariableMirror on 'field'", reflectClass(Foo).declarations[#field]);
+  expect("MethodMirror on 'method'", reflectClass(Foo).declarations[#method]);
+  String s = reflect(main).toString();
+  Expect.isTrue(s.startsWith("ClosureMirror on '"), s);
+}
diff --git a/tests/lib/mirrors/top_level_accessors_test.dart b/tests/lib/mirrors/top_level_accessors_test.dart
new file mode 100644
index 0000000..269153e
--- /dev/null
+++ b/tests/lib/mirrors/top_level_accessors_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.top_level_accessors_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+var field;
+
+get accessor => field;
+
+set accessor(value) {
+  field = value;
+  return 'fisk'; //# 01: compile-time error
+}
+
+main() {
+  LibraryMirror library =
+      currentMirrorSystem().findLibrary(#test.top_level_accessors_test);
+  field = 42;
+  Expect.equals(42, library.getField(#accessor).reflectee);
+  Expect.equals(87, library.setField(#accessor, 87).reflectee);
+  Expect.equals(87, field);
+  Expect.equals(87, library.getField(#accessor).reflectee);
+}
diff --git a/tests/lib/mirrors/type_argument_is_type_variable_test.dart b/tests/lib/mirrors/type_argument_is_type_variable_test.dart
new file mode 100644
index 0000000..2aa7118
--- /dev/null
+++ b/tests/lib/mirrors/type_argument_is_type_variable_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.type_argument_is_type_variable;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_helper.dart';
+
+class SuperSuper<SS> {}
+
+class Super<S> extends SuperSuper<S> {}
+
+class Generic<G> extends Super<G> {}
+
+main() {
+  // Declarations.
+  ClassMirror generic = reflectClass(Generic);
+  ClassMirror superOfGeneric = generic.superclass!;
+  ClassMirror superOfSuperOfGeneric = superOfGeneric.superclass!;
+
+  TypeVariableMirror gFromGeneric = generic.typeVariables.single;
+  TypeVariableMirror sFromSuper = superOfGeneric.typeVariables.single;
+  TypeVariableMirror ssFromSuperSuper =
+      superOfSuperOfGeneric.typeVariables.single;
+
+  Expect.equals(#G, gFromGeneric.simpleName);
+  Expect.equals(#S, sFromSuper.simpleName);
+  Expect.equals(#SS, ssFromSuperSuper.simpleName);
+
+  typeParameters(generic, [#G]);
+  typeParameters(superOfGeneric, [#S]);
+  typeParameters(superOfSuperOfGeneric, [#SS]);
+
+  typeArguments(generic, []);
+  typeArguments(superOfGeneric, [gFromGeneric]);
+  typeArguments(superOfSuperOfGeneric, [gFromGeneric]);
+
+  // Instantiations.
+  ClassMirror genericWithInt = reflect(new Generic<int>()).type;
+  ClassMirror superOfGenericWithInt = genericWithInt.superclass!;
+  ClassMirror superOfSuperOfGenericWithInt = superOfGenericWithInt.superclass!;
+
+  typeParameters(genericWithInt, [#G]);
+  typeParameters(superOfGenericWithInt, [#S]);
+  typeParameters(superOfSuperOfGenericWithInt, [#SS]);
+
+  typeArguments(genericWithInt, [reflectClass(int)]);
+  typeArguments(superOfGenericWithInt, [reflectClass(int)]);
+  typeArguments(superOfSuperOfGenericWithInt, [reflectClass(int)]);
+}
diff --git a/tests/lib/mirrors/type_mirror_for_type_test.dart b/tests/lib/mirrors/type_mirror_for_type_test.dart
new file mode 100644
index 0000000..92e101f
--- /dev/null
+++ b/tests/lib/mirrors/type_mirror_for_type_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for the dart2js implementation of runtime types.
+
+library test.type_mirror_for_type;
+
+import 'package:expect/expect.dart';
+
+import 'dart:mirrors';
+
+class C<T> {}
+
+class X {
+  Type foo() {}
+}
+
+main() {
+  // Make sure that we need a type test against the runtime representation of
+  // [Type].
+  var a = (new DateTime.now().millisecondsSinceEpoch != 42)
+      ? new C<Type>()
+      : new C<int>();
+  print(a is C<Type>);
+
+  var typeMirror = reflectType(X) as ClassMirror;
+  var declarationMirror = typeMirror.declarations[#foo] as MethodMirror;
+  // Test that the runtime type implementation does not confuse the runtime type
+  // representation of [Type] with an actual value of type [Type] when analyzing
+  // the return type of [foo].
+  Expect.equals(reflectType(Type), declarationMirror.returnType);
+}
diff --git a/tests/lib/mirrors/type_variable_is_static_test.dart b/tests/lib/mirrors/type_variable_is_static_test.dart
new file mode 100644
index 0000000..ff7bfa5
--- /dev/null
+++ b/tests/lib/mirrors/type_variable_is_static_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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 test.type_variable_owner;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class C<T> {}
+
+typedef bool Predicate<T>(T t);
+
+main() {
+  Expect.isFalse(reflectType(C).typeVariables.single.isStatic);
+  Expect.isFalse(reflectType(Predicate).typeVariables.single.isStatic);
+}
diff --git a/tests/lib/mirrors/type_variable_owner_test.dart b/tests/lib/mirrors/type_variable_owner_test.dart
new file mode 100644
index 0000000..150d74b
--- /dev/null
+++ b/tests/lib/mirrors/type_variable_owner_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Owner of a type variable should be the declaration of the generic class or
+// typedef, not an instantiation.
+
+library test.type_variable_owner;
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class B<R> extends A<R> {}
+
+testTypeVariableOfClass() {
+  ClassMirror aDecl = reflectClass(A);
+  ClassMirror bDecl = reflectClass(B);
+  ClassMirror aOfInt = reflect(new A<int>()).type;
+  ClassMirror aOfR = bDecl.superclass!;
+  ClassMirror bOfString = reflect(new B<String>()).type;
+  ClassMirror aOfString = bOfString.superclass!;
+
+  Expect.equals(aDecl, aDecl.typeVariables[0].owner);
+  Expect.equals(aDecl, aOfInt.typeVariables[0].owner);
+  Expect.equals(aDecl, aOfR.typeVariables[0].owner);
+  Expect.equals(aDecl, aOfString.typeVariables[0].owner);
+
+  Expect.equals(bDecl, bDecl.typeVariables[0].owner);
+  Expect.equals(bDecl, bOfString.typeVariables[0].owner);
+}
+
+typedef bool Predicate<T>(T t);
+late Predicate<List> somePredicateOfList;
+
+testTypeVariableOfTypedef() {
+  LibraryMirror thisLibrary =
+      currentMirrorSystem().findLibrary(#test.type_variable_owner);
+
+  TypedefMirror predicateOfDynamic = reflectType(Predicate) as TypedefMirror;
+  TypedefMirror predicateOfList =
+      (thisLibrary.declarations[#somePredicateOfList] as VariableMirror).type as TypedefMirror;
+  TypedefMirror predicateDecl = predicateOfList.originalDeclaration as TypedefMirror;
+
+  Expect.equals(predicateDecl, predicateOfDynamic.typeVariables[0].owner);
+  Expect.equals(predicateDecl, predicateOfList.typeVariables[0].owner);
+  Expect.equals(predicateDecl, predicateDecl.typeVariables[0].owner);
+}
+
+main() {
+  testTypeVariableOfClass();
+  testTypeVariableOfTypedef(); // //# 01: ok
+}
diff --git a/tests/lib/mirrors/typearguments_mirror_test.dart b/tests/lib/mirrors/typearguments_mirror_test.dart
new file mode 100644
index 0000000..a5474d5
--- /dev/null
+++ b/tests/lib/mirrors/typearguments_mirror_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+import 'dart:mirrors';
+
+class Foo<T> {}
+
+class Bar<T, R> {}
+
+main() {
+  var cm = reflectClass(Foo);
+  var cm1 = reflect((new Foo<String>())).type;
+
+  Expect.notEquals(cm, cm1);
+  Expect.isFalse(cm1.isOriginalDeclaration);
+  Expect.isTrue(cm.isOriginalDeclaration);
+
+  Expect.equals(cm, cm1.originalDeclaration);
+
+  Expect.equals(cm, reflectClass(Foo));
+  Expect.equals(cm, reflectClass((new Foo().runtimeType)));
+  Expect.equals(cm1, reflect(new Foo<String>()).type);
+
+  expect('[]', cm.typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]', cm1.typeArguments);
+
+  cm = reflect(new Bar<List, Set>()).type;
+  cm1 = reflect(new Bar<List, Set<String>>()).type;
+
+  var cm2 = reflect(new Bar<List<String>, Set>()).type;
+  var cm3 = reflect(new Bar<List<String>, Set<String>>()).type;
+
+  expect(
+      '[Class(s(List) in s(dart.core), top-level),'
+      ' Class(s(Set) in s(dart.core), top-level)]',
+      cm.typeArguments);
+  expect(
+      '[Class(s(List) in s(dart.core), top-level),'
+      ' Class(s(Set) in s(dart.core), top-level)]',
+      cm1.typeArguments);
+  expect(
+      '[Class(s(List) in s(dart.core), top-level),'
+      ' Class(s(Set) in s(dart.core), top-level)]',
+      cm2.typeArguments);
+  expect(
+      '[Class(s(List) in s(dart.core), top-level),'
+      ' Class(s(Set) in s(dart.core), top-level)]',
+      cm3.typeArguments);
+
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+      cm1.typeArguments[1].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+      cm2.typeArguments[0].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+      cm3.typeArguments[0].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+      cm3.typeArguments[1].typeArguments);
+
+  var cm4 = reflect(new Bar<Bar<List, Set>, String>()).type;
+
+  expect(
+      '[Class(s(Bar) in s(lib), top-level),'
+      ' Class(s(String) in s(dart.core), top-level)]',
+      cm4.typeArguments);
+  expect(
+      '[Class(s(List) in s(dart.core), top-level), '
+      'Class(s(Set) in s(dart.core), top-level)]',
+      cm4.typeArguments[0].typeArguments);
+}
diff --git a/tests/lib/mirrors/typedef_deferred_library_test.dart b/tests/lib/mirrors/typedef_deferred_library_test.dart
new file mode 100644
index 0000000..77e45a8
--- /dev/null
+++ b/tests/lib/mirrors/typedef_deferred_library_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library foo;
+
+import 'dart:mirrors';
+import 'typedef_library.dart' deferred as def;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  def.loadLibrary().then((_) {
+    var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar"));
+    var gTypedef = barLibrary.declarations[new Symbol("G")]!;
+    Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName));
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/mirrors/typedef_in_signature_test.dart b/tests/lib/mirrors/typedef_in_signature_test.dart
new file mode 100644
index 0000000..8695750
--- /dev/null
+++ b/tests/lib/mirrors/typedef_in_signature_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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 test.typedef_in_signature_test;
+
+import 'dart:mirrors';
+
+import "package:expect/expect.dart";
+
+typedef int foo();
+typedef String foo2();
+typedef foo foo3(foo2 x);
+
+foo2 bar(foo x) => throw "does-not-return"; //
+
+foo3 gee(int x, foo3 tt) => throw "does-not-return"; //
+
+main() {
+  var lm = currentMirrorSystem().findLibrary(#test.typedef_in_signature_test);
+  var mm = lm.declarations[#bar] as MethodMirror;
+  Expect.equals(reflectType(foo2), mm.returnType);
+  Expect.equals(reflectType(foo), mm.parameters[0].type);
+  mm = lm.declarations[#gee] as MethodMirror;
+  Expect.equals(reflectType(int), mm.parameters[0].type);
+  Expect.equals(reflectType(foo3), mm.returnType);
+  var ftm = (mm.returnType as TypedefMirror).referent;
+  Expect.equals(reflectType(foo), ftm.returnType);
+  Expect.equals(reflectType(foo2), ftm.parameters[0].type);
+}
diff --git a/tests/lib/mirrors/typedef_library.dart b/tests/lib/mirrors/typedef_library.dart
new file mode 100644
index 0000000..fcb3231
--- /dev/null
+++ b/tests/lib/mirrors/typedef_library.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library bar;
+
+typedef G();
diff --git a/tests/lib/mirrors/typedef_library_test.dart b/tests/lib/mirrors/typedef_library_test.dart
new file mode 100644
index 0000000..33ddaf3
--- /dev/null
+++ b/tests/lib/mirrors/typedef_library_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library foo;
+
+import 'dart:mirrors';
+import 'typedef_library.dart';
+
+import 'package:expect/expect.dart';
+
+main() {
+  var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar"));
+  var gTypedef = barLibrary.declarations[new Symbol("G")]!;
+  Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName));
+}
diff --git a/tests/lib/mirrors/typedef_metadata_test.dart b/tests/lib/mirrors/typedef_metadata_test.dart
new file mode 100644
index 0000000..7b5e098
--- /dev/null
+++ b/tests/lib/mirrors/typedef_metadata_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@string
+@symbol
+library test.typedef_metadata_test;
+
+import 'dart:mirrors';
+
+import 'metadata_test.dart';
+
+class S {}
+
+class M {}
+
+@symbol
+class MA = S with M;
+
+@string
+typedef bool Predicate(Object o);
+
+main() {
+  checkMetadata(reflectType(MA), [symbol]);
+  checkMetadata(reflectType(Predicate), [string]);
+}
diff --git a/tests/lib/mirrors/typedef_reflected_type_test.dart b/tests/lib/mirrors/typedef_reflected_type_test.dart
new file mode 100644
index 0000000..7b017f5
--- /dev/null
+++ b/tests/lib/mirrors/typedef_reflected_type_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, 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 test;
+
+import 'package:expect/expect.dart';
+
+import 'dart:mirrors';
+
+typedef int Foo<T>(String x);
+typedef int Bar();
+
+class C {
+  Bar fun(Foo<int> x) => null;
+}
+
+main() {
+  var m = reflectClass(C).declarations[#fun] as MethodMirror;
+
+  Expect.equals(Bar, m.returnType.reflectedType);
+  Expect.equals("Foo<int>", m.parameters[0].type.reflectedType.toString()); //  //# 01: ok
+  Expect.equals(int, m.parameters[0].type.typeArguments[0].reflectedType); //   //# 01: continued
+  Expect.isFalse(m.parameters[0].type.isOriginalDeclaration); //                //# 01: continued
+
+  var lib = currentMirrorSystem().findLibrary(#test);
+  Expect.isTrue((lib.declarations[#Foo] as TypeMirror).isOriginalDeclaration);
+}
diff --git a/tests/lib/mirrors/typedef_test.dart b/tests/lib/mirrors/typedef_test.dart
new file mode 100644
index 0000000..b7a152f
--- /dev/null
+++ b/tests/lib/mirrors/typedef_test.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test is a multi-test with three positive tests. "01" pass on dart2js,
+// "02" pass on the VM, and "none" is the correct behavior.
+// The goal is to remove all "01" and "02" lines.
+
+library test.typedef_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+typedef Func();
+typedef void Void();
+typedef String Foo(int x);
+typedef String Bar(int x, [num y]);
+typedef String Baz(int x, {num y});
+typedef String Foo2(int x, num y);
+typedef String Bar2(int x, [num y, num z]);
+typedef String Baz2(int x, {num y, num z});
+
+check(t) {
+  var sb = new StringBuffer();
+  writeln(o) {
+    sb.write(o);
+    sb.write('\n');
+  }
+
+  writeln(t);
+  t = t.referent;
+  writeln(t);
+  writeln(t.returnType);
+  writeln(t.parameters);
+  for (var p in t.parameters) {
+    writeln(p.simpleName);
+    writeln(p.type);
+  }
+
+  return sb.toString();
+}
+
+// Return "$args -> $ret".
+ft(args, ret) {
+  return '$args -> $ret';
+}
+
+void main() {
+  String x = 'x';
+  String y = 'y';
+  String z = 'z';
+
+  Expect.stringEquals("""
+TypedefMirror on 'Func'
+FunctionTypeMirror on '${ft('()', 'dynamic')}'
+TypeMirror on 'dynamic'
+[]
+""", check(reflectType(Func)));
+  Expect.stringEquals("""
+TypedefMirror on 'Void'
+FunctionTypeMirror on '${ft('()', 'void')}'
+TypeMirror on 'void'
+[]
+""", check(reflectType(Void)));
+  Expect.stringEquals("""
+TypedefMirror on 'Foo'
+FunctionTypeMirror on '${ft('(dart.core.int)', 'dart.core.String')}'
+ClassMirror on 'String'
+[ParameterMirror on '$x']
+Symbol(\"$x\")
+ClassMirror on 'int'
+""", check(reflectType(Foo)));
+  String type = ft('(dart.core.int, dart.core.num)', 'dart.core.String');
+  Expect.stringEquals("""
+TypedefMirror on 'Foo2'
+FunctionTypeMirror on '$type'
+ClassMirror on 'String'
+[ParameterMirror on '$x', ParameterMirror on '$y']
+Symbol(\"$x\")
+ClassMirror on 'int'
+Symbol(\"$y\")
+ClassMirror on 'num'
+""", check(reflectType(Foo2)));
+  type = ft('(dart.core.int, [dart.core.num])', 'dart.core.String');
+  Expect.stringEquals("""
+TypedefMirror on 'Bar'
+FunctionTypeMirror on '$type'
+ClassMirror on 'String'
+[ParameterMirror on '$x', ParameterMirror on '$y']
+Symbol(\"$x\")
+ClassMirror on 'int'
+Symbol(\"$y\")
+ClassMirror on 'num'
+""", check(reflectType(Bar)));
+  type =
+      ft('(dart.core.int, [dart.core.num, dart.core.num])', 'dart.core.String');
+  Expect.stringEquals("""
+TypedefMirror on 'Bar2'
+FunctionTypeMirror on '$type'
+ClassMirror on 'String'
+[ParameterMirror on '$x', ParameterMirror on '$y', ParameterMirror on '$z']
+Symbol(\"$x\")
+ClassMirror on 'int'
+Symbol(\"$y\")
+ClassMirror on 'num'
+Symbol(\"$z\")
+ClassMirror on 'num'
+""", check(reflectType(Bar2)));
+  type = ft('(dart.core.int, {y: dart.core.num})', 'dart.core.String');
+  Expect.stringEquals("""
+TypedefMirror on 'Baz'
+FunctionTypeMirror on '$type'
+ClassMirror on 'String'
+[ParameterMirror on '$x', ParameterMirror on 'y']
+Symbol(\"$x\")
+ClassMirror on 'int'
+Symbol(\"y\")
+ClassMirror on 'num'
+""", check(reflectType(Baz)));
+  type = ft('(dart.core.int, {y: dart.core.num, z: dart.core.num})',
+      'dart.core.String');
+  Expect.stringEquals("""
+TypedefMirror on 'Baz2'
+FunctionTypeMirror on '$type'
+ClassMirror on 'String'
+[ParameterMirror on '$x', ParameterMirror on 'y', ParameterMirror on 'z']
+Symbol(\"$x\")
+ClassMirror on 'int'
+Symbol(\"y\")
+ClassMirror on 'num'
+Symbol(\"z\")
+ClassMirror on 'num'
+""", check(reflectType(Baz2)));
+}
diff --git a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
new file mode 100644
index 0000000..9841e8f
--- /dev/null
+++ b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.typevariable_metadata_test;
+
+import "dart:mirrors";
+
+import "metadata_test.dart";
+
+const m1 = 'm1';
+const m2 = #m2;
+const m3 = 3;
+
+class A<S, @m1 @m2 T> {}
+
+class B<@m3 T> {}
+
+typedef bool Predicate<@m1 @m2 G>(G a);
+
+main() {
+  ClassMirror cm;
+  cm = reflectClass(A);
+  checkMetadata(cm.typeVariables[0], []);
+  checkMetadata(cm.typeVariables[1], [m1, m2]);
+
+  cm = reflectClass(B);
+  checkMetadata(cm.typeVariables[0], [m3]);
+
+  TypedefMirror tm = reflectType(Predicate) as TypedefMirror;
+  checkMetadata(tm.typeVariables[0], [m1, m2]);
+  FunctionTypeMirror ftm = tm.referent;
+  checkMetadata(ftm, []);
+}
diff --git a/tests/lib/mirrors/unmangled_type_test.dart b/tests/lib/mirrors/unmangled_type_test.dart
new file mode 100644
index 0000000..b9fa763
--- /dev/null
+++ b/tests/lib/mirrors/unmangled_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lib;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Foo {}
+
+main() {
+  Expect.stringEquals('Foo', '${new Foo().runtimeType}');
+  Expect.stringEquals('foo', MirrorSystem.getName(new Symbol('foo')));
+}
diff --git a/tests/lib/mirrors/unnamed_library_test.dart b/tests/lib/mirrors/unnamed_library_test.dart
new file mode 100644
index 0000000..5e6160d
--- /dev/null
+++ b/tests/lib/mirrors/unnamed_library_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// No library declaration.
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Class {}
+
+main() {
+  ClassMirror cm = reflectClass(Class);
+  LibraryMirror lm = cm.owner as LibraryMirror;
+
+  Expect.equals('Class', MirrorSystem.getName(cm.simpleName));
+  Expect.equals('.Class', MirrorSystem.getName(cm.qualifiedName));
+  Expect.equals('', MirrorSystem.getName(lm.simpleName));
+  Expect.equals('', MirrorSystem.getName(lm.qualifiedName));
+}
diff --git a/tests/lib/mirrors/unnamed_mixin_application_test.dart b/tests/lib/mirrors/unnamed_mixin_application_test.dart
new file mode 100644
index 0000000..d884495
--- /dev/null
+++ b/tests/lib/mirrors/unnamed_mixin_application_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test that the forwarding constructors of unnamed mixin applications are
+/// included for reflection.
+
+library lib;
+
+import 'dart:mirrors';
+
+class S {
+  S();
+  S.anUnusedName();
+}
+
+class M {}
+
+class C extends S with M {
+  C();
+}
+
+main() {
+  // Use 'C#', 'S+M#' and 'S#' but not 'S#anUnusedName' nor 'S+M#anUnusedName'.
+  new C();
+  // Disable tree shaking making 'S+M#anUnusedName' live.
+  reflectClass(C);
+}
diff --git a/tests/lib/mirrors/variable_is_const_test.dart b/tests/lib/mirrors/variable_is_const_test.dart
new file mode 100644
index 0000000..de3b0cb
--- /dev/null
+++ b/tests/lib/mirrors/variable_is_const_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.variable_is_const;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class Class {
+  const //# 01: compile-time error
+      int instanceWouldBeConst = 1;
+  var instanceNonConst = 2;
+
+  static const staticConst = 3;
+  static var staticNonConst = 4;
+}
+
+const topLevelConst = 5;
+var topLevelNonConst = 6;
+
+main() {
+  bool isConst(m, Symbol s) => (m.declarations[s] as VariableMirror).isConst;
+
+  ClassMirror cm = reflectClass(Class);
+  Expect.isFalse(isConst(cm, #instanceWouldBeConst));
+  Expect.isFalse(isConst(cm, #instanceNonConst));
+  Expect.isTrue(isConst(cm, #staticConst));
+  Expect.isFalse(isConst(cm, #staticNonConst));
+
+  LibraryMirror lm = cm.owner as LibraryMirror;
+  Expect.isTrue(isConst(lm, #topLevelConst));
+  Expect.isFalse(isConst(lm, #topLevelNonConst));
+}
diff --git a/tests/lib/typed_data/byte_data_test.dart b/tests/lib/typed_data/byte_data_test.dart
new file mode 100644
index 0000000..2b0e3ea
--- /dev/null
+++ b/tests/lib/typed_data/byte_data_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+main() {
+  testRegress10898();
+}
+
+testRegress10898() {
+  ByteData data = new ByteData(16);
+  Expect.equals(16, data.lengthInBytes);
+  for (int i = 0; i < data.lengthInBytes; i++) {
+    Expect.equals(0, data.getInt8(i));
+    data.setInt8(i, 42 + i);
+    Expect.equals(42 + i, data.getInt8(i));
+  }
+
+  ByteData backing = new ByteData(16);
+  ByteData view = new ByteData.view(backing.buffer);
+  for (int i = 0; i < view.lengthInBytes; i++) {
+    Expect.equals(0, view.getInt8(i));
+    view.setInt8(i, 87 + i);
+    Expect.equals(87 + i, view.getInt8(i));
+  }
+
+  view = new ByteData.view(backing.buffer, 4);
+  Expect.equals(12, view.lengthInBytes);
+  for (int i = 0; i < view.lengthInBytes; i++) {
+    Expect.equals(87 + i + 4, view.getInt8(i));
+  }
+
+  view = new ByteData.view(backing.buffer, 8, 4);
+  Expect.equals(4, view.lengthInBytes);
+  for (int i = 0; i < view.lengthInBytes; i++) {
+    Expect.equals(87 + i + 8, view.getInt8(i));
+  }
+}
diff --git a/tests/lib/typed_data/constructor_checks_test.dart b/tests/lib/typed_data/constructor_checks_test.dart
new file mode 100644
index 0000000..a07239c
--- /dev/null
+++ b/tests/lib/typed_data/constructor_checks_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+/// Check that normal dynamic invariant enforcement applies for arguments,
+/// also with these constructors of built-in types.
+checkLengthConstructors() {
+  check(creator) {
+    Expect.throws(() => creator(null));
+    Expect.throws(() => creator(8.5));
+    Expect.throws(() => creator('10'));
+    var a = creator(10);
+    Expect.equals(10, a.length);
+  }
+
+  check((a) => new Float32List(a));
+  check((a) => new Float64List(a));
+  check((a) => new Int8List(a));
+  check((a) => new Int8List(a));
+  check((a) => new Int16List(a));
+  check((a) => new Int32List(a));
+  check((a) => new Uint8List(a));
+  check((a) => new Uint16List(a));
+  check((a) => new Uint32List(a));
+}
+
+checkViewConstructors() {
+  var buffer = new Int8List(256).buffer;
+
+  check1(creator) {
+    Expect.throws(() => creator(10));
+    Expect.throws(() => creator(null));
+    var a = creator(buffer);
+    Expect.equals(buffer, a.buffer);
+  }
+
+  check2(creator) {
+    Expect.throws(() => creator(10, 0));
+    Expect.throws(() => creator(null, 0));
+    Expect.throws(() => creator(buffer, null));
+    Expect.throws(() => creator(buffer, '8'));
+    var a = creator(buffer, 8);
+    Expect.equals(buffer, a.buffer);
+  }
+
+  check1((a) => new Float32List.view(a));
+  check1((a) => new Float64List.view(a));
+  check1((a) => new Int8List.view(a));
+  check1((a) => new Int8List.view(a));
+  check1((a) => new Int16List.view(a));
+  check1((a) => new Int32List.view(a));
+  check1((a) => new Uint8List.view(a));
+  check1((a) => new Uint16List.view(a));
+  check1((a) => new Uint32List.view(a));
+
+  check2((a, b) => new Float32List.view(a, b));
+  check2((a, b) => new Float64List.view(a, b));
+  check2((a, b) => new Int8List.view(a, b));
+  check2((a, b) => new Int8List.view(a, b));
+  check2((a, b) => new Int16List.view(a, b));
+  check2((a, b) => new Int32List.view(a, b));
+  check2((a, b) => new Uint8List.view(a, b));
+  check2((a, b) => new Uint16List.view(a, b));
+  check2((a, b) => new Uint32List.view(a, b));
+}
+
+main() {
+  checkLengthConstructors();
+  checkViewConstructors();
+}
diff --git a/tests/lib/typed_data/endianness_test.dart b/tests/lib/typed_data/endianness_test.dart
new file mode 100644
index 0000000..2bec2d7
--- /dev/null
+++ b/tests/lib/typed_data/endianness_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+main() {
+  swapTest();
+  swapTestVar(Endian.little, Endian.big);
+  swapTestVar(Endian.big, Endian.little);
+}
+
+swapTest() {
+  ByteData data = new ByteData(16);
+  Expect.equals(16, data.lengthInBytes);
+  for (int i = 0; i < 4; i++) {
+    data.setInt32(i * 4, i);
+  }
+
+  for (int i = 0; i < data.lengthInBytes; i += 4) {
+    var e = data.getInt32(i, Endian.big);
+    data.setInt32(i, e, Endian.little);
+  }
+
+  Expect.equals(0x02000000, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 2) {
+    var e = data.getInt16(i, Endian.big);
+    data.setInt16(i, e, Endian.little);
+  }
+
+  Expect.equals(0x00020000, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 4) {
+    var e = data.getUint32(i, Endian.little);
+    data.setUint32(i, e, Endian.big);
+  }
+
+  Expect.equals(0x00000200, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 2) {
+    var e = data.getUint16(i, Endian.little);
+    data.setUint16(i, e, Endian.big);
+  }
+
+  Expect.equals(0x00000002, data.getInt32(8));
+}
+
+swapTestVar(read, write) {
+  ByteData data = new ByteData(16);
+  Expect.equals(16, data.lengthInBytes);
+  for (int i = 0; i < 4; i++) {
+    data.setInt32(i * 4, i);
+  }
+
+  for (int i = 0; i < data.lengthInBytes; i += 4) {
+    var e = data.getInt32(i, read);
+    data.setInt32(i, e, write);
+  }
+
+  Expect.equals(0x02000000, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 2) {
+    var e = data.getInt16(i, read);
+    data.setInt16(i, e, write);
+  }
+
+  Expect.equals(0x00020000, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 4) {
+    var e = data.getUint32(i, read);
+    data.setUint32(i, e, write);
+  }
+
+  Expect.equals(0x00000200, data.getInt32(8));
+
+  for (int i = 0; i < data.lengthInBytes; i += 2) {
+    var e = data.getUint16(i, read);
+    data.setUint16(i, e, write);
+  }
+
+  Expect.equals(0x00000002, data.getInt32(8));
+}
diff --git a/tests/lib/typed_data/float32x4_clamp_test.dart b/tests/lib/typed_data/float32x4_clamp_test.dart
new file mode 100644
index 0000000..0109478
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_clamp_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_clamp_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testClampLowerGreaterThanUpper() {
+  Float32x4 l = new Float32x4(1.0, 1.0, 1.0, 1.0);
+  Float32x4 u = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+  Float32x4 z = new Float32x4.zero();
+  Float32x4 a = z.clamp(l, u);
+  Expect.equals(a.x, 1.0);
+  Expect.equals(a.y, 1.0);
+  Expect.equals(a.z, 1.0);
+  Expect.equals(a.w, 1.0);
+}
+
+void testClamp() {
+  Float32x4 l = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+  Float32x4 u = new Float32x4(1.0, 1.0, 1.0, 1.0);
+  Float32x4 z = new Float32x4.zero();
+  Float32x4 a = z.clamp(l, u);
+  Expect.equals(a.x, 0.0);
+  Expect.equals(a.y, 0.0);
+  Expect.equals(a.z, 0.0);
+  Expect.equals(a.w, 0.0);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testClampLowerGreaterThanUpper();
+    testClamp();
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_cross_test.dart b/tests/lib/typed_data/float32x4_cross_test.dart
new file mode 100644
index 0000000..7c905ec
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_cross_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_cross_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+Float32x4 cross(Float32x4 a, Float32x4 b) {
+  var t0 = a.shuffle(Float32x4.yzxw);
+  var t1 = b.shuffle(Float32x4.zxyw);
+  var l = t0 * t1;
+  t0 = a.shuffle(Float32x4.zxyw);
+  t1 = b.shuffle(Float32x4.yzxw);
+  var r = t0 * t1;
+  return l - r;
+}
+
+void testCross(Float32x4 a, Float32x4 b, Float32x4 r) {
+  var x = cross(a, b);
+  Expect.equals(r.x, x.x);
+  Expect.equals(r.y, x.y);
+  Expect.equals(r.z, x.z);
+  Expect.equals(r.w, x.w);
+}
+
+main() {
+  var x = new Float32x4(1.0, 0.0, 0.0, 0.0);
+  var y = new Float32x4(0.0, 1.0, 0.0, 0.0);
+  var z = new Float32x4(0.0, 0.0, 1.0, 0.0);
+  var zero = new Float32x4.zero();
+
+  for (int i = 0; i < 20; i++) {
+    testCross(x, y, z);
+    testCross(z, x, y);
+    testCross(y, z, x);
+    testCross(z, y, -x);
+    testCross(x, z, -y);
+    testCross(y, x, -z);
+    testCross(x, x, zero);
+    testCross(y, y, zero);
+    testCross(z, z, zero);
+    testCross(x, y, cross(-y, x));
+    testCross(x, y + z, cross(x, y) + cross(x, z));
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_list_test.dart b/tests/lib/typed_data/float32x4_list_test.dart
new file mode 100644
index 0000000..4cb29ba
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_list_test.dart
@@ -0,0 +1,254 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background_compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_list_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+testLoadStore(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is List<Float32x4>);
+  array[0] = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Expect.equals(1.0, array[0].x);
+  Expect.equals(2.0, array[0].y);
+  Expect.equals(3.0, array[0].z);
+  Expect.equals(4.0, array[0].w);
+  array[1] = array[0];
+  array[0] = array[0].withX(9.0);
+  Expect.equals(9.0, array[0].x);
+  Expect.equals(2.0, array[0].y);
+  Expect.equals(3.0, array[0].z);
+  Expect.equals(4.0, array[0].w);
+  Expect.equals(1.0, array[1].x);
+  Expect.equals(2.0, array[1].y);
+  Expect.equals(3.0, array[1].z);
+  Expect.equals(4.0, array[1].w);
+}
+
+testLoadStoreDeopt(array, index, value) {
+  array[index] = value;
+  Expect.equals(value.x, array[index].x);
+  Expect.equals(value.y, array[index].y);
+  Expect.equals(value.z, array[index].z);
+  Expect.equals(value.w, array[index].w);
+}
+
+testLoadStoreDeoptDriver() {
+  Float32x4List list = new Float32x4List(4);
+  Float32x4 value = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // Invalid index.
+    testLoadStoreDeopt(list, 5, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // null list.
+    testLoadStoreDeopt(null, 0, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // null value.
+    testLoadStoreDeopt(list, 0, null);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-smi index.
+    testLoadStoreDeopt(list, 3.14159, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-Float32x4 value.
+    testLoadStoreDeopt(list, 0, 4.toDouble());
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-Float32x4List list.
+    testLoadStoreDeopt([new Float32x4(2.0, 3.0, 4.0, 5.0)], 0, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+}
+
+testListZero() {
+  Float32x4List list = new Float32x4List(1);
+  Expect.equals(0.0, list[0].x);
+  Expect.equals(0.0, list[0].y);
+  Expect.equals(0.0, list[0].z);
+  Expect.equals(0.0, list[0].w);
+}
+
+testView(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is List<Float32x4>);
+  Expect.equals(0.0, array[0].x);
+  Expect.equals(1.0, array[0].y);
+  Expect.equals(2.0, array[0].z);
+  Expect.equals(3.0, array[0].w);
+  Expect.equals(4.0, array[1].x);
+  Expect.equals(5.0, array[1].y);
+  Expect.equals(6.0, array[1].z);
+  Expect.equals(7.0, array[1].w);
+}
+
+testSublist(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is Float32x4List);
+  var a = array.sublist(0, 1);
+  Expect.equals(1, a.length);
+  Expect.equals(0.0, a[0].x);
+  Expect.equals(1.0, a[0].y);
+  Expect.equals(2.0, a[0].z);
+  Expect.equals(3.0, a[0].w);
+  a = array.sublist(1, 2);
+  Expect.equals(4.0, a[0].x);
+  Expect.equals(5.0, a[0].y);
+  Expect.equals(6.0, a[0].z);
+  Expect.equals(7.0, a[0].w);
+  a = array.sublist(0);
+  Expect.equals(a.length, array.length);
+  for (int i = 0; i < array.length; i++) {
+    Expect.equals(array[i].x, a[i].x);
+    Expect.equals(array[i].y, a[i].y);
+    Expect.equals(array[i].z, a[i].z);
+    Expect.equals(array[i].w, a[i].w);
+  }
+}
+
+void testSpecialValues(array) {
+  /// Same as Expect.identical, but also works with NaNs and -0.0 for dart2js.
+  void checkEquals(expected, actual) {
+    if (expected.isNaN) {
+      Expect.isTrue(actual.isNaN);
+    } else if (expected == 0.0 && expected.isNegative) {
+      Expect.isTrue(actual == 0.0 && actual.isNegative);
+    } else {
+      Expect.equals(expected, actual);
+    }
+  }
+
+  var pairs = [
+    [0.0, 0.0],
+    [5e-324, 0.0],
+    [2.225073858507201e-308, 0.0],
+    [2.2250738585072014e-308, 0.0],
+    [0.9999999999999999, 1.0],
+    [1.0, 1.0],
+    [1.0000000000000002, 1.0],
+    [4294967295.0, 4294967296.0],
+    [4294967296.0, 4294967296.0],
+    [4503599627370495.5, 4503599627370496.0],
+    [9007199254740992.0, 9007199254740992.0],
+    [1.7976931348623157e+308, double.infinity],
+    [0.49999999999999994, 0.5],
+    [4503599627370497.0, 4503599627370496.0],
+    [9007199254740991.0, 9007199254740992.0],
+    [double.infinity, double.infinity],
+    [double.nan, double.nan],
+  ];
+
+  var conserved = [
+    1.401298464324817e-45,
+    1.1754942106924411e-38,
+    1.1754943508222875e-38,
+    0.9999999403953552,
+    1.0000001192092896,
+    8388607.5,
+    8388608.0,
+    3.4028234663852886e+38,
+    8388609.0,
+    16777215.0,
+  ];
+
+  var minusPairs = pairs.map((pair) {
+    return [-pair[0], -pair[1]];
+  });
+  var conservedPairs = conserved.map((value) => [value, value]);
+
+  var allTests = [pairs, minusPairs, conservedPairs].expand((x) => x);
+
+  for (var pair in allTests) {
+    var input = pair[0];
+    var expected = pair[1];
+    var f;
+    f = new Float32x4(input, 2.0, 3.0, 4.0);
+    array[0] = f;
+    f = array[0];
+    checkEquals(expected, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, input, 3.0, 4.0);
+    array[1] = f;
+    f = array[1];
+    Expect.equals(1.0, f.x);
+    checkEquals(expected, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, input, 4.0);
+    array[2] = f;
+    f = array[2];
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    checkEquals(expected, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, 3.0, input);
+    array[3] = f;
+    f = array[3];
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    checkEquals(expected, f.w);
+  }
+}
+
+main() {
+  var list;
+
+  list = new Float32x4List(8);
+  for (int i = 0; i < 20; i++) {
+    testLoadStore(list);
+  }
+
+  Float32List floatList = new Float32List(32);
+  for (int i = 0; i < floatList.length; i++) {
+    floatList[i] = i.toDouble();
+  }
+  list = new Float32x4List.view(floatList.buffer);
+  for (int i = 0; i < 20; i++) {
+    testView(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testSublist(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testLoadStore(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testListZero();
+  }
+  for (int i = 0; i < 20; i++) {
+    testSpecialValues(list);
+  }
+  testLoadStoreDeoptDriver();
+}
diff --git a/tests/lib/typed_data/float32x4_shuffle_test.dart b/tests/lib/typed_data/float32x4_shuffle_test.dart
new file mode 100644
index 0000000..418527f
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_shuffle_test.dart
@@ -0,0 +1,1436 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_shuffle_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+void testShuffle00() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.xxxx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xxxy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xxxz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xxxw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xxyx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xxyy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xxyz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xxyw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xxzx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xxzy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xxzz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xxzw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xxwx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xxwy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xxwz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xxww);
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle01() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.xyxx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xyxy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xyxz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xyxw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xyyx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xyyy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xyyz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xyyw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xyzx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xyzy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xyzz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xyzw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xywx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xywy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xywz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xyww);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle02() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.xzxx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xzxy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xzxz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xzxw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xzyx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xzyy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xzyz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xzyw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xzzx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xzzy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xzzz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xzzw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xzwx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xzwy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xzwz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xzww);
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle03() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.xwxx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xwxy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xwxz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xwxw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xwyx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xwyy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xwyz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xwyw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xwzx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xwzy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xwzz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xwzw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.xwwx);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.xwwy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.xwwz);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.xwww);
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle10() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.yxxx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yxxy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yxxz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yxxw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yxyx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yxyy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yxyz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yxyw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yxzx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yxzy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yxzz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yxzw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yxwx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yxwy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yxwz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yxww);
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle11() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.yyxx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yyxy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yyxz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yyxw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yyyx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yyyy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yyyz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yyyw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yyzx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yyzy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yyzz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yyzw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yywx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yywy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yywz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yyww);
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle12() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.yzxx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yzxy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yzxz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yzxw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yzyx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yzyy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yzyz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yzyw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yzzx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yzzy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yzzz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yzzw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.yzwx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.yzwy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.yzwz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.yzww);
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle13() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.ywxx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.ywxy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.ywxz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.ywxw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.ywyx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.ywyy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.ywyz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.ywyw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.ywzx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.ywzy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.ywzz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.ywzw);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.ywwx);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.ywwy);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.ywwz);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.ywww);
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle20() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.zxxx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zxxy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zxxz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zxxw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zxyx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zxyy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zxyz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zxyw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zxzx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zxzy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zxzz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zxzw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zxwx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zxwy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zxwz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zxww);
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle21() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.zyxx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zyxy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zyxz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zyxw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zyyx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zyyy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zyyz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zyyw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zyzx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zyzy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zyzz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zyzw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zywx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zywy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zywz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zyww);
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle22() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.zzxx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zzxy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zzxz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zzxw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zzyx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zzyy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zzyz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zzyw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zzzx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zzzy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zzzz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zzzw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zzwx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zzwy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zzwz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zzww);
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle23() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.zwxx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zwxy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zwxz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zwxw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zwyx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zwyy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zwyz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zwyw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zwzx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zwzy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zwzz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zwzw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.zwwx);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.zwwy);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.zwwz);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.zwww);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle30() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.wxxx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wxxy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wxxz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wxxw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wxyx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wxyy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wxyz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wxyw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wxzx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wxzy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wxzz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wxzw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wxwx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wxwy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wxwz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wxww);
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle31() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.wyxx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wyxy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wyxz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wyxw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wyyx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wyyy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wyyz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wyyw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wyzx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wyzy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wyzz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wyzw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wywx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wywy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wywz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wyww);
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle32() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.wzxx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wzxy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wzxz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wzxw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wzyx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wzyy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wzyz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wzyw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wzzx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wzzy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wzzz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wzzw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wzwx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wzwy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wzwz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wzww);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle33() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.wwxx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wwxy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wwxz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wwxw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wwyx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wwyy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wwyz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wwyw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wwzx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wwzy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wwzz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wwzw);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.shuffle(Float32x4.wwwx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.shuffle(Float32x4.wwwy);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.shuffle(Float32x4.wwwz);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.shuffle(Float32x4.wwww);
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffleNonConstant(mask) {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(mask);
+  if (mask == 1) {
+    Expect.equals(2.0, c.x);
+    Expect.equals(1.0, c.y);
+    Expect.equals(1.0, c.z);
+    Expect.equals(1.0, c.w);
+  } else {
+    Expect.equals(Float32x4.yyyy + 1, mask);
+    Expect.equals(3.0, c.x);
+    Expect.equals(2.0, c.y);
+    Expect.equals(2.0, c.z);
+    Expect.equals(2.0, c.w);
+  }
+}
+
+void testInvalidShuffle(mask) {
+  // Not a valid mask.
+  Expect.isFalse(mask <= 255 && mask >= 0);
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  Expect.throws(() {
+    c = m.shuffle(mask);
+  });
+}
+
+void testShuffle() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.shuffle(Float32x4.wzyx);
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+}
+
+main() {
+  var xxxx = Float32x4.xxxx + 1;
+  var yyyy = Float32x4.yyyy + 1;
+  for (int i = 0; i < 20; i++) {
+    testShuffle();
+    testShuffle00();
+    testShuffle01();
+    testShuffle02();
+    testShuffle03();
+    testShuffle10();
+    testShuffle11();
+    testShuffle12();
+    testShuffle13();
+    testShuffle20();
+    testShuffle21();
+    testShuffle22();
+    testShuffle23();
+    testShuffle30();
+    testShuffle31();
+    testShuffle32();
+    testShuffle33();
+    testShuffleNonConstant(xxxx);
+    testShuffleNonConstant(yyyy);
+    testInvalidShuffle(256);
+    testInvalidShuffle(-1);
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_sign_mask_test.dart b/tests/lib/typed_data/float32x4_sign_mask_test.dart
new file mode 100644
index 0000000..06a0bb0
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_sign_mask_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_sign_mask;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testImmediates() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Float32x4(-1.0, -2.0, -3.0, -0.0);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+  f = new Float32x4(-1.0, 2.0, 3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x1, m);
+  f = new Float32x4(1.0, -2.0, 3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x2, m);
+  f = new Float32x4(1.0, 2.0, -3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x4, m);
+  f = new Float32x4(1.0, 2.0, 3.0, -4.0);
+  m = f.signMask;
+  Expect.equals(0x8, m);
+}
+
+void testZero() {
+  var f = new Float32x4(0.0, 0.0, 0.0, 0.0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Float32x4(-0.0, -0.0, -0.0, -0.0);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+}
+
+void testArithmetic() {
+  var a = new Float32x4(1.0, 1.0, 1.0, 1.0);
+  var b = new Float32x4(2.0, 2.0, 2.0, 2.0);
+  var c = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+  var m1 = (a - b).signMask;
+  Expect.equals(0xf, m1);
+  var m2 = (b - a).signMask;
+  Expect.equals(0x0, m2);
+  var m3 = (c * c).signMask;
+  Expect.equals(0x0, m3);
+  var m4 = (a * c).signMask;
+  Expect.equals(0xf, m4);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testImmediates();
+    testZero();
+    testArithmetic();
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_static_test.dart b/tests/lib/typed_data/float32x4_static_test.dart
new file mode 100644
index 0000000..15ec048
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_static_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library tag to be able to run in html test framework.
+library float32x4_static_test;
+
+import 'dart:typed_data';
+
+main() {
+  var str = "foo";
+  /*@compile-error=unspecified*/ new Float32x4(str, 2.0, 3.0, 4.0);
+}
diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart
new file mode 100644
index 0000000..c68ecc1
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_test.dart
@@ -0,0 +1,525 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--no-intrinsify
+
+// Requirements=nnbd-strong
+
+// Library tag to be able to run in html test framework.
+library float32x4_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+testAdd() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m + n;
+  Expect.equals(0.0, o.x);
+  Expect.equals(0.0, o.y);
+  Expect.equals(0.0, o.z);
+  Expect.equals(0.0, o.w);
+}
+
+testNegate() {
+  var m = new Float32x4(1.0, 2.0, -3.0, -4.0);
+  m = -m;
+  Expect.equals(-1.0, m.x);
+  Expect.equals(-2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testSub() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m - n;
+  Expect.equals(-2.0, o.x);
+  Expect.equals(-4.0, o.y);
+  Expect.equals(-6.0, o.z);
+  Expect.equals(-8.0, o.w);
+}
+
+testMul() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m * n;
+  Expect.equals(-1.0, o.x);
+  Expect.equals(-4.0, o.y);
+  Expect.equals(-9.0, o.z);
+  Expect.equals(-16.0, o.w);
+}
+
+testDiv() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m / n;
+  Expect.equals(-1.0, o.x);
+  Expect.equals(-1.0, o.y);
+  Expect.equals(-1.0, o.z);
+  Expect.equals(-1.0, o.w);
+}
+
+testComparison() {
+  var m = new Float32x4(1.0, 2.0, 0.1, 0.001);
+  var n = new Float32x4(2.0, 2.0, 0.001, 0.1);
+  var cmp;
+  cmp = m.lessThan(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.lessThanOrEqual(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.equal(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(0x0, cmp.w);
+
+  cmp = m.notEqual(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.greaterThanOrEqual(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(0x0, cmp.w);
+
+  cmp = m.greaterThan(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(0x0, cmp.w);
+}
+
+testAbs() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  m = m.abs();
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testScale() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  m = m.scale(20.0);
+  Expect.equals(20.0, m.x);
+  Expect.equals(-40.0, m.y);
+  Expect.equals(60.0, m.z);
+  Expect.equals(-80.0, m.w);
+}
+
+testClamp() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  var lo = new Float32x4(0.0, 0.0, 0.0, 0.0);
+  var hi = new Float32x4(2.0, 2.0, 2.0, 2.0);
+  m = m.clamp(lo, hi);
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.0, m.y);
+  Expect.equals(2.0, m.z);
+  Expect.equals(0.0, m.w);
+}
+
+testShuffle() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var xxxx = m.shuffle(Float32x4.xxxx);
+  Expect.equals(1.0, xxxx.x);
+  Expect.equals(1.0, xxxx.y);
+  Expect.equals(1.0, xxxx.z);
+  Expect.equals(1.0, xxxx.w);
+  var yyyy = m.shuffle(Float32x4.yyyy);
+  Expect.equals(2.0, yyyy.x);
+  Expect.equals(2.0, yyyy.y);
+  Expect.equals(2.0, yyyy.z);
+  Expect.equals(2.0, yyyy.w);
+  var zzzz = m.shuffle(Float32x4.zzzz);
+  Expect.equals(3.0, zzzz.x);
+  Expect.equals(3.0, zzzz.y);
+  Expect.equals(3.0, zzzz.z);
+  Expect.equals(3.0, zzzz.w);
+  var wwww = m.shuffle(Float32x4.wwww);
+  Expect.equals(4.0, wwww.x);
+  Expect.equals(4.0, wwww.y);
+  Expect.equals(4.0, wwww.z);
+  Expect.equals(4.0, wwww.w);
+  var wzyx = m.shuffle(Float32x4.wzyx);
+  Expect.equals(4.0, wzyx.x);
+  Expect.equals(3.0, wzyx.y);
+  Expect.equals(2.0, wzyx.z);
+  Expect.equals(1.0, wzyx.w);
+  var wwzz = m.shuffle(Float32x4.wwzz);
+  Expect.equals(4.0, wwzz.x);
+  Expect.equals(4.0, wwzz.y);
+  Expect.equals(3.0, wwzz.z);
+  Expect.equals(3.0, wwzz.w);
+  var xxyy = m.shuffle(Float32x4.xxyy);
+  Expect.equals(1.0, xxyy.x);
+  Expect.equals(1.0, xxyy.y);
+  Expect.equals(2.0, xxyy.z);
+  Expect.equals(2.0, xxyy.w);
+  var yyww = m.shuffle(Float32x4.yyww);
+  Expect.equals(2.0, yyww.x);
+  Expect.equals(2.0, yyww.y);
+  Expect.equals(4.0, yyww.z);
+  Expect.equals(4.0, yyww.w);
+}
+
+testMin() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var n = new Float32x4(1.0, 0.0, 2.5, 5.0);
+  m = m.min(n);
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.0, m.y);
+  Expect.equals(2.5, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testMax() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var n = new Float32x4(1.0, 0.0, 2.5, 5.0);
+  m = m.max(n);
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(5.0, m.w);
+}
+
+testSqrt() {
+  var m = new Float32x4(1.0, 4.0, 9.0, 16.0);
+  m = m.sqrt();
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testReciprocal() {
+  var m = new Float32x4(1.0, 4.0, 9.0, 16.0);
+  m = m.reciprocal();
+  Expect.approxEquals(1.0, m.x, 0.001);
+  Expect.approxEquals(0.25, m.y, 0.001);
+  Expect.approxEquals(0.1111111, m.z, 0.001);
+  Expect.approxEquals(0.0625, m.w, 0.001);
+}
+
+testReciprocalSqrt() {
+  var m = new Float32x4(1.0, 0.25, 0.111111, 0.0625);
+  m = m.reciprocalSqrt();
+  Expect.approxEquals(1.0, m.x, 0.001);
+  Expect.approxEquals(2.0, m.y, 0.001);
+  Expect.approxEquals(3.0, m.z, 0.001);
+  Expect.approxEquals(4.0, m.w, 0.001);
+}
+
+testSelect() {
+  var m = new Int32x4.bool(true, true, false, false);
+  var t = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var f = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  var s = m.select(t, f);
+  Expect.equals(1.0, s.x);
+  Expect.equals(2.0, s.y);
+  Expect.equals(7.0, s.z);
+  Expect.equals(8.0, s.w);
+}
+
+testConversions() {
+  var m = new Int32x4(0x3F800000, 0x40000000, 0x40400000, 0x40800000);
+  var n = new Float32x4.fromInt32x4Bits(m);
+  Expect.equals(1.0, n.x);
+  Expect.equals(2.0, n.y);
+  Expect.equals(3.0, n.z);
+  Expect.equals(4.0, n.w);
+  n = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  m = new Int32x4.fromFloat32x4Bits(n);
+  Expect.equals(0x40A00000, m.x);
+  Expect.equals(0x40C00000, m.y);
+  Expect.equals(0x40E00000, m.z);
+  Expect.equals(0x41000000, m.w);
+  // Flip sign using bit-wise operators.
+  n = new Float32x4(9.0, 10.0, 11.0, 12.0);
+  m = new Int32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000);
+  var nMask = new Int32x4.fromFloat32x4Bits(n);
+  nMask = nMask ^ m; // flip sign.
+  n = new Float32x4.fromInt32x4Bits(nMask);
+  Expect.equals(-9.0, n.x);
+  Expect.equals(-10.0, n.y);
+  Expect.equals(-11.0, n.z);
+  Expect.equals(-12.0, n.w);
+  nMask = new Int32x4.fromFloat32x4Bits(n);
+  nMask = nMask ^ m; // flip sign.
+  n = new Float32x4.fromInt32x4Bits(nMask);
+  Expect.equals(9.0, n.x);
+  Expect.equals(10.0, n.y);
+  Expect.equals(11.0, n.z);
+  Expect.equals(12.0, n.w);
+}
+
+testBitOperators() {
+  var m = new Int32x4(0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA);
+  var n = new Int32x4(0x5555555, 0x5555555, 0x5555555, 0x5555555);
+  Expect.equals(0xAAAAAAA, m.x);
+  Expect.equals(0xAAAAAAA, m.y);
+  Expect.equals(0xAAAAAAA, m.z);
+  Expect.equals(0xAAAAAAA, m.w);
+  Expect.equals(0x5555555, n.x);
+  Expect.equals(0x5555555, n.y);
+  Expect.equals(0x5555555, n.z);
+  Expect.equals(0x5555555, n.w);
+  Expect.equals(true, n.flagX);
+  Expect.equals(true, n.flagY);
+  Expect.equals(true, n.flagZ);
+  Expect.equals(true, n.flagW);
+  var o = m | n; // or
+  Expect.equals(0xFFFFFFF, o.x);
+  Expect.equals(0xFFFFFFF, o.y);
+  Expect.equals(0xFFFFFFF, o.z);
+  Expect.equals(0xFFFFFFF, o.w);
+  Expect.equals(true, o.flagX);
+  Expect.equals(true, o.flagY);
+  Expect.equals(true, o.flagZ);
+  Expect.equals(true, o.flagW);
+  o = m & n; // and
+  Expect.equals(0x0, o.x);
+  Expect.equals(0x0, o.y);
+  Expect.equals(0x0, o.z);
+  Expect.equals(0x0, o.w);
+  n = n.withX(0xAAAAAAA);
+  n = n.withY(0xAAAAAAA);
+  n = n.withZ(0xAAAAAAA);
+  n = n.withW(0xAAAAAAA);
+  Expect.equals(0xAAAAAAA, n.x);
+  Expect.equals(0xAAAAAAA, n.y);
+  Expect.equals(0xAAAAAAA, n.z);
+  Expect.equals(0xAAAAAAA, n.w);
+  o = m ^ n; // xor
+  Expect.equals(0x0, o.x);
+  Expect.equals(0x0, o.y);
+  Expect.equals(0x0, o.z);
+  Expect.equals(0x0, o.w);
+  Expect.equals(false, o.flagX);
+  Expect.equals(false, o.flagY);
+  Expect.equals(false, o.flagZ);
+  Expect.equals(false, o.flagW);
+}
+
+testSetters() {
+  var f = new Float32x4.zero();
+  Expect.equals(0.0, f.x);
+  Expect.equals(0.0, f.y);
+  Expect.equals(0.0, f.z);
+  Expect.equals(0.0, f.w);
+  f = f.withX(4.0);
+  Expect.equals(4.0, f.x);
+  f = f.withY(3.0);
+  Expect.equals(3.0, f.y);
+  f = f.withZ(2.0);
+  Expect.equals(2.0, f.z);
+  f = f.withW(1.0);
+  Expect.equals(1.0, f.w);
+  f = new Float32x4.zero();
+  f = f.withX(4.0).withZ(2.0).withW(1.0).withY(3.0);
+  Expect.equals(4.0, f.x);
+  Expect.equals(3.0, f.y);
+  Expect.equals(2.0, f.z);
+  Expect.equals(1.0, f.w);
+  var m = new Int32x4.bool(false, false, false, false);
+  Expect.equals(false, m.flagX);
+  Expect.equals(false, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagX(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(false, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagY(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagZ(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagW(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(true, m.flagW);
+}
+
+testGetters() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Expect.equals(1.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(3.0, f.z);
+  Expect.equals(4.0, f.w);
+  var m = new Int32x4.bool(false, true, true, false);
+  Expect.equals(false, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(false, m.flagW);
+}
+
+void testSplat() {
+  var f = new Float32x4.splat(2.0);
+  Expect.equals(2.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(2.0, f.z);
+  Expect.equals(2.0, f.w);
+}
+
+void testZero() {
+  var f = new Float32x4.zero();
+  Expect.equals(0.0, f.x);
+  Expect.equals(0.0, f.y);
+  Expect.equals(0.0, f.z);
+  Expect.equals(0.0, f.w);
+}
+
+void testConstructor() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Expect.equals(1.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(3.0, f.z);
+  Expect.equals(4.0, f.w);
+}
+
+void testBadArguments() {
+  dynamic dynamicNull = null;
+  Expect.throwsTypeError(() => new Float32x4(dynamicNull, 2.0, 3.0, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, dynamicNull, 3.0, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, 2.0, dynamicNull, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, 2.0, 3.0, dynamicNull));
+
+  // Use local variable typed as "dynamic" to avoid static warnings.
+  dynamic str = "foo";
+  Expect.throwsTypeError(() => new Float32x4(str, 2.0, 3.0, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, str, 3.0, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, 2.0, str, 4.0));
+  Expect.throwsTypeError(() => new Float32x4(1.0, 2.0, 3.0, str));
+}
+
+void testSpecialValues() {
+  /// Same as Expect.identical, but also works with NaNs and -0.0 for dart2js.
+  void checkEquals(expected, actual) {
+    if (expected.isNaN) {
+      Expect.isTrue(actual.isNaN);
+    } else if (expected == 0.0 && expected.isNegative) {
+      Expect.isTrue(actual == 0.0 && actual.isNegative);
+    } else {
+      Expect.equals(expected, actual);
+    }
+  }
+
+  var pairs = [
+    [0.0, 0.0],
+    [5e-324, 0.0],
+    [2.225073858507201e-308, 0.0],
+    [2.2250738585072014e-308, 0.0],
+    [0.9999999999999999, 1.0],
+    [1.0, 1.0],
+    [1.0000000000000002, 1.0],
+    [4294967295.0, 4294967296.0],
+    [4294967296.0, 4294967296.0],
+    [4503599627370495.5, 4503599627370496.0],
+    [9007199254740992.0, 9007199254740992.0],
+    [1.7976931348623157e+308, double.infinity],
+    [0.49999999999999994, 0.5],
+    [4503599627370497.0, 4503599627370496.0],
+    [9007199254740991.0, 9007199254740992.0],
+    [double.infinity, double.infinity],
+    [double.nan, double.nan],
+  ];
+
+  var conserved = [
+    1.401298464324817e-45,
+    1.1754942106924411e-38,
+    1.1754943508222875e-38,
+    0.9999999403953552,
+    1.0000001192092896,
+    8388607.5,
+    8388608.0,
+    3.4028234663852886e+38,
+    8388609.0,
+    16777215.0,
+  ];
+
+  var minusPairs = pairs.map((pair) {
+    return [-pair[0], -pair[1]];
+  });
+  var conservedPairs = conserved.map((value) => [value, value]);
+
+  var allTests = [pairs, minusPairs, conservedPairs].expand((x) => x);
+
+  for (var pair in allTests) {
+    var input = pair[0];
+    var expected = pair[1];
+    var f;
+    f = new Float32x4(input, 2.0, 3.0, 4.0);
+    checkEquals(expected, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, input, 3.0, 4.0);
+    Expect.equals(1.0, f.x);
+    checkEquals(expected, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, input, 4.0);
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    checkEquals(expected, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, 3.0, input);
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    checkEquals(expected, f.w);
+  }
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testConstructor();
+    testSplat();
+    testZero();
+    testAdd();
+    testGetters();
+    testSetters();
+    testBitOperators();
+    testConversions();
+    testSelect();
+    testShuffle();
+    testSub();
+    testNegate();
+    testMul();
+    testDiv();
+    testComparison();
+    testScale();
+    testClamp();
+    testAbs();
+    testMin();
+    testMax();
+    testSqrt();
+    testReciprocal();
+    testReciprocalSqrt();
+    testBadArguments();
+    testSpecialValues();
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_transpose_test.dart b/tests/lib/typed_data/float32x4_transpose_test.dart
new file mode 100644
index 0000000..062cb7b
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_transpose_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_transpose_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void transpose(Float32x4List m) {
+  Expect.equals(4, m.length);
+  var m0 = m[0];
+  var m1 = m[1];
+  var m2 = m[2];
+  var m3 = m[3];
+
+  var t0 = m0.shuffleMix(m1, Float32x4.xyxy);
+  var t1 = m2.shuffleMix(m3, Float32x4.xyxy);
+  m[0] = t0.shuffleMix(t1, Float32x4.xzxz);
+  m[1] = t0.shuffleMix(t1, Float32x4.ywyw);
+
+  var t2 = m0.shuffleMix(m1, Float32x4.zwzw);
+  var t3 = m2.shuffleMix(m3, Float32x4.zwzw);
+  m[2] = t2.shuffleMix(t3, Float32x4.xzxz);
+  m[3] = t2.shuffleMix(t3, Float32x4.ywyw);
+}
+
+void testTranspose(Float32x4List m, Float32x4List r) {
+  transpose(m); // In place transpose.
+  for (int i = 0; i < 4; i++) {
+    var a = m[i];
+    var b = r[i];
+    Expect.equals(b.x, a.x);
+    Expect.equals(b.y, a.y);
+    Expect.equals(b.z, a.z);
+    Expect.equals(b.w, a.w);
+  }
+}
+
+main() {
+  var A = new Float32x4List(4);
+  A[0] = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  A[1] = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  A[2] = new Float32x4(9.0, 10.0, 11.0, 12.0);
+  A[3] = new Float32x4(13.0, 14.0, 15.0, 16.0);
+  var B = new Float32x4List(4);
+  B[0] = new Float32x4(1.0, 5.0, 9.0, 13.0);
+  B[1] = new Float32x4(2.0, 6.0, 10.0, 14.0);
+  B[2] = new Float32x4(3.0, 7.0, 11.0, 15.0);
+  B[3] = new Float32x4(4.0, 8.0, 12.0, 16.0);
+  var I = new Float32x4List(4);
+  I[0] = new Float32x4(1.0, 0.0, 0.0, 0.0);
+  I[1] = new Float32x4(0.0, 1.0, 0.0, 0.0);
+  I[2] = new Float32x4(0.0, 0.0, 1.0, 0.0);
+  I[3] = new Float32x4(0.0, 0.0, 0.0, 1.0);
+  for (int i = 0; i < 20; i++) {
+    var m = new Float32x4List.fromList(I);
+    testTranspose(m, I);
+    m = new Float32x4List.fromList(A);
+    testTranspose(m, B);
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
new file mode 100644
index 0000000..db6c253
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_two_arg_shuffle_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+testWithZWInXY() {
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  Float32x4 c = b.shuffleMix(a, Float32x4.zwzw);
+  Expect.equals(7.0, c.x);
+  Expect.equals(8.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+testInterleaveXY() {
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  Float32x4 c = a.shuffleMix(b, Float32x4.xyxy).shuffle(Float32x4.xzyw);
+  Expect.equals(1.0, c.x);
+  Expect.equals(5.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(6.0, c.w);
+}
+
+testInterleaveZW() {
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  Float32x4 c = a.shuffleMix(b, Float32x4.zwzw).shuffle(Float32x4.xzyw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(7.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(8.0, c.w);
+}
+
+testInterleaveXYPairs() {
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  Float32x4 c = a.shuffleMix(b, Float32x4.xyxy);
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(5.0, c.z);
+  Expect.equals(6.0, c.w);
+}
+
+testInterleaveZWPairs() {
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  Float32x4 c = a.shuffleMix(b, Float32x4.zwzw);
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(7.0, c.z);
+  Expect.equals(8.0, c.w);
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testWithZWInXY();
+    testInterleaveXY();
+    testInterleaveZW();
+    testInterleaveXYPairs();
+    testInterleaveZWPairs();
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_unbox_phi_test.dart b/tests/lib/typed_data/float32x4_unbox_phi_test.dart
new file mode 100644
index 0000000..d96b2cf
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_unbox_phi_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_unbox_regress_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+double testUnboxPhi(Float32x4List data) {
+  var res = new Float32x4.zero();
+  for (int i = 0; i < data.length; i++) {
+    res += data[i];
+  }
+  return res.x + res.y + res.z + res.w;
+}
+
+main() {
+  Float32x4List list = new Float32x4List(10);
+  Float32List floatList = new Float32List.view(list.buffer);
+  for (int i = 0; i < floatList.length; i++) {
+    floatList[i] = i.toDouble();
+  }
+  for (int i = 0; i < 20; i++) {
+    double r = testUnboxPhi(list);
+    Expect.equals(780.0, r);
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_unbox_regress_test.dart b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
new file mode 100644
index 0000000..3955990
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library float32x4_unbox_regress_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+testListStore(array, index, value) {
+  array[index] = value;
+}
+
+void testListStoreDeopt() {
+  var list;
+  var value = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var smi = 12;
+  list = new Float32x4List(8);
+  for (int i = 0; i < 20; i++) {
+    testListStore(list, 0, value);
+  }
+
+  try {
+    // Without a proper check for SMI in the Float32x4 unbox instruction
+    // this might trigger a crash.
+    testListStore(list, 0, smi);
+  } catch (_) {}
+}
+
+testAdd(a, b) {
+  var c = a + b;
+  Expect.equals(3.0, c.x);
+  Expect.equals(5.0, c.y);
+  Expect.equals(7.0, c.z);
+  Expect.equals(9.0, c.w);
+}
+
+void testAddDeopt() {
+  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var b = new Float32x4(2.0, 3.0, 4.0, 5.0);
+  var smi = 12;
+  for (int i = 0; i < 20; i++) {
+    testAdd(a, b);
+  }
+
+  try {
+    testAdd(a, smi);
+  } catch (_) {}
+}
+
+testGet(a) {
+  var c = a.x + a.y + a.z + a.w;
+  Expect.equals(10.0, c);
+}
+
+void testGetDeopt() {
+  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var smi = 12;
+  for (int i = 0; i < 20; i++) {
+    testGet(a);
+  }
+
+  try {
+    testGet(12);
+  } catch (_) {}
+
+  for (int i = 0; i < 20; i++) {
+    testGet(a);
+  }
+}
+
+void testComparison(a, b) {
+  Int32x4 r = a.equal(b);
+  Expect.equals(true, r.flagX);
+  Expect.equals(false, r.flagY);
+  Expect.equals(false, r.flagZ);
+  Expect.equals(true, r.flagW);
+}
+
+void testComparisonDeopt() {
+  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var b = new Float32x4(1.0, 2.1, 3.1, 4.0);
+  var smi = 12;
+
+  for (int i = 0; i < 20; i++) {
+    testComparison(a, b);
+  }
+
+  try {
+    testComparison(a, smi);
+  } catch (_) {}
+
+  for (int i = 0; i < 20; i++) {
+    testComparison(a, b);
+  }
+
+  try {
+    testComparison(smi, a);
+  } catch (_) {}
+
+  for (int i = 0; i < 20; i++) {
+    testComparison(a, b);
+  }
+}
+
+main() {
+  testListStoreDeopt();
+  testAddDeopt();
+  testGetDeopt();
+  testComparisonDeopt();
+}
diff --git a/tests/lib/typed_data/float32x4_weak_test.dart b/tests/lib/typed_data/float32x4_weak_test.dart
new file mode 100644
index 0000000..3892377
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_weak_test.dart
@@ -0,0 +1,534 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--no-intrinsify
+
+// Requirements=nnbd-weak
+
+// Library tag to be able to run in html test framework.
+library float32x4_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+testAdd() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m + n;
+  Expect.equals(0.0, o.x);
+  Expect.equals(0.0, o.y);
+  Expect.equals(0.0, o.z);
+  Expect.equals(0.0, o.w);
+}
+
+testNegate() {
+  var m = new Float32x4(1.0, 2.0, -3.0, -4.0);
+  m = -m;
+  Expect.equals(-1.0, m.x);
+  Expect.equals(-2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testSub() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m - n;
+  Expect.equals(-2.0, o.x);
+  Expect.equals(-4.0, o.y);
+  Expect.equals(-6.0, o.z);
+  Expect.equals(-8.0, o.w);
+}
+
+testMul() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m * n;
+  Expect.equals(-1.0, o.x);
+  Expect.equals(-4.0, o.y);
+  Expect.equals(-9.0, o.z);
+  Expect.equals(-16.0, o.w);
+}
+
+testDiv() {
+  var m = new Float32x4(-1.0, -2.0, -3.0, -4.0);
+  var n = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var o = m / n;
+  Expect.equals(-1.0, o.x);
+  Expect.equals(-1.0, o.y);
+  Expect.equals(-1.0, o.z);
+  Expect.equals(-1.0, o.w);
+}
+
+testComparison() {
+  var m = new Float32x4(1.0, 2.0, 0.1, 0.001);
+  var n = new Float32x4(2.0, 2.0, 0.001, 0.1);
+  var cmp;
+  cmp = m.lessThan(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.lessThanOrEqual(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.equal(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(0x0, cmp.z);
+  Expect.equals(0x0, cmp.w);
+
+  cmp = m.notEqual(n);
+  Expect.equals(-1, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(-1, cmp.w);
+
+  cmp = m.greaterThanOrEqual(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(-1, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(0x0, cmp.w);
+
+  cmp = m.greaterThan(n);
+  Expect.equals(0x0, cmp.x);
+  Expect.equals(0x0, cmp.y);
+  Expect.equals(-1, cmp.z);
+  Expect.equals(0x0, cmp.w);
+}
+
+testAbs() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  m = m.abs();
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testScale() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  m = m.scale(20.0);
+  Expect.equals(20.0, m.x);
+  Expect.equals(-40.0, m.y);
+  Expect.equals(60.0, m.z);
+  Expect.equals(-80.0, m.w);
+}
+
+testClamp() {
+  var m = new Float32x4(1.0, -2.0, 3.0, -4.0);
+  var lo = new Float32x4(0.0, 0.0, 0.0, 0.0);
+  var hi = new Float32x4(2.0, 2.0, 2.0, 2.0);
+  m = m.clamp(lo, hi);
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.0, m.y);
+  Expect.equals(2.0, m.z);
+  Expect.equals(0.0, m.w);
+}
+
+testShuffle() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var xxxx = m.shuffle(Float32x4.xxxx);
+  Expect.equals(1.0, xxxx.x);
+  Expect.equals(1.0, xxxx.y);
+  Expect.equals(1.0, xxxx.z);
+  Expect.equals(1.0, xxxx.w);
+  var yyyy = m.shuffle(Float32x4.yyyy);
+  Expect.equals(2.0, yyyy.x);
+  Expect.equals(2.0, yyyy.y);
+  Expect.equals(2.0, yyyy.z);
+  Expect.equals(2.0, yyyy.w);
+  var zzzz = m.shuffle(Float32x4.zzzz);
+  Expect.equals(3.0, zzzz.x);
+  Expect.equals(3.0, zzzz.y);
+  Expect.equals(3.0, zzzz.z);
+  Expect.equals(3.0, zzzz.w);
+  var wwww = m.shuffle(Float32x4.wwww);
+  Expect.equals(4.0, wwww.x);
+  Expect.equals(4.0, wwww.y);
+  Expect.equals(4.0, wwww.z);
+  Expect.equals(4.0, wwww.w);
+  var wzyx = m.shuffle(Float32x4.wzyx);
+  Expect.equals(4.0, wzyx.x);
+  Expect.equals(3.0, wzyx.y);
+  Expect.equals(2.0, wzyx.z);
+  Expect.equals(1.0, wzyx.w);
+  var wwzz = m.shuffle(Float32x4.wwzz);
+  Expect.equals(4.0, wwzz.x);
+  Expect.equals(4.0, wwzz.y);
+  Expect.equals(3.0, wwzz.z);
+  Expect.equals(3.0, wwzz.w);
+  var xxyy = m.shuffle(Float32x4.xxyy);
+  Expect.equals(1.0, xxyy.x);
+  Expect.equals(1.0, xxyy.y);
+  Expect.equals(2.0, xxyy.z);
+  Expect.equals(2.0, xxyy.w);
+  var yyww = m.shuffle(Float32x4.yyww);
+  Expect.equals(2.0, yyww.x);
+  Expect.equals(2.0, yyww.y);
+  Expect.equals(4.0, yyww.z);
+  Expect.equals(4.0, yyww.w);
+}
+
+testMin() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var n = new Float32x4(1.0, 0.0, 2.5, 5.0);
+  m = m.min(n);
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.0, m.y);
+  Expect.equals(2.5, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testMax() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var n = new Float32x4(1.0, 0.0, 2.5, 5.0);
+  m = m.max(n);
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(5.0, m.w);
+}
+
+testSqrt() {
+  var m = new Float32x4(1.0, 4.0, 9.0, 16.0);
+  m = m.sqrt();
+  Expect.equals(1.0, m.x);
+  Expect.equals(2.0, m.y);
+  Expect.equals(3.0, m.z);
+  Expect.equals(4.0, m.w);
+}
+
+testReciprocal() {
+  var m = new Float32x4(1.0, 4.0, 9.0, 16.0);
+  m = m.reciprocal();
+  Expect.approxEquals(1.0, m.x, 0.001);
+  Expect.approxEquals(0.25, m.y, 0.001);
+  Expect.approxEquals(0.1111111, m.z, 0.001);
+  Expect.approxEquals(0.0625, m.w, 0.001);
+}
+
+testReciprocalSqrt() {
+  var m = new Float32x4(1.0, 0.25, 0.111111, 0.0625);
+  m = m.reciprocalSqrt();
+  Expect.approxEquals(1.0, m.x, 0.001);
+  Expect.approxEquals(2.0, m.y, 0.001);
+  Expect.approxEquals(3.0, m.z, 0.001);
+  Expect.approxEquals(4.0, m.w, 0.001);
+}
+
+testSelect() {
+  var m = new Int32x4.bool(true, true, false, false);
+  var t = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var f = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  var s = m.select(t, f);
+  Expect.equals(1.0, s.x);
+  Expect.equals(2.0, s.y);
+  Expect.equals(7.0, s.z);
+  Expect.equals(8.0, s.w);
+}
+
+testConversions() {
+  var m = new Int32x4(0x3F800000, 0x40000000, 0x40400000, 0x40800000);
+  var n = new Float32x4.fromInt32x4Bits(m);
+  Expect.equals(1.0, n.x);
+  Expect.equals(2.0, n.y);
+  Expect.equals(3.0, n.z);
+  Expect.equals(4.0, n.w);
+  n = new Float32x4(5.0, 6.0, 7.0, 8.0);
+  m = new Int32x4.fromFloat32x4Bits(n);
+  Expect.equals(0x40A00000, m.x);
+  Expect.equals(0x40C00000, m.y);
+  Expect.equals(0x40E00000, m.z);
+  Expect.equals(0x41000000, m.w);
+  // Flip sign using bit-wise operators.
+  n = new Float32x4(9.0, 10.0, 11.0, 12.0);
+  m = new Int32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000);
+  var nMask = new Int32x4.fromFloat32x4Bits(n);
+  nMask = nMask ^ m; // flip sign.
+  n = new Float32x4.fromInt32x4Bits(nMask);
+  Expect.equals(-9.0, n.x);
+  Expect.equals(-10.0, n.y);
+  Expect.equals(-11.0, n.z);
+  Expect.equals(-12.0, n.w);
+  nMask = new Int32x4.fromFloat32x4Bits(n);
+  nMask = nMask ^ m; // flip sign.
+  n = new Float32x4.fromInt32x4Bits(nMask);
+  Expect.equals(9.0, n.x);
+  Expect.equals(10.0, n.y);
+  Expect.equals(11.0, n.z);
+  Expect.equals(12.0, n.w);
+}
+
+testBitOperators() {
+  var m = new Int32x4(0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA);
+  var n = new Int32x4(0x5555555, 0x5555555, 0x5555555, 0x5555555);
+  Expect.equals(0xAAAAAAA, m.x);
+  Expect.equals(0xAAAAAAA, m.y);
+  Expect.equals(0xAAAAAAA, m.z);
+  Expect.equals(0xAAAAAAA, m.w);
+  Expect.equals(0x5555555, n.x);
+  Expect.equals(0x5555555, n.y);
+  Expect.equals(0x5555555, n.z);
+  Expect.equals(0x5555555, n.w);
+  Expect.equals(true, n.flagX);
+  Expect.equals(true, n.flagY);
+  Expect.equals(true, n.flagZ);
+  Expect.equals(true, n.flagW);
+  var o = m | n; // or
+  Expect.equals(0xFFFFFFF, o.x);
+  Expect.equals(0xFFFFFFF, o.y);
+  Expect.equals(0xFFFFFFF, o.z);
+  Expect.equals(0xFFFFFFF, o.w);
+  Expect.equals(true, o.flagX);
+  Expect.equals(true, o.flagY);
+  Expect.equals(true, o.flagZ);
+  Expect.equals(true, o.flagW);
+  o = m & n; // and
+  Expect.equals(0x0, o.x);
+  Expect.equals(0x0, o.y);
+  Expect.equals(0x0, o.z);
+  Expect.equals(0x0, o.w);
+  n = n.withX(0xAAAAAAA);
+  n = n.withY(0xAAAAAAA);
+  n = n.withZ(0xAAAAAAA);
+  n = n.withW(0xAAAAAAA);
+  Expect.equals(0xAAAAAAA, n.x);
+  Expect.equals(0xAAAAAAA, n.y);
+  Expect.equals(0xAAAAAAA, n.z);
+  Expect.equals(0xAAAAAAA, n.w);
+  o = m ^ n; // xor
+  Expect.equals(0x0, o.x);
+  Expect.equals(0x0, o.y);
+  Expect.equals(0x0, o.z);
+  Expect.equals(0x0, o.w);
+  Expect.equals(false, o.flagX);
+  Expect.equals(false, o.flagY);
+  Expect.equals(false, o.flagZ);
+  Expect.equals(false, o.flagW);
+}
+
+testSetters() {
+  var f = new Float32x4.zero();
+  Expect.equals(0.0, f.x);
+  Expect.equals(0.0, f.y);
+  Expect.equals(0.0, f.z);
+  Expect.equals(0.0, f.w);
+  f = f.withX(4.0);
+  Expect.equals(4.0, f.x);
+  f = f.withY(3.0);
+  Expect.equals(3.0, f.y);
+  f = f.withZ(2.0);
+  Expect.equals(2.0, f.z);
+  f = f.withW(1.0);
+  Expect.equals(1.0, f.w);
+  f = new Float32x4.zero();
+  f = f.withX(4.0).withZ(2.0).withW(1.0).withY(3.0);
+  Expect.equals(4.0, f.x);
+  Expect.equals(3.0, f.y);
+  Expect.equals(2.0, f.z);
+  Expect.equals(1.0, f.w);
+  var m = new Int32x4.bool(false, false, false, false);
+  Expect.equals(false, m.flagX);
+  Expect.equals(false, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagX(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(false, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagY(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(false, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagZ(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(false, m.flagW);
+  m = m.withFlagW(true);
+  Expect.equals(true, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(true, m.flagW);
+}
+
+testGetters() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Expect.equals(1.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(3.0, f.z);
+  Expect.equals(4.0, f.w);
+  var m = new Int32x4.bool(false, true, true, false);
+  Expect.equals(false, m.flagX);
+  Expect.equals(true, m.flagY);
+  Expect.equals(true, m.flagZ);
+  Expect.equals(false, m.flagW);
+}
+
+void testSplat() {
+  var f = new Float32x4.splat(2.0);
+  Expect.equals(2.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(2.0, f.z);
+  Expect.equals(2.0, f.w);
+}
+
+void testZero() {
+  var f = new Float32x4.zero();
+  Expect.equals(0.0, f.x);
+  Expect.equals(0.0, f.y);
+  Expect.equals(0.0, f.z);
+  Expect.equals(0.0, f.w);
+}
+
+void testConstructor() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Expect.equals(1.0, f.x);
+  Expect.equals(2.0, f.y);
+  Expect.equals(3.0, f.z);
+  Expect.equals(4.0, f.w);
+}
+
+void testBadArguments() {
+  // This test runs in weak checking mode, so `e as double` will complete
+  // normally when `e` evaluates to the null object. This means that we do
+  // not get the `TypeError` that we would have in strong checking mode, but
+  // we happen to get an `ArgumentError` from the body of the constructor.
+
+  dynamic dynamicNull = null;
+  Expect.throwsArgumentError(() => new Float32x4(dynamicNull, 2.0, 3.0, 4.0));
+  Expect.throwsArgumentError(() => new Float32x4(1.0, dynamicNull, 3.0, 4.0));
+  Expect.throwsArgumentError(() => new Float32x4(1.0, 2.0, dynamicNull, 4.0));
+  Expect.throwsArgumentError(() => new Float32x4(1.0, 2.0, 3.0, dynamicNull));
+
+  bool isTypeError(e) => e is TypeError;
+
+  // Use local variable typed as "dynamic" to avoid static warnings.
+  // When `e` evaluates to a string, `e as double` will fail, so we do get
+  // the `TypeError`.
+  dynamic str = "foo";
+  Expect.throws(() => new Float32x4(str, 2.0, 3.0, 4.0), isTypeError);
+  Expect.throws(() => new Float32x4(1.0, str, 3.0, 4.0), isTypeError);
+  Expect.throws(() => new Float32x4(1.0, 2.0, str, 4.0), isTypeError);
+  Expect.throws(() => new Float32x4(1.0, 2.0, 3.0, str), isTypeError);
+}
+
+void testSpecialValues() {
+  /// Same as Expect.identical, but also works with NaNs and -0.0 for dart2js.
+  void checkEquals(expected, actual) {
+    if (expected.isNaN) {
+      Expect.isTrue(actual.isNaN);
+    } else if (expected == 0.0 && expected.isNegative) {
+      Expect.isTrue(actual == 0.0 && actual.isNegative);
+    } else {
+      Expect.equals(expected, actual);
+    }
+  }
+
+  var pairs = [
+    [0.0, 0.0],
+    [5e-324, 0.0],
+    [2.225073858507201e-308, 0.0],
+    [2.2250738585072014e-308, 0.0],
+    [0.9999999999999999, 1.0],
+    [1.0, 1.0],
+    [1.0000000000000002, 1.0],
+    [4294967295.0, 4294967296.0],
+    [4294967296.0, 4294967296.0],
+    [4503599627370495.5, 4503599627370496.0],
+    [9007199254740992.0, 9007199254740992.0],
+    [1.7976931348623157e+308, double.infinity],
+    [0.49999999999999994, 0.5],
+    [4503599627370497.0, 4503599627370496.0],
+    [9007199254740991.0, 9007199254740992.0],
+    [double.infinity, double.infinity],
+    [double.nan, double.nan],
+  ];
+
+  var conserved = [
+    1.401298464324817e-45,
+    1.1754942106924411e-38,
+    1.1754943508222875e-38,
+    0.9999999403953552,
+    1.0000001192092896,
+    8388607.5,
+    8388608.0,
+    3.4028234663852886e+38,
+    8388609.0,
+    16777215.0,
+  ];
+
+  var minusPairs = pairs.map((pair) {
+    return [-pair[0], -pair[1]];
+  });
+  var conservedPairs = conserved.map((value) => [value, value]);
+
+  var allTests = [pairs, minusPairs, conservedPairs].expand((x) => x);
+
+  for (var pair in allTests) {
+    var input = pair[0];
+    var expected = pair[1];
+    var f;
+    f = new Float32x4(input, 2.0, 3.0, 4.0);
+    checkEquals(expected, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, input, 3.0, 4.0);
+    Expect.equals(1.0, f.x);
+    checkEquals(expected, f.y);
+    Expect.equals(3.0, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, input, 4.0);
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    checkEquals(expected, f.z);
+    Expect.equals(4.0, f.w);
+
+    f = new Float32x4(1.0, 2.0, 3.0, input);
+    Expect.equals(1.0, f.x);
+    Expect.equals(2.0, f.y);
+    Expect.equals(3.0, f.z);
+    checkEquals(expected, f.w);
+  }
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testConstructor();
+    testSplat();
+    testZero();
+    testAdd();
+    testGetters();
+    testSetters();
+    testBitOperators();
+    testConversions();
+    testSelect();
+    testShuffle();
+    testSub();
+    testNegate();
+    testMul();
+    testDiv();
+    testComparison();
+    testScale();
+    testClamp();
+    testAbs();
+    testMin();
+    testMax();
+    testSqrt();
+    testReciprocal();
+    testReciprocalSqrt();
+    testBadArguments();
+    testSpecialValues();
+  }
+}
diff --git a/tests/lib/typed_data/float64x2_functional_test.dart b/tests/lib/typed_data/float64x2_functional_test.dart
new file mode 100644
index 0000000..69aa96e
--- /dev/null
+++ b/tests/lib/typed_data/float64x2_functional_test.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--no-intrinsify
+
+library float64x2_functional_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+testConstructor() {
+  var a = new Float64x2(1.0, 2.0);
+  Expect.equals(1.0, a.x);
+  Expect.equals(2.0, a.y);
+  var b = new Float64x2.splat(1.0);
+  Expect.equals(1.0, b.x);
+  Expect.equals(1.0, b.y);
+  var c = new Float64x2.zero();
+  Expect.equals(0.0, c.x);
+  Expect.equals(0.0, c.y);
+}
+
+testCastConstructor() {
+  var a = new Float32x4(9.0, 8.0, 7.0, 6.0);
+  var b = new Float64x2.fromFloat32x4(a);
+  Expect.equals(9.0, b.x);
+  Expect.equals(8.0, b.y);
+  var c = new Float32x4.fromFloat64x2(b);
+  Expect.equals(9.0, c.x);
+  Expect.equals(8.0, c.y);
+  Expect.equals(0.0, c.z);
+  Expect.equals(0.0, c.w);
+}
+
+testLaneSetter() {
+  var a = new Float64x2.zero();
+  Expect.equals(0.0, a.x);
+  Expect.equals(0.0, a.y);
+  var b = a.withX(99.0);
+  Expect.equals(0.0, a.x);
+  Expect.equals(0.0, a.y);
+  Expect.equals(99.0, b.x);
+  Expect.equals(0.0, b.y);
+  var c = a.withY(88.0);
+  Expect.equals(0.0, a.x);
+  Expect.equals(0.0, a.y);
+  Expect.equals(0.0, c.x);
+  Expect.equals(88.0, c.y);
+  var d = c.withX(11.0);
+  Expect.equals(0.0, c.x);
+  Expect.equals(88.0, c.y);
+  Expect.equals(11.0, d.x);
+  Expect.equals(88.0, d.y);
+}
+
+testNegate() {
+  var m = new Float64x2(1.0, -2.0);
+  var o = -m;
+  Expect.equals(-1.0, o.x);
+  Expect.equals(2.0, o.y);
+}
+
+testAdd() {
+  var m = new Float64x2(1.0, -2.0);
+  var n = new Float64x2(1.0, 2.0);
+  var o = m + n;
+  Expect.equals(2.0, o.x);
+  Expect.equals(0.0, o.y);
+}
+
+testSub() {
+  var m = new Float64x2(1.5, -2.0);
+  var n = new Float64x2(1.0, 2.0);
+  var o = m - n;
+  Expect.equals(0.5, o.x);
+  Expect.equals(-4.0, o.y);
+}
+
+testMul() {
+  var m = new Float64x2(1.0, -2.0);
+  var n = new Float64x2(2.0, 2.0);
+  var o = m * n;
+  Expect.equals(2.0, o.x);
+  Expect.equals(-4.0, o.y);
+}
+
+testDiv() {
+  var m = new Float64x2(1.0, -2.0);
+  var n = new Float64x2(2.0, 2.0);
+  var o = m / n;
+  Expect.equals(0.5, o.x);
+  Expect.equals(-1.0, o.y);
+}
+
+testScale() {
+  var m = new Float64x2(1.0, 0.5);
+  var n = m.scale(2.0);
+  Expect.equals(2.0, n.x);
+  Expect.equals(1.0, n.y);
+}
+
+testAbs() {
+  var m = new Float64x2(1.0, -0.5).abs();
+  var n = new Float64x2(-2.0, 1.0).abs();
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.5, m.y);
+  Expect.equals(2.0, n.x);
+  Expect.equals(1.0, n.y);
+}
+
+testClamp() {
+  var m = new Float64x2(1.0, -2.0);
+  var lo = new Float64x2(0.0, 0.5);
+  var hi = new Float64x2(2.0, 2.0);
+  m = m.clamp(lo, hi);
+  Expect.equals(1.0, m.x);
+  Expect.equals(0.5, m.y);
+}
+
+testSignMask() {
+  var m = new Float64x2(-1.0, -0.0);
+  Expect.equals(3, m.signMask);
+  m = new Float64x2(0.0, 0.0);
+  Expect.equals(0, m.signMask);
+  m = new Float64x2(-1.0, 0.0);
+  Expect.equals(1, m.signMask);
+  m = new Float64x2(1.0, -0.0);
+  Expect.equals(2, m.signMask);
+}
+
+testMin() {
+  var m = new Float64x2(0.0, -99.0);
+  var n = new Float64x2(-1.0, -1.0);
+  var o = m.min(n);
+  Expect.equals(-1.0, o.x);
+  Expect.equals(-99.0, o.y);
+}
+
+testMax() {
+  var m = new Float64x2(0.5, -99.0);
+  var n = new Float64x2(-1.0, -1.0);
+  var o = m.max(n);
+  Expect.equals(0.5, o.x);
+  Expect.equals(-1.0, o.y);
+}
+
+testSqrt() {
+  var m = new Float64x2(9.0, 16.0);
+  var o = m.sqrt();
+  Expect.equals(3.0, o.x);
+  Expect.equals(4.0, o.y);
+}
+
+testTypedList() {
+  var m = new Float64x2List(2);
+  var n = m[0];
+  Expect.equals(0.0, n.x);
+  Expect.equals(0.0, n.y);
+  n = n.withX(1.0);
+  n = n.withY(2.0);
+  m[0] = n;
+  n = n.withX(99.0);
+  Expect.equals(99.0, n.x);
+  Expect.equals(1.0, m[0].x);
+  Expect.equals(2.0, m[0].y);
+}
+
+testTypedListFromList() {
+  var l = [new Float64x2(1.0, 2.0), new Float64x2(3.0, 4.0)];
+  var m = new Float64x2List.fromList(l);
+  Expect.equals(2, m.length);
+  Expect.equals(16, m.elementSizeInBytes);
+  Expect.equals(32, m.lengthInBytes);
+  Expect.equals(1.0, m[0].x);
+  Expect.equals(2.0, m[0].y);
+  Expect.equals(3.0, m[1].x);
+  Expect.equals(4.0, m[1].y);
+}
+
+testTypedListFromTypedList() {
+  var l = new Float64x2List(2);
+  l[0] = new Float64x2(1.0, 2.0);
+  l[1] = new Float64x2(3.0, 4.0);
+  Expect.equals(2, l.length);
+  Expect.equals(16, l.elementSizeInBytes);
+  Expect.equals(32, l.lengthInBytes);
+  Expect.equals(1.0, l[0].x);
+  Expect.equals(2.0, l[0].y);
+  Expect.equals(3.0, l[1].x);
+  Expect.equals(4.0, l[1].y);
+  var m = new Float64x2List.fromList(l);
+  Expect.equals(2, m.length);
+  Expect.equals(16, m.elementSizeInBytes);
+  Expect.equals(32, m.lengthInBytes);
+  Expect.equals(2, m.length);
+  Expect.equals(1.0, m[0].x);
+  Expect.equals(2.0, m[0].y);
+  Expect.equals(3.0, m[1].x);
+  Expect.equals(4.0, m[1].y);
+}
+
+testTypedListView() {
+  var l = [1.0, 2.0, 3.0, 4.0];
+  Expect.equals(4, l.length);
+  var fl = new Float64List.fromList(l);
+  Expect.equals(4, fl.length);
+  var m = new Float64x2List.view(fl.buffer);
+  Expect.equals(2, m.length);
+  Expect.equals(1.0, m[0].x);
+  Expect.equals(2.0, m[0].y);
+  Expect.equals(3.0, m[1].x);
+  Expect.equals(4.0, m[1].y);
+}
+
+testTypedListFullView() {
+  var l = [new Float64x2(1.0, 2.0), new Float64x2(3.0, 4.0)];
+  var m = new Float64x2List.fromList(l);
+  Expect.equals(2, m.length);
+  Expect.equals(1.0, m[0].x);
+  Expect.equals(2.0, m[0].y);
+  Expect.equals(3.0, m[1].x);
+  Expect.equals(4.0, m[1].y);
+  // Create a view which spans the entire buffer.
+  var n = new Float64x2List.view(m.buffer);
+  Expect.equals(2, n.length);
+  Expect.equals(1.0, n[0].x);
+  Expect.equals(2.0, n[0].y);
+  Expect.equals(3.0, n[1].x);
+  Expect.equals(4.0, n[1].y);
+  // Create a view which spans the entire buffer by specifying length.
+  var o = new Float64x2List.view(m.buffer, 0, 2);
+  Expect.equals(2, o.length);
+  Expect.equals(1.0, o[0].x);
+  Expect.equals(2.0, o[0].y);
+  Expect.equals(3.0, o[1].x);
+  Expect.equals(4.0, o[1].y);
+}
+
+testSubList() {
+  var l = [new Float64x2(1.0, 2.0), new Float64x2(3.0, 4.0)];
+  var m = new Float64x2List.fromList(l);
+  var n = m.sublist(0, 1);
+  Expect.equals(1, n.length);
+  Expect.equals(1.0, n[0].x);
+  Expect.equals(2.0, n[0].y);
+  var o = m.sublist(1, 2);
+  Expect.equals(1, o.length);
+  Expect.equals(3.0, o[0].x);
+  Expect.equals(4.0, o[0].y);
+}
+
+testSubView() {
+  var l = [new Float64x2(1.0, 2.0), new Float64x2(3.0, 4.0)];
+  var m = new Float64x2List.fromList(l);
+  var n = new Float64x2List.view(m.buffer, 16, 1);
+  Expect.equals(1, n.length);
+  Expect.equals(16, n.offsetInBytes);
+  Expect.equals(16, n.lengthInBytes);
+  Expect.equals(3.0, n[0].x);
+  Expect.equals(4.0, n[0].y);
+  var o = new Float64x2List.view(m.buffer, 0, 1);
+  Expect.equals(1, o.length);
+  Expect.equals(0, o.offsetInBytes);
+  Expect.equals(16, o.lengthInBytes);
+  Expect.equals(1.0, o[0].x);
+  Expect.equals(2.0, o[0].y);
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testConstructor();
+    testCastConstructor();
+    testLaneSetter();
+    testNegate();
+    testAdd();
+    testSub();
+    testMul();
+    testDiv();
+    testScale();
+    testAbs();
+    testClamp();
+    testSignMask();
+    testMin();
+    testMax();
+    testSqrt();
+    testTypedList();
+    testTypedListFromList();
+    testTypedListFromTypedList();
+    testTypedListView();
+    testTypedListFullView();
+    testSubList();
+    testSubView();
+  }
+}
diff --git a/tests/lib/typed_data/float64x2_typed_list_test.dart b/tests/lib/typed_data/float64x2_typed_list_test.dart
new file mode 100644
index 0000000..7c43da8
--- /dev/null
+++ b/tests/lib/typed_data/float64x2_typed_list_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+library float64x2_typed_list_test;
+
+import 'dart:typed_data';
+
+void test(Float64x2List l) {
+  var a = l[0];
+  var b = l[1];
+  l[0] = b;
+  l[1] = a;
+}
+
+bool compare(a, b) {
+  return (a.x == b.x) && (a.y == b.y);
+}
+
+main() {
+  var l = new Float64x2List(2);
+  var a = new Float64x2(1.0, 2.0);
+  var b = new Float64x2(3.0, 4.0);
+  l[0] = a;
+  l[1] = b;
+  for (var i = 0; i < 41; i++) {
+    test(l);
+  }
+  if (!compare(l[0], b) || !compare(l[1], a)) {
+    throw 123;
+  }
+}
diff --git a/tests/lib/typed_data/int32x4_arithmetic_test.dart b/tests/lib/typed_data/int32x4_arithmetic_test.dart
new file mode 100644
index 0000000..f9a740e
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_arithmetic_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library uint32x4_arithmetic_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+testAdd() {
+  var m = new Int32x4(0, 0, 0, 0);
+  var n = new Int32x4(-1, -1, -1, -1);
+  var o = m + n;
+  Expect.equals(-1, o.x);
+  Expect.equals(-1, o.y);
+  Expect.equals(-1, o.z);
+  Expect.equals(-1, o.w);
+
+  m = new Int32x4(0, 0, 0, 0);
+  n = new Int32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(-1, o.x);
+  Expect.equals(-1, o.y);
+  Expect.equals(-1, o.z);
+  Expect.equals(-1, o.w);
+
+  n = new Int32x4(1, 1, 1, 1);
+  m = new Int32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(0, o.x);
+  Expect.equals(0, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Int32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  m = new Int32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(-2, o.x);
+  Expect.equals(-2, o.y);
+  Expect.equals(-2, o.z);
+  Expect.equals(-2, o.w);
+
+  n = new Int32x4(1, 0, 0, 0);
+  m = new Int32x4(2, 0, 0, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(0, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Int32x4(1, 3, 0, 0);
+  m = new Int32x4(2, 4, 0, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(7, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Int32x4(1, 3, 5, 0);
+  m = new Int32x4(2, 4, 6, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(7, o.y);
+  Expect.equals(11, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Int32x4(1, 3, 5, 7);
+  m = new Int32x4(-2, -4, -6, -8);
+  o = n + m;
+  Expect.equals(-1, o.x);
+  Expect.equals(-1, o.y);
+  Expect.equals(-1, o.z);
+  Expect.equals(-1, o.w);
+}
+
+testSub() {
+  var m = new Int32x4(0, 0, 0, 0);
+  var n = new Int32x4(1, 1, 1, 1);
+  var o = m - n;
+  Expect.equals(-1, o.x);
+  Expect.equals(-1, o.y);
+  Expect.equals(-1, o.z);
+  Expect.equals(-1, o.w);
+
+  o = n - m;
+  Expect.equals(1, o.x);
+  Expect.equals(1, o.y);
+  Expect.equals(1, o.z);
+  Expect.equals(1, o.w);
+}
+
+const int53 = 0x20000000000000; // 2^53.
+final usingJavaScriptNumbers = (int53 + 1) == int53;
+
+testTruncation() {
+  // Check that various bits from bit 32 and up are masked away.
+  var base = usingJavaScriptNumbers ? 0x1BCCDD00000000 : 0xAABBCCDD00000000;
+  var x1 = new Int32x4(base + 1, 0, 0, 0);
+  Expect.equals(1, x1.x);
+
+  // Check that all even bits up to bit 30 are preserved.
+  var x2 = new Int32x4(base + 0x55555555, 0, 0, 0);
+  Expect.equals(0x55555555, x2.x);
+
+  // Check that the odd bits up to bit 31 are preserved, and that
+  // bit 31 is treated as a sign bit.
+  var x3 = new Int32x4(base + 0xAAAAAAAA, 0, 0, 0);
+  const signExtended = -1431655766; // 0xFFFFFFFFAAAAAAAA or 0x3FFFFFAAAAAAAA.
+  Expect.equals(signExtended, x3.x);
+
+  // Check that all bits from bit 32 and up are masked away.
+  var highBase = 0xFFFFFFFF10000000;
+  var x4 = new Int32x4(highBase, 0, 0, 0);
+  Expect.equals(0x10000000, x4.x);
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testAdd();
+    testSub();
+    testTruncation();
+  }
+}
diff --git a/tests/lib/typed_data/int32x4_list_test.dart b/tests/lib/typed_data/int32x4_list_test.dart
new file mode 100644
index 0000000..1b03ce6
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_list_test.dart
@@ -0,0 +1,216 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library int32x4_list_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+testLoadStore(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is List<Int32x4>);
+  array[0] = new Int32x4(1, 2, 3, 4);
+  Expect.equals(1, array[0].x);
+  Expect.equals(2, array[0].y);
+  Expect.equals(3, array[0].z);
+  Expect.equals(4, array[0].w);
+  array[1] = array[0];
+  array[0] = array[0].withX(9);
+  Expect.equals(9, array[0].x);
+  Expect.equals(2, array[0].y);
+  Expect.equals(3, array[0].z);
+  Expect.equals(4, array[0].w);
+  Expect.equals(1, array[1].x);
+  Expect.equals(2, array[1].y);
+  Expect.equals(3, array[1].z);
+  Expect.equals(4, array[1].w);
+}
+
+testLoadStoreDeopt(array, index, value) {
+  array[index] = value;
+  Expect.equals(value.x, array[index].x);
+  Expect.equals(value.y, array[index].y);
+  Expect.equals(value.z, array[index].z);
+  Expect.equals(value.w, array[index].w);
+}
+
+testLoadStoreDeoptDriver() {
+  Int32x4List list = new Int32x4List(4);
+  Int32x4 value = new Int32x4(1, 2, 3, 4);
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // Invalid index.
+    testLoadStoreDeopt(list, 5, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // null list.
+    testLoadStoreDeopt(null, 0, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // null value.
+    testLoadStoreDeopt(list, 0, null);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-smi index.
+    testLoadStoreDeopt(list, 3.14159, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-Int32x4 value.
+    testLoadStoreDeopt(list, 0, 4.toDouble());
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+  try {
+    // non-Int32x4List list.
+    testLoadStoreDeopt([new Int32x4(2, 3, 4, 5)], 0, value);
+  } catch (_) {}
+  for (int i = 0; i < 20; i++) {
+    testLoadStoreDeopt(list, 0, value);
+  }
+}
+
+testListZero() {
+  Int32x4List list = new Int32x4List(1);
+  Expect.equals(0, list[0].x);
+  Expect.equals(0, list[0].y);
+  Expect.equals(0, list[0].z);
+  Expect.equals(0, list[0].w);
+}
+
+testView(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is List<Int32x4>);
+  Expect.equals(0, array[0].x);
+  Expect.equals(1, array[0].y);
+  Expect.equals(2, array[0].z);
+  Expect.equals(3, array[0].w);
+  Expect.equals(4, array[1].x);
+  Expect.equals(5, array[1].y);
+  Expect.equals(6, array[1].z);
+  Expect.equals(7, array[1].w);
+}
+
+testSublist(array) {
+  Expect.equals(8, array.length);
+  Expect.isTrue(array is Int32x4List);
+  var a = array.sublist(0, 1);
+  Expect.equals(1, a.length);
+  Expect.equals(0, a[0].x);
+  Expect.equals(1, a[0].y);
+  Expect.equals(2, a[0].z);
+  Expect.equals(3, a[0].w);
+  a = array.sublist(1, 2);
+  Expect.equals(4, a[0].x);
+  Expect.equals(5, a[0].y);
+  Expect.equals(6, a[0].z);
+  Expect.equals(7, a[0].w);
+  a = array.sublist(0);
+  Expect.equals(a.length, array.length);
+  for (int i = 0; i < array.length; i++) {
+    Expect.equals(array[i].x, a[i].x);
+    Expect.equals(array[i].y, a[i].y);
+    Expect.equals(array[i].z, a[i].z);
+    Expect.equals(array[i].w, a[i].w);
+  }
+}
+
+void testSpecialValues(array) {
+  var tests = [
+    [0x8901234567890, 0x34567890],
+    [0x89012A4567890, -1537836912],
+    [0x80000000, -2147483648],
+    [-0x80000000, -2147483648],
+    [0x7fffffff, 2147483647],
+    [-0x7fffffff, -2147483647],
+  ];
+  var int32x4;
+
+  for (var test in tests) {
+    var input = test[0];
+    var expected = test[1];
+
+    int32x4 = new Int32x4(input, 2, 3, 4);
+    array[0] = int32x4;
+    int32x4 = array[0];
+    Expect.equals(expected, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, input, 3, 4);
+    array[0] = int32x4;
+    int32x4 = array[0];
+    Expect.equals(1, int32x4.x);
+    Expect.equals(expected, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, input, 4);
+    array[0] = int32x4;
+    int32x4 = array[0];
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(expected, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, 3, input);
+    array[0] = int32x4;
+    int32x4 = array[0];
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(expected, int32x4.w);
+  }
+}
+
+main() {
+  var list;
+
+  list = new Int32x4List(8);
+  for (int i = 0; i < 20; i++) {
+    testLoadStore(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testSpecialValues(list);
+  }
+
+  Uint32List uint32List = new Uint32List(32);
+  for (int i = 0; i < uint32List.length; i++) {
+    uint32List[i] = i;
+  }
+  list = new Int32x4List.view(uint32List.buffer);
+  for (int i = 0; i < 20; i++) {
+    testView(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testSublist(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testLoadStore(list);
+  }
+  for (int i = 0; i < 20; i++) {
+    testListZero();
+  }
+  for (int i = 0; i < 20; i++) {
+    testSpecialValues(list);
+  }
+  testLoadStoreDeoptDriver();
+}
diff --git a/tests/lib/typed_data/int32x4_shuffle_test.dart b/tests/lib/typed_data/int32x4_shuffle_test.dart
new file mode 100644
index 0000000..6fcad56
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_shuffle_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library uint32x4_shuffle_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+void testShuffle() {
+  var m = new Int32x4(1, 2, 3, 4);
+  var c;
+  c = m.shuffle(Int32x4.wzyx);
+  Expect.equals(4, c.x);
+  Expect.equals(3, c.y);
+  Expect.equals(2, c.z);
+  Expect.equals(1, c.w);
+}
+
+void testShuffleNonConstant(mask) {
+  var m = new Int32x4(1, 2, 3, 4);
+  var c;
+  c = m.shuffle(mask);
+  if (mask == 1) {
+    Expect.equals(2, c.x);
+    Expect.equals(1, c.y);
+    Expect.equals(1, c.z);
+    Expect.equals(1, c.w);
+  } else {
+    Expect.equals(Int32x4.yyyy + 1, mask);
+    Expect.equals(3, c.x);
+    Expect.equals(2, c.y);
+    Expect.equals(2, c.z);
+    Expect.equals(2, c.w);
+  }
+}
+
+void testShuffleMix() {
+  var m = new Int32x4(1, 2, 3, 4);
+  var n = new Int32x4(5, 6, 7, 8);
+  var c = m.shuffleMix(n, Int32x4.xyxy);
+  Expect.equals(1, c.x);
+  Expect.equals(2, c.y);
+  Expect.equals(5, c.z);
+  Expect.equals(6, c.w);
+}
+
+main() {
+  var xxxx = Int32x4.xxxx + 1;
+  var yyyy = Int32x4.yyyy + 1;
+  for (int i = 0; i < 20; i++) {
+    testShuffle();
+    testShuffleNonConstant(xxxx);
+    testShuffleNonConstant(yyyy);
+    testShuffleMix();
+  }
+}
diff --git a/tests/lib/typed_data/int32x4_sign_mask_test.dart b/tests/lib/typed_data/int32x4_sign_mask_test.dart
new file mode 100644
index 0000000..522054d
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_sign_mask_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library int32x4_sign_mask;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testImmediates() {
+  var f = new Int32x4(1, 2, 3, 4);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Int32x4(-1, -2, -3, -4);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+  f = new Int32x4.bool(true, false, false, false);
+  m = f.signMask;
+  Expect.equals(0x1, m);
+  f = new Int32x4.bool(false, true, false, false);
+  m = f.signMask;
+  Expect.equals(0x2, m);
+  f = new Int32x4.bool(false, false, true, false);
+  m = f.signMask;
+  Expect.equals(0x4, m);
+  f = new Int32x4.bool(false, false, false, true);
+  m = f.signMask;
+  Expect.equals(0x8, m);
+}
+
+void testZero() {
+  var f = new Int32x4(0, 0, 0, 0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Int32x4(-0, -0, -0, -0);
+  m = f.signMask;
+  Expect.equals(0x0, m);
+}
+
+void testLogic() {
+  var a = new Int32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000);
+  var b = new Int32x4(0x70000000, 0x70000000, 0x70000000, 0x70000000);
+  var c = new Int32x4(0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000);
+  var m1 = (a & c).signMask;
+  Expect.equals(0xf, m1);
+  var m2 = (a & b).signMask;
+  Expect.equals(0x0, m2);
+  var m3 = (b ^ a).signMask;
+  Expect.equals(0xf, m3);
+  var m4 = (b | c).signMask;
+  Expect.equals(0xf, m4);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testImmediates();
+    testZero();
+    testLogic();
+  }
+}
diff --git a/tests/lib/typed_data/int32x4_static_test.dart b/tests/lib/typed_data/int32x4_static_test.dart
new file mode 100644
index 0000000..44ce01c
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_static_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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 int32x4_static_test;
+
+import 'dart:typed_data';
+
+main() {
+  var str = "foo";
+  new Int32x4(str, 2, 3, 4); //# 01: compile-time error
+
+  var d = 0.5;
+  new Int32x4(d, 2, 3, 4); //# 02: compile-time error
+}
diff --git a/tests/lib/typed_data/int32x4_test.dart b/tests/lib/typed_data/int32x4_test.dart
new file mode 100644
index 0000000..e9b2f4a
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--no-intrinsify
+
+// Requirements=nnbd-strong
+
+library int32x4_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testBadArguments() {
+  // Check that the actual argument type error is detected and a dynamic
+  // error is raised. This is not trivially covered by similar dynamic type
+  // checks on actual parameters of user-written functions because `Int32x4`
+  // is a built-in type.
+
+  dynamic dynamicNull = null;
+  Expect.throwsTypeError(() => new Int32x4(dynamicNull, 2, 3, 4));
+  Expect.throwsTypeError(() => new Int32x4(1, dynamicNull, 3, 4));
+  Expect.throwsTypeError(() => new Int32x4(1, 2, dynamicNull, 4));
+  Expect.throwsTypeError(() => new Int32x4(1, 2, 3, dynamicNull));
+
+  bool isTypeError(e) => e is TypeError;
+
+  // Use a local variable typed as dynamic to avoid static warnings.
+  dynamic str = "foo";
+  Expect.throws(() => new Int32x4(str, 2, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, str, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, str, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, 3, str), isTypeError);
+  // Use a local variable typed as dynamic to avoid static warnings.
+  dynamic d = 0.5;
+  Expect.throws(() => new Int32x4(d, 2, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, d, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, d, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, 3, d), isTypeError);
+}
+
+void testBigArguments() {
+  var tests = [
+    [0x8901234567890, 0x34567890],
+    [0x89012A4567890, -1537836912],
+    [0x80000000, -2147483648],
+    [-0x80000000, -2147483648],
+    [0x7fffffff, 2147483647],
+    [-0x7fffffff, -2147483647],
+  ];
+  var int32x4;
+
+  for (var test in tests) {
+    var input = test[0];
+    var expected = test[1];
+
+    int32x4 = new Int32x4(input, 2, 3, 4);
+    Expect.equals(expected, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, input, 3, 4);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(expected, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, input, 4);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(expected, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, 3, input);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(expected, int32x4.w);
+  }
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testBigArguments();
+    testBadArguments();
+  }
+}
diff --git a/tests/lib/typed_data/int32x4_weak_test.dart b/tests/lib/typed_data/int32x4_weak_test.dart
new file mode 100644
index 0000000..1513498
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_weak_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--no-intrinsify
+
+// Requirements=nnbd-weak
+
+library int32x4_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testBadArguments() {
+  // This test runs in weak checking mode, so `e as int` will complete
+  // normally when `e` evaluates to the null object. This means that we do
+  // not get the `TypeError` that we would have in strong checking mode, but
+  // we happen to get an `ArgumentError` from the body of the constructor.
+
+  dynamic dynamicNull = null;
+  Expect.throwsArgumentError(() => new Int32x4(dynamicNull, 2, 3, 4));
+  Expect.throwsArgumentError(() => new Int32x4(1, dynamicNull, 3, 4));
+  Expect.throwsArgumentError(() => new Int32x4(1, 2, dynamicNull, 4));
+  Expect.throwsArgumentError(() => new Int32x4(1, 2, 3, dynamicNull));
+
+  bool isTypeError(e) => e is TypeError;
+
+  // Use a local variable typed as dynamic to avoid static warnings.
+  dynamic str = "foo";
+  Expect.throws(() => new Int32x4(str, 2, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, str, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, str, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, 3, str), isTypeError);
+  // Use a local variable typed as dynamic to avoid static warnings.
+  dynamic d = 0.5;
+  Expect.throws(() => new Int32x4(d, 2, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, d, 3, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, d, 4), isTypeError);
+  Expect.throws(() => new Int32x4(1, 2, 3, d), isTypeError);
+}
+
+void testBigArguments() {
+  var tests = [
+    [0x8901234567890, 0x34567890],
+    [0x89012A4567890, -1537836912],
+    [0x80000000, -2147483648],
+    [-0x80000000, -2147483648],
+    [0x7fffffff, 2147483647],
+    [-0x7fffffff, -2147483647],
+  ];
+  var int32x4;
+
+  for (var test in tests) {
+    var input = test[0];
+    var expected = test[1];
+
+    int32x4 = new Int32x4(input, 2, 3, 4);
+    Expect.equals(expected, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, input, 3, 4);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(expected, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, input, 4);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(expected, int32x4.z);
+    Expect.equals(4, int32x4.w);
+
+    int32x4 = new Int32x4(1, 2, 3, input);
+    Expect.equals(1, int32x4.x);
+    Expect.equals(2, int32x4.y);
+    Expect.equals(3, int32x4.z);
+    Expect.equals(expected, int32x4.w);
+  }
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testBigArguments();
+    testBadArguments();
+  }
+}
diff --git a/tests/lib/typed_data/int64_list_load_store_test.dart b/tests/lib/typed_data/int64_list_load_store_test.dart
new file mode 100644
index 0000000..632d4c4
--- /dev/null
+++ b/tests/lib/typed_data/int64_list_load_store_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Test that the compiler's load elimination phase sees interfering writes to
+// the array's buffer.
+
+// This test is not compatible with dart2js: Int64List is not supported.
+
+import "dart:typed_data";
+import 'package:expect/expect.dart';
+
+void testStoreLoad(l, z) {
+  l[0] = 9223372036854775807;
+  l[1] = 9223372036854775806;
+  l[2] = l[0];
+  l[3] = z;
+  Expect.equals(l[0], 9223372036854775807);
+  Expect.equals(l[1], 9223372036854775806);
+  Expect.isTrue(l[1] < l[0]);
+  Expect.equals(l[2], l[0]);
+  Expect.equals(l[3], z);
+}
+
+main() {
+  var l = new Int64List(4);
+  var zGood = 9223372036854775807;
+  var zBad = false;
+  for (var i = 0; i < 40; i++) {
+    testStoreLoad(l, zGood);
+  }
+  // Deopt.
+  try {
+    testStoreLoad(l, zBad);
+  } catch (_) {}
+  for (var i = 0; i < 40; i++) {
+    testStoreLoad(l, zGood);
+  }
+}
diff --git a/tests/lib/typed_data/native_interceptor_no_own_method_to_intercept_test.dart b/tests/lib/typed_data/native_interceptor_no_own_method_to_intercept_test.dart
new file mode 100644
index 0000000..6828d6a
--- /dev/null
+++ b/tests/lib/typed_data/native_interceptor_no_own_method_to_intercept_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+@pragma('dart2js:noInline')
+use(s) => s;
+
+main() {
+  // In dart2js ByteData should have an interceptor so that it doesn't end up
+  // as an unknown JS object.
+  // This test is just to make sure that dart2js doesn't crash.
+  use(new ByteData(1).toString());
+}
diff --git a/tests/lib/typed_data/setRange_1_test.dart b/tests/lib/typed_data/setRange_1_test.dart
new file mode 100644
index 0000000..f39515c
--- /dev/null
+++ b/tests/lib/typed_data/setRange_1_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+import 'setRange_lib.dart';
+
+sameTypeTest() {
+  checkSameSize(makeInt16List, makeInt16View, makeInt16View);
+  checkSameSize(makeUint16List, makeUint16View, makeUint16View);
+}
+
+main() {
+  sameTypeTest();
+}
diff --git a/tests/lib/typed_data/setRange_2_test.dart b/tests/lib/typed_data/setRange_2_test.dart
new file mode 100644
index 0000000..efd85f5
--- /dev/null
+++ b/tests/lib/typed_data/setRange_2_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+import 'setRange_lib.dart';
+
+sameElementSizeTest() {
+  // Views of elements with the same size but different 'types'.
+  checkSameSize(makeInt16List, makeInt16View, makeUint16View);
+  checkSameSize(makeInt16List, makeUint16View, makeInt16View);
+}
+
+main() {
+  sameElementSizeTest();
+}
diff --git a/tests/lib/typed_data/setRange_3_test.dart b/tests/lib/typed_data/setRange_3_test.dart
new file mode 100644
index 0000000..7ac0e01
--- /dev/null
+++ b/tests/lib/typed_data/setRange_3_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+import 'setRange_lib.dart';
+
+expandContractTest() {
+  // Copying between views that have different element sizes can't be done with
+  // a single scan-up or scan-down.
+  //
+  // Typed lists a1 and a2 share a buffer as follows:
+  //
+  // a1:  aaaabbbbccccddddeeeeffffgggghhhh
+  // a2:              abcdefgh
+
+  var a1 = new Int32List(8);
+  var buffer = a1.buffer;
+  var a2 = new Int8List.view(buffer, 12, 8);
+
+  initialize(a2);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a2');
+  a1.setRange(0, 8, a2);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a1');
+
+  initialize(a1);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a1');
+  a2.setRange(0, 8, a1);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a2');
+}
+
+main() {
+  expandContractTest();
+}
diff --git a/tests/lib/typed_data/setRange_4_test.dart b/tests/lib/typed_data/setRange_4_test.dart
new file mode 100644
index 0000000..5ddb266
--- /dev/null
+++ b/tests/lib/typed_data/setRange_4_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+import 'setRange_lib.dart';
+
+clampingTest() {
+  var a1 = new Int8List(8);
+  var a2 = new Uint8ClampedList.view(a1.buffer);
+  initialize(a1);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a1');
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8]', '$a2');
+  a1[0] = -1;
+  a2.setRange(0, 2, a1);
+  Expect.equals('[0, 2, 3, 4, 5, 6, 7, 8]', '$a2');
+}
+
+main() {
+  clampingTest();
+}
diff --git a/tests/lib/typed_data/setRange_5_test.dart b/tests/lib/typed_data/setRange_5_test.dart
new file mode 100644
index 0000000..fb86cb0
--- /dev/null
+++ b/tests/lib/typed_data/setRange_5_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+import 'setRange_lib.dart';
+
+overlapTest() {
+  // buffer:  xxxxxxxxyyyyyyyyzzzzzzzz  // 3 * float32
+  // a0:       1 2 3 4 5 6 7 8 9101112  // 12 bytes
+  // a1:         a b c d e              //  5 bytes
+  // a2:           p q r s t            //  5 bytes
+  var buffer = new Float32List(3).buffer;
+  var a0 = new Int8List.view(buffer);
+  var a1 = new Int8List.view(buffer, 1, 5);
+  var a2 = new Int8List.view(buffer, 2, 5);
+  initialize(a0);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]', '$a0');
+  Expect.equals('[2, 3, 4, 5, 6]', '$a1');
+  Expect.equals('[3, 4, 5, 6, 7]', '$a2');
+  a1.setRange(0, 5, a2);
+  Expect.equals('[1, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12]', '$a0');
+
+  initialize(a0);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]', '$a0');
+  Expect.equals('[2, 3, 4, 5, 6]', '$a1');
+  Expect.equals('[3, 4, 5, 6, 7]', '$a2');
+  a2.setRange(0, 5, a1);
+  Expect.equals('[1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12]', '$a0');
+}
+
+main() {
+  overlapTest();
+}
diff --git a/tests/lib/typed_data/setRange_lib.dart b/tests/lib/typed_data/setRange_lib.dart
new file mode 100644
index 0000000..f9b1dfb
--- /dev/null
+++ b/tests/lib/typed_data/setRange_lib.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library setRange_lib;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+initialize(a) {
+  for (int i = 0; i < a.length; i++) {
+    a[i] = i + 1;
+  }
+}
+
+makeInt16View(buffer, byteOffset, length) =>
+    new Int16List.view(buffer, byteOffset, length);
+
+makeUint16View(buffer, byteOffset, length) =>
+    new Uint16List.view(buffer, byteOffset, length);
+
+makeInt16List(length) => new Int16List(length);
+makeUint16List(length) => new Uint16List(length);
+
+checkSameSize(constructor0, constructor1, constructor2) {
+  // Typed lists a1 and a2 share a buffer as follows (bytes):
+  //
+  //  a0:  aabbccddeeffgghhii
+  //  a1:  aabbccddeeffgg
+  //  a2:      aabbccddeeffgg
+
+  var a0 = constructor0(9);
+  var buffer = a0.buffer;
+  var a1 = constructor1(buffer, 0, 7);
+  var a2 = constructor2(buffer, 2 * a0.elementSizeInBytes, 7);
+
+  initialize(a0);
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7, 8, 9]', '$a0');
+  Expect.equals('[1, 2, 3, 4, 5, 6, 7]', '$a1');
+  Expect.equals('[3, 4, 5, 6, 7, 8, 9]', '$a2');
+
+  initialize(a0);
+  a1.setRange(0, 7, a2);
+  Expect.equals('[3, 4, 5, 6, 7, 8, 9, 8, 9]', '$a0');
+
+  initialize(a0);
+  a2.setRange(0, 7, a1);
+  Expect.equals('[1, 2, 1, 2, 3, 4, 5, 6, 7]', '$a0');
+
+  initialize(a0);
+  a1.setRange(1, 7, a2);
+  Expect.equals('[1, 3, 4, 5, 6, 7, 8, 8, 9]', '$a0');
+
+  initialize(a0);
+  a2.setRange(1, 7, a1);
+  Expect.equals('[1, 2, 3, 1, 2, 3, 4, 5, 6]', '$a0');
+
+  initialize(a0);
+  a1.setRange(0, 6, a2, 1);
+  Expect.equals('[4, 5, 6, 7, 8, 9, 7, 8, 9]', '$a0');
+
+  initialize(a0);
+  a2.setRange(0, 6, a1, 1);
+  Expect.equals('[1, 2, 2, 3, 4, 5, 6, 7, 9]', '$a0');
+}
diff --git a/tests/lib/typed_data/simd_store_to_load_forward_test.dart b/tests/lib/typed_data/simd_store_to_load_forward_test.dart
new file mode 100644
index 0000000..bb0e0b4
--- /dev/null
+++ b/tests/lib/typed_data/simd_store_to_load_forward_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library simd_store_to_load_forward_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+Float32x4 testLoadStoreForwardingFloat32x4(Float32x4List l, Float32x4 v) {
+  l[1] = v;
+  var r = l[1];
+  return r;
+}
+
+main() {
+  Float32x4List l = new Float32x4List(4);
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  Float32x4 b;
+  int i = 0;
+  do {
+    // do-while ensures `b` is definitely assigned.
+    b = testLoadStoreForwardingFloat32x4(l, a);
+  } while (++i < 20);
+  Expect.equals(a.x, b.x);
+  Expect.equals(a.y, b.y);
+  Expect.equals(a.z, b.z);
+  Expect.equals(a.w, b.w);
+}
diff --git a/tests/lib/typed_data/simd_type_check_removal.dart b/tests/lib/typed_data/simd_type_check_removal.dart
new file mode 100644
index 0000000..816b546
--- /dev/null
+++ b/tests/lib/typed_data/simd_type_check_removal.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library simd_store_to_load_forward_test;
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+bool testFloat32x4TypeCheck(Float32x4 v) {
+  if (v == null) {
+    v = new Float32x4.zero();
+  }
+  var l = v * v;
+  var b = v + l;
+  return b is Float32x4;
+}
+
+main() {
+  Float32x4List l = new Float32x4List(4);
+  Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var b;
+  for (int i = 0; i < 8000; i++) {
+    b = testFloat32x4TypeCheck(null);
+  }
+  Expect.equals(true, b);
+}
diff --git a/tests/lib/typed_data/simd_type_null_params_error_test.dart b/tests/lib/typed_data/simd_type_null_params_error_test.dart
new file mode 100644
index 0000000..ac51f95
--- /dev/null
+++ b/tests/lib/typed_data/simd_type_null_params_error_test.dart
@@ -0,0 +1,359 @@
+// Copyright (c) 2020, 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.
+
+// Requirements=nnbd-strong
+
+// Many other tests will check that static nullability checks are applied to
+// actual arguments of regular function invocations. This test is still not
+// redundant, because it involves a built-in type and methods subject to
+// patching, and patching could introduce bugs in this area.
+
+import 'dart:typed_data';
+
+main() {
+  // Float32x4
+  final float32x4 = Float32x4(0.0, 0.0, 0.0, 0.0);
+
+  float32x4 + null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4 - null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4 * null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4 / null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.lessThan(null);
+  //                 ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.lessThanOrEqual(null);
+  //                        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.greaterThan(null);
+  //                    ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.greaterThanOrEqual(null);
+  //                           ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.equal(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.notEqual(null);
+  //                 ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.scale(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.clamp(null, float32x4);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.clamp(float32x4, null);
+  //                         ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.shuffle(null);
+  //                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.shuffleMix(float32x4, null);
+  //                              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.shuffleMix(null, 0);
+  //                   ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.withX(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.withY(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.withZ(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.withW(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.min(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float32x4.max(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float32x4(null, 0.0, 0.0, 0.0);
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float32x4(0.0, null, 0.0, 0.0);
+  //             ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float32x4(0.0, 0.0, null, 0.0);
+  //                  ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float32x4(0.0, 0.0, 0.0, null);
+  //                       ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Float32x4.splat
+  Float32x4.splat(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Float64x2
+  final float64x2 = Float64x2(0.0, 0.0);
+  float64x2 + null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2 - null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2 * null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2 / null;
+  //          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.scale(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.clamp(null, float64x2);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.clamp(float64x2, null);
+  //                         ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.withX(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.withY(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float64x2(null, 0.0);
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Float64x2(0.0, null);
+  //             ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.min(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  float64x2.max(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Float64x2.splat
+  Float64x2.splat(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Int32x4
+  final int32x4 = Int32x4(0, 0, 0, 0);
+  int32x4 + null;
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4 - null;
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4 ^ null;
+  //           ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4 & null;
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4 | null;
+  //        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.shuffle(null);
+  //              ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.shuffleMix(int32x4, null);
+  //                          ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.shuffleMix(null, 0);
+  //                 ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withX(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withY(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withZ(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withW(null);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withFlagX(null);
+  //                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withFlagY(null);
+  //                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withFlagZ(null);
+  //                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.withFlagW(null);
+  //                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4(null, 0, 0, 0);
+  //      ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4(0, null, 0, 0);
+  //         ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4(0, 0, null, 0);
+  //            ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4(0, 0, 0, null);
+  //               ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.select(null, float32x4);
+  //             ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  int32x4.select(float32x4, null);
+  //                        ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Int32x4.bool
+  Int32x4.bool(null, false, false, false);
+  //           ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4.bool(false, null, false, false);
+  //                  ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4.bool(false, false, null, false);
+  //                         ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  Int32x4.bool(false, false, false, null);
+  //                                ^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
diff --git a/tests/lib/typed_data/simd_type_null_params_test.dart b/tests/lib/typed_data/simd_type_null_params_test.dart
new file mode 100644
index 0000000..536b2be
--- /dev/null
+++ b/tests/lib/typed_data/simd_type_null_params_test.dart
@@ -0,0 +1,124 @@
+// 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.
+
+// Requirements=nnbd-strong
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+bool throwsTypeError(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    return e is TypeError;
+  }
+  return false;
+}
+
+main() {
+  dynamic dynamicNull = null;
+  // Float32x4
+  final float32x4 = Float32x4(0.0, 0.0, 0.0, 0.0);
+  Expect.equals(true, throwsTypeError(() => float32x4 + dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float32x4 - dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float32x4 * dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float32x4 / dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float32x4.lessThan(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.lessThanOrEqual(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.greaterThan(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.greaterThanOrEqual(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.equal(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.notEqual(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.scale(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.clamp(dynamicNull, float32x4)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.clamp(float32x4, dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.shuffle(dynamicNull)));
+  Expect.equals(true,
+      throwsTypeError(() => float32x4.shuffleMix(float32x4, dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float32x4.shuffleMix(dynamicNull, 0)));
+  Expect.equals(true, throwsTypeError(() => float32x4.withX(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.withY(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.withZ(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.withW(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.min(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float32x4.max(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => Float32x4(dynamicNull, 0.0, 0.0, 0.0)));
+  Expect.equals(
+      true, throwsTypeError(() => Float32x4(0.0, dynamicNull, 0.0, 0.0)));
+  Expect.equals(
+      true, throwsTypeError(() => Float32x4(0.0, 0.0, dynamicNull, 0.0)));
+  Expect.equals(
+      true, throwsTypeError(() => Float32x4(0.0, 0.0, 0.0, dynamicNull)));
+
+  // Float32x4.splat
+  Expect.equals(true, throwsTypeError(() => Float32x4.splat(dynamicNull)));
+
+  // Float64x2
+  final float64x2 = Float64x2(0.0, 0.0);
+  Expect.equals(true, throwsTypeError(() => float64x2 + dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float64x2 - dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float64x2 * dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float64x2 / dynamicNull));
+  Expect.equals(true, throwsTypeError(() => float64x2.scale(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => float64x2.clamp(dynamicNull, float64x2)));
+  Expect.equals(
+      true, throwsTypeError(() => float64x2.clamp(float64x2, dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float64x2.withX(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float64x2.withY(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => Float64x2(dynamicNull, 0.0)));
+  Expect.equals(true, throwsTypeError(() => Float64x2(0.0, dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float64x2.min(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => float64x2.max(dynamicNull)));
+
+  // Float64x2.splat
+  Expect.equals(true, throwsTypeError(() => Float64x2.splat(dynamicNull)));
+
+  // Int32x4
+  final int32x4 = Int32x4(0, 0, 0, 0);
+  Expect.equals(true, throwsTypeError(() => int32x4 + dynamicNull));
+  Expect.equals(true, throwsTypeError(() => int32x4 - dynamicNull));
+  Expect.equals(true, throwsTypeError(() => int32x4 ^ dynamicNull));
+  Expect.equals(true, throwsTypeError(() => int32x4 & dynamicNull));
+  Expect.equals(true, throwsTypeError(() => int32x4 | dynamicNull));
+  Expect.equals(true, throwsTypeError(() => int32x4.shuffle(dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => int32x4.shuffleMix(int32x4, dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => int32x4.shuffleMix(dynamicNull, 0)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withX(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withY(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withZ(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withW(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withFlagX(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withFlagY(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withFlagZ(dynamicNull)));
+  Expect.equals(true, throwsTypeError(() => int32x4.withFlagW(dynamicNull)));
+
+  Expect.equals(true, throwsTypeError(() => Int32x4(dynamicNull, 0, 0, 0)));
+  Expect.equals(true, throwsTypeError(() => Int32x4(0, dynamicNull, 0, 0)));
+  Expect.equals(true, throwsTypeError(() => Int32x4(0, 0, dynamicNull, 0)));
+  Expect.equals(true, throwsTypeError(() => Int32x4(0, 0, 0, dynamicNull)));
+  Expect.equals(
+      true, throwsTypeError(() => int32x4.select(dynamicNull, float32x4)));
+  Expect.equals(
+      true, throwsTypeError(() => int32x4.select(float32x4, dynamicNull)));
+
+  // Int32x4.bool
+  Expect.equals(true,
+      throwsTypeError(() => Int32x4.bool(dynamicNull, false, false, false)));
+  Expect.equals(true,
+      throwsTypeError(() => Int32x4.bool(false, dynamicNull, false, false)));
+  Expect.equals(true,
+      throwsTypeError(() => Int32x4.bool(false, false, dynamicNull, false)));
+  Expect.equals(true,
+      throwsTypeError(() => Int32x4.bool(false, false, false, dynamicNull)));
+}
diff --git a/tests/lib/typed_data/simd_type_null_params_weak_test.dart b/tests/lib/typed_data/simd_type_null_params_weak_test.dart
new file mode 100644
index 0000000..a3770ed
--- /dev/null
+++ b/tests/lib/typed_data/simd_type_null_params_weak_test.dart
@@ -0,0 +1,127 @@
+// 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.
+
+// Requirements=nnbd-weak
+
+import 'dart:typed_data';
+import "package:expect/expect.dart";
+
+bool throwsSomeError(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    return e is TypeError ||
+        e is NoSuchMethodError ||
+        e is ArgumentError ||
+        e is AssertionError;
+  }
+  return false;
+}
+
+main() {
+  dynamic dynamicNull = null;
+  // Float32x4
+  final float32x4 = Float32x4(0.0, 0.0, 0.0, 0.0);
+  Expect.equals(true, throwsSomeError(() => float32x4 + dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float32x4 - dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float32x4 * dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float32x4 / dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float32x4.lessThan(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.lessThanOrEqual(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.greaterThan(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.greaterThanOrEqual(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.equal(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.notEqual(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.scale(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.clamp(dynamicNull, float32x4)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.clamp(float32x4, dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.shuffle(dynamicNull)));
+  Expect.equals(true,
+      throwsSomeError(() => float32x4.shuffleMix(float32x4, dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float32x4.shuffleMix(dynamicNull, 0)));
+  Expect.equals(true, throwsSomeError(() => float32x4.withX(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.withY(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.withZ(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.withW(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.min(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float32x4.max(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => Float32x4(dynamicNull, 0.0, 0.0, 0.0)));
+  Expect.equals(
+      true, throwsSomeError(() => Float32x4(0.0, dynamicNull, 0.0, 0.0)));
+  Expect.equals(
+      true, throwsSomeError(() => Float32x4(0.0, 0.0, dynamicNull, 0.0)));
+  Expect.equals(
+      true, throwsSomeError(() => Float32x4(0.0, 0.0, 0.0, dynamicNull)));
+
+  // Float32x4.splat
+  Expect.equals(true, throwsSomeError(() => Float32x4.splat(dynamicNull)));
+
+  // Float64x2
+  final float64x2 = Float64x2(0.0, 0.0);
+  Expect.equals(true, throwsSomeError(() => float64x2 + dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float64x2 - dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float64x2 * dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float64x2 / dynamicNull));
+  Expect.equals(true, throwsSomeError(() => float64x2.scale(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => float64x2.clamp(dynamicNull, float64x2)));
+  Expect.equals(
+      true, throwsSomeError(() => float64x2.clamp(float64x2, dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float64x2.withX(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float64x2.withY(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => Float64x2(dynamicNull, 0.0)));
+  Expect.equals(true, throwsSomeError(() => Float64x2(0.0, dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float64x2.min(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => float64x2.max(dynamicNull)));
+
+  // Float64x2.splat
+  Expect.equals(true, throwsSomeError(() => Float64x2.splat(dynamicNull)));
+
+  // Int32x4
+  final int32x4 = Int32x4(0, 0, 0, 0);
+  Expect.equals(true, throwsSomeError(() => int32x4 + dynamicNull));
+  Expect.equals(true, throwsSomeError(() => int32x4 - dynamicNull));
+  Expect.equals(true, throwsSomeError(() => int32x4 ^ dynamicNull));
+  Expect.equals(true, throwsSomeError(() => int32x4 & dynamicNull));
+  Expect.equals(true, throwsSomeError(() => int32x4 | dynamicNull));
+  Expect.equals(true, throwsSomeError(() => int32x4.shuffle(dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => int32x4.shuffleMix(int32x4, dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => int32x4.shuffleMix(dynamicNull, 0)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withX(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withY(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withZ(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withW(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withFlagX(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withFlagY(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withFlagZ(dynamicNull)));
+  Expect.equals(true, throwsSomeError(() => int32x4.withFlagW(dynamicNull)));
+
+  Expect.equals(true, throwsSomeError(() => Int32x4(dynamicNull, 0, 0, 0)));
+  Expect.equals(true, throwsSomeError(() => Int32x4(0, dynamicNull, 0, 0)));
+  Expect.equals(true, throwsSomeError(() => Int32x4(0, 0, dynamicNull, 0)));
+  Expect.equals(true, throwsSomeError(() => Int32x4(0, 0, 0, dynamicNull)));
+  Expect.equals(
+      true, throwsSomeError(() => int32x4.select(dynamicNull, float32x4)));
+  Expect.equals(
+      true, throwsSomeError(() => int32x4.select(float32x4, dynamicNull)));
+
+  // Int32x4.bool
+  Expect.equals(true,
+      throwsSomeError(() => Int32x4.bool(dynamicNull, false, false, false)));
+  Expect.equals(true,
+      throwsSomeError(() => Int32x4.bool(false, dynamicNull, false, false)));
+  Expect.equals(true,
+      throwsSomeError(() => Int32x4.bool(false, false, dynamicNull, false)));
+  Expect.equals(true,
+      throwsSomeError(() => Int32x4.bool(false, false, false, dynamicNull)));
+}
diff --git a/tests/lib/typed_data/typed_data_from_list_test.dart b/tests/lib/typed_data/typed_data_from_list_test.dart
new file mode 100644
index 0000000..9548c73
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_from_list_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:typed_data';
+
+main() {
+  var list = new UnmodifiableListView([1, 2]);
+  var typed = new Uint8List.fromList(list);
+  if (typed[0] != 1 || typed[1] != 2 || typed.length != 2) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/lib/typed_data/typed_data_hierarchy_int64_test.dart b/tests/lib/typed_data/typed_data_hierarchy_int64_test.dart
new file mode 100644
index 0000000..19142ff
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_hierarchy_int64_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library typed_data_hierarchy_int64_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+var inscrutable = null;
+
+void implementsTypedData() {
+  Expect.isTrue(inscrutable(new Int64List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Uint64List(1)) is TypedData);
+}
+
+void implementsList() {
+  Expect.isTrue(inscrutable(new Int64List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Uint64List(1)) is List<int>);
+}
+
+main() {
+  inscrutable = (x) => x;
+  implementsTypedData();
+  implementsList();
+}
diff --git a/tests/lib/typed_data/typed_data_hierarchy_test.dart b/tests/lib/typed_data/typed_data_hierarchy_test.dart
new file mode 100644
index 0000000..cdcbec8
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_hierarchy_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Library tag to be able to run in html test framework.
+library typed_data_hierarchy_test;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+var inscrutable = null;
+
+void testClampedList() {
+  // Force lookup of Uint8List first.
+  Expect.isTrue(inscrutable(new Uint8List(1)) is Uint8List);
+
+  Expect.isFalse(
+      new Uint8ClampedList(1) is Uint8List,
+      'Uint8ClampedList should not be a subtype of Uint8List '
+      'in optimizable test');
+  Expect.isFalse(inscrutable(new Uint8ClampedList(1)) is Uint8List,
+      'Uint8ClampedList should not be a subtype of Uint8List in dynamic test');
+}
+
+void implementsTypedData() {
+  Expect.isTrue(inscrutable(new ByteData(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Float32List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Float32x4List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Float64List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Int8List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Int16List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Int32List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Uint8List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Uint8ClampedList(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Uint16List(1)) is TypedData);
+  Expect.isTrue(inscrutable(new Uint32List(1)) is TypedData);
+}
+
+void implementsList() {
+  Expect.isTrue(inscrutable(new Float32List(1)) is List<double>);
+  Expect.isTrue(inscrutable(new Float32x4List(1)) is List<Float32x4>);
+  Expect.isTrue(inscrutable(new Float64List(1)) is List<double>);
+  Expect.isTrue(inscrutable(new Int8List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Int16List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Int32List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Uint8List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Uint8ClampedList(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Uint16List(1)) is List<int>);
+  Expect.isTrue(inscrutable(new Uint32List(1)) is List<int>);
+}
+
+main() {
+  inscrutable = (x) => x;
+
+  // Note: this test must come first to control order of lookup on Uint8List and
+  // Uint8ClampedList.
+  testClampedList();
+
+  implementsTypedData();
+  implementsList();
+}
diff --git a/tests/lib/typed_data/typed_data_list_test.dart b/tests/lib/typed_data/typed_data_list_test.dart
new file mode 100644
index 0000000..890f274
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_list_test.dart
@@ -0,0 +1,193 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+confuse(x) => x;
+
+void testListFunctions<T extends num>(
+    List<T> list, first, last, T toElementType(dynamic x)) {
+  assert(list.length > 0);
+
+  var reversed = list.reversed;
+  Expect.listEquals(list, reversed.toList().reversed.toList());
+  int index = list.length - 1;
+  for (var x in reversed) {
+    Expect.equals(list[index], x);
+    index--;
+  }
+
+  var zero = toElementType(0);
+  var one = toElementType(1);
+  var two = toElementType(2);
+  // Typed lists are fixed length.
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(zero));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => true));
+
+  var map = list.asMap();
+  Expect.equals(list.length, map.length);
+  Expect.isTrue(map is Map);
+  Expect.listEquals(list, map.values.toList());
+  for (int i = 0; i < list.length; i++) {
+    Expect.equals(list[i], map[i]);
+  }
+
+  Expect.listEquals(list, list.getRange(0, list.length).toList());
+  var subRange = list.getRange(1, list.length - 1).toList();
+  Expect.equals(list.length - 2, subRange.length);
+  index = 1;
+  for (var x in subRange) {
+    Expect.equals(list[index], x);
+    index++;
+  }
+
+  Expect.equals(0, list.lastIndexOf(first));
+  Expect.equals(list.length - 1, list.lastIndexOf(last));
+  if (list is List<int>) {
+    Expect.equals(-1, list.lastIndexOf(-1 as T));
+  } else {
+    Expect.equals(-1, list.lastIndexOf(-1.0 as T));
+  }
+
+  var copy = list.toList();
+  list.fillRange(1, list.length - 1, toElementType(0));
+  Expect.equals(copy.first, list.first);
+  Expect.equals(copy.last, list.last);
+  for (int i = 1; i < list.length - 1; i++) {
+    Expect.equals(0, list[i]);
+  }
+
+  list.setAll(
+      1, list.getRange(1, list.length - 1).map((x) => toElementType(2)));
+  Expect.equals(copy.first, list.first);
+  Expect.equals(copy.last, list.last);
+  for (int i = 1; i < list.length - 1; i++) {
+    Expect.equals(2, list[i]);
+  }
+
+  list.setRange(1, list.length - 1,
+      new Iterable.generate(list.length - 2, (x) => toElementType(x + 5)));
+  Expect.equals(first, list.first);
+  Expect.equals(last, list.last);
+  for (int i = 1; i < list.length - 1; i++) {
+    Expect.equals(4 + i, list[i]);
+  }
+  list.setRange(1, list.length - 1,
+      new Iterable.generate(list.length - 1, (x) => toElementType(x + 5)), 1);
+  Expect.equals(first, list.first);
+  Expect.equals(last, list.last);
+  for (int i = 1; i < list.length - 1; i++) {
+    Expect.equals(5 + i, list[i]);
+  }
+
+  Expect.throwsStateError(() => list.setRange(1, list.length - 1, []));
+
+  for (int i = 0; i < list.length; i++) {
+    list[list.length - 1 - i] = toElementType(i);
+  }
+  list.sort();
+  for (int i = 0; i < list.length; i++) {
+    Expect.equals(i, list[i]);
+  }
+
+  Expect.listEquals(list.getRange(1, list.length - 1).toList(),
+      list.sublist(1, list.length - 1));
+  Expect.listEquals(list.getRange(1, list.length).toList(), list.sublist(1));
+  Expect.listEquals(list, list.sublist(0));
+
+  Expect.listEquals([], list.sublist(0, 0));
+  Expect.listEquals([], list.sublist(list.length));
+  Expect.listEquals([], list.sublist(list.length, list.length));
+
+  Expect.throwsRangeError(() => list.sublist(list.length + 1));
+  Expect.throwsRangeError(() => list.sublist(0, list.length + 1));
+  Expect.throwsRangeError(() => list.sublist(1, 0));
+}
+
+void emptyChecks<T>(List<T> list, T toElementType(dynamic c)) {
+  assert(list.length == 0);
+
+  Expect.isTrue(list.isEmpty);
+
+  var reversed = list.reversed;
+  Expect.listEquals(list, reversed.toList().reversed.toList());
+
+  var zero = toElementType(0);
+  var one = toElementType(1);
+  var two = toElementType(2);
+  // Typed lists are fixed length. Even when they are empty.
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(zero));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => true));
+
+  var map = list.asMap();
+  Expect.equals(list.length, map.length);
+  Expect.isTrue(map is Map);
+  Expect.listEquals(list, map.values.toList());
+  for (int i = 0; i < list.length; i++) {
+    Expect.equals(list[i], map[i]);
+  }
+
+  Expect.listEquals(list, list.getRange(0, list.length).toList());
+
+  var copy = list.toList();
+  // Make sure we are allowed to call range-functions if they are 0..0.
+  list.fillRange(0, 0);
+  Expect.listEquals([], list.getRange(0, 0).toList());
+
+  final minusOne = toElementType(-1);
+  Expect.equals(-1, list.lastIndexOf(minusOne));
+  list.setRange(0, 0, [one, two]);
+
+  list.sort();
+
+  Expect.listEquals([], list.sublist(0, 0));
+}
+
+main() {
+  double toDouble(x) => x.toDouble();
+  int toInt(x) => x.toInt();
+
+  testListFunctions(
+      new Float32List.fromList([1.5, 6.3, 9.5]), 1.5, 9.5, toDouble);
+  testListFunctions(
+      new Float64List.fromList([1.5, 6.3, 9.5]), 1.5, 9.5, toDouble);
+  testListFunctions(new Int8List.fromList([3, 5, 9]), 3, 9, toInt);
+  testListFunctions(new Int16List.fromList([3, 5, 9]), 3, 9, toInt);
+  testListFunctions(new Int32List.fromList([3, 5, 9]), 3, 9, toInt);
+  testListFunctions(new Uint8List.fromList([3, 5, 9]), 3, 9, toInt);
+  testListFunctions(new Uint16List.fromList([3, 5, 9]), 3, 9, toInt);
+  testListFunctions(new Uint32List.fromList([3, 5, 9]), 3, 9, toInt);
+
+  emptyChecks(new Float32List(0), toDouble);
+  emptyChecks(new Float64List(0), toDouble);
+  emptyChecks(new Int8List(0), toInt);
+  emptyChecks(new Int16List(0), toInt);
+  emptyChecks(new Int32List(0), toInt);
+  emptyChecks(new Uint8List(0), toInt);
+  emptyChecks(new Uint16List(0), toInt);
+  emptyChecks(new Uint32List(0), toInt);
+}
diff --git a/tests/lib/typed_data/typed_data_load2_test.dart b/tests/lib/typed_data/typed_data_load2_test.dart
new file mode 100644
index 0000000..3775615
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_load2_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the compiler's load elimination phase sees interfering writes to
+// the array's buffer.
+
+import "dart:typed_data";
+import 'package:expect/expect.dart';
+
+aliasWithByteData1() {
+  var aa = new Int8List(10);
+  var b = new ByteData.view(aa.buffer);
+  for (int i = 0; i < aa.length; i++) aa[i] = 9;
+
+  var x1 = aa[3];
+  b.setInt8(3, 1);
+  var x2 = aa[3];
+
+  Expect.equals(9, x1);
+  Expect.equals(1, x2);
+}
+
+aliasWithByteData2() {
+  var b = new ByteData(10);
+  var aa = new Int8List.view(b.buffer);
+  for (int i = 0; i < aa.length; i++) aa[i] = 9;
+
+  var x1 = aa[3];
+  b.setInt8(3, 1);
+  var x2 = aa[3];
+
+  Expect.equals(9, x1);
+  Expect.equals(1, x2);
+}
+
+alias8x8() {
+  var buffer = new Int8List(10).buffer;
+  var a1 = new Int8List.view(buffer);
+  var a2 = new Int8List.view(buffer, 1);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Different indexes that alias.
+  var x1 = a1[1];
+  a2[0] = 0;
+  var x2 = a1[1];
+  Expect.equals(9, x1);
+  Expect.equals(0, x2);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Same indexes that don't alias.
+  x1 = a1[1];
+  a2[1] = 5;
+  x2 = a1[1];
+  Expect.equals(9, x1);
+  Expect.equals(9, x2);
+}
+
+alias8x16() {
+  var a1 = new Int8List(10);
+  var a2 = new Int16List.view(a1.buffer);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Same indexes that alias.
+  var x1 = a1[0];
+  a2[0] = 0x101;
+  var x2 = a1[0];
+  Expect.equals(9, x1);
+  Expect.equals(1, x2);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Different indexes that alias.
+  x1 = a1[4];
+  a2[2] = 0x505;
+  x2 = a1[4];
+  Expect.equals(9, x1);
+  Expect.equals(5, x2);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Same indexes that don't alias.
+  x1 = a1[3];
+  a2[3] = 0x505;
+  x2 = a1[3];
+  Expect.equals(9, x1);
+  Expect.equals(9, x2);
+
+  for (int i = 0; i < a1.length; i++) a1[i] = 9;
+
+  // Different indexes don't alias.
+  x1 = a1[2];
+  a2[0] = 0x505;
+  x2 = a1[2];
+  Expect.equals(9, x1);
+  Expect.equals(9, x2);
+}
+
+main() {
+  aliasWithByteData1();
+  aliasWithByteData2();
+  alias8x8();
+  alias8x16();
+}
diff --git a/tests/lib/typed_data/typed_data_load_test.dart b/tests/lib/typed_data/typed_data_load_test.dart
new file mode 100644
index 0000000..55a0808
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_load_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the compiler's load elimination phase does not re-use the
+// value that was stored in a typed array.
+
+import "dart:typed_data";
+
+main() {
+  var list = new Int8List(1);
+  list[0] = 300;
+  if (list[0] != 44) {
+    throw 'Test failed';
+  }
+
+  var a = list[0];
+  list[0] = 0;
+  if (list[0] != 0) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/lib/typed_data/typed_data_sublist_type_test.dart b/tests/lib/typed_data/typed_data_sublist_type_test.dart
new file mode 100644
index 0000000..f52ad9f
--- /dev/null
+++ b/tests/lib/typed_data/typed_data_sublist_type_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+// Test that the sublist of a typed_data list is of the same type.
+
+var inscrutable;
+
+class Is<T> {
+  final name;
+  Is(this.name);
+  check(x) => x is T;
+  expect(x, part) {
+    Expect.isTrue(check(x), '($part: ${x.runtimeType}) is $name');
+  }
+
+  expectNot(x, part) {
+    Expect.isFalse(check(x), '($part: ${x.runtimeType}) is! $name');
+  }
+}
+
+void testSublistType(input, positive, all) {
+  var negative = all.where((check) => !positive.contains(check));
+
+  input = inscrutable(input);
+
+  for (var check in positive) check.expect(input, 'input');
+  for (var check in negative) check.expectNot(input, 'input');
+
+  var sub = inscrutable(input.sublist(1));
+
+  for (var check in positive) check.expect(sub, 'sublist');
+  for (var check in negative) check.expectNot(sub, 'sublist');
+
+  var sub2 = inscrutable(input.sublist(10));
+
+  Expect.equals(0, sub2.length);
+  for (var check in positive) check.expect(sub2, 'empty sublist');
+  for (var check in negative) check.expectNot(sub2, 'empty sublist');
+}
+
+void testTypes() {
+  var isFloat32list = new Is<Float32List>('Float32List');
+  var isFloat64list = new Is<Float64List>('Float64List');
+
+  var isInt8List = new Is<Int8List>('Int8List');
+  var isInt16List = new Is<Int16List>('Int16List');
+  var isInt32List = new Is<Int32List>('Int32List');
+
+  var isUint8List = new Is<Uint8List>('Uint8List');
+  var isUint16List = new Is<Uint16List>('Uint16List');
+  var isUint32List = new Is<Uint32List>('Uint32List');
+
+  var isUint8ClampedList = new Is<Uint8ClampedList>('Uint8ClampedList');
+
+  var isIntList = new Is<List<int>>('List<int>');
+  var isDoubleList = new Is<List<double>>('List<double>');
+  var isNumList = new Is<List<num>>('List<num>');
+
+  var allChecks = <Is<List>>[
+    isFloat32list,
+    isFloat64list,
+    isInt8List,
+    isInt16List,
+    isInt32List,
+    isUint8List,
+    isUint16List,
+    isUint32List,
+    isUint8ClampedList
+  ];
+
+  testInt(list, check) {
+    testSublistType(list, <Is<List>>[check, isIntList, isNumList], allChecks);
+  }
+
+  testDouble(list, check) {
+    testSublistType(
+        list, <Is<List>>[check, isDoubleList, isNumList], allChecks);
+  }
+
+  testDouble(new Float32List(10), isFloat32list);
+  testDouble(new Float64List(10), isFloat64list);
+
+  testInt(new Int8List(10), isInt8List);
+  testInt(new Int16List(10), isInt16List);
+  testInt(new Int32List(10), isInt32List);
+
+  testInt(new Uint8List(10), isUint8List);
+  testInt(new Uint16List(10), isUint16List);
+  testInt(new Uint32List(10), isUint32List);
+
+  testInt(new Uint8ClampedList(10), isUint8ClampedList);
+}
+
+main() {
+  inscrutable = (x) => x;
+  testTypes();
+}
diff --git a/tests/lib/typed_data/typed_list_iterable_test.dart b/tests/lib/typed_data/typed_list_iterable_test.dart
new file mode 100644
index 0000000..844f535
--- /dev/null
+++ b/tests/lib/typed_data/typed_list_iterable_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:expect/expect.dart';
+
+void testIterableFunctions<T extends num>(
+    List<T> list, T first, T last, T zero) {
+  assert(list.length > 0);
+
+  Expect.equals(first, list.first);
+  Expect.equals(last, list.last);
+  Expect.equals(first, list.firstWhere((x) => x == first));
+  Expect.equals(last, list.lastWhere((x) => x == last));
+  if (list.length == 1) {
+    Expect.equals(first, list.single);
+    Expect.equals(first, list.singleWhere((x) => x == last));
+  } else {
+    Expect.throwsStateError(() => list.single);
+    bool isFirst = true;
+    Expect.equals(first, list.singleWhere((x) {
+      if (isFirst) {
+        isFirst = false;
+        return true;
+      }
+      return false;
+    }));
+  }
+  Expect.isFalse(list.isEmpty);
+
+  int i = 0;
+  for (var x in list) {
+    Expect.equals(list[i++], x);
+  }
+  Expect.isTrue(list.any((x) => x == last));
+  Expect.isFalse(list.any((x) => false));
+  Expect.isTrue(list.contains(last));
+  Expect.equals(first, list.elementAt(0));
+  Expect.isTrue(list.every((x) => true));
+  Expect.isFalse(list.every((x) => x != last));
+  Expect.listEquals([], list.expand((x) => []).toList());
+  var expand2 = list.expand((x) => [x, x]);
+  i = 0;
+  for (var x in expand2) {
+    Expect.equals(list[i ~/ 2], x);
+    i++;
+  }
+  Expect.equals(2 * list.length, i);
+  Expect.listEquals(list, list.fold([], (result, x) => result..add(x)));
+  i = 0;
+  list.forEach((x) {
+    Expect.equals(list[i++], x);
+  });
+  Expect.equals(list.toList().join("*"), list.join("*"));
+  Expect.listEquals(list, list.map((x) => x).toList());
+  int mapCount = 0;
+  var mappedList = list.map((x) {
+    mapCount++;
+    return x;
+  });
+  Expect.equals(0, mapCount);
+  Expect.equals(list.length, mappedList.length);
+  Expect.equals(0, mapCount);
+  mappedList.join();
+  Expect.equals(list.length, mapCount);
+
+  Expect.listEquals(list, list.where((x) => true).toList());
+  int whereCount = 0;
+  var whereList = list.where((x) {
+    whereCount++;
+    return true;
+  });
+  Expect.equals(0, whereCount);
+  Expect.equals(list.length, whereList.length);
+  Expect.equals(list.length, whereCount);
+
+  if (list.length > 1) {
+    var reduceResult = zero + 1;
+    Expect.equals(list.length, list.reduce((x, y) => ++reduceResult as T));
+  } else {
+    Expect.equals(first, list.reduce((x, y) {
+      throw "should not be called";
+    }));
+  }
+
+  Expect.isTrue(list.skip(list.length).isEmpty);
+  Expect.listEquals(list, list.skip(0).toList());
+  Expect.isTrue(list.skipWhile((x) => true).isEmpty);
+  Expect.listEquals(list, list.skipWhile((x) => false).toList());
+  Expect.listEquals(list, list.take(list.length).toList());
+  Expect.isTrue(list.take(0).isEmpty);
+  Expect.isTrue(list.takeWhile((x) => false).isEmpty);
+  Expect.listEquals(list, list.takeWhile((x) => true).toList());
+  Expect.listEquals(list, list.toList().toList());
+  var l2 = list.toList();
+  l2.add(first);
+  Expect.equals(first, l2.last);
+  var l3 = list.toList(growable: false);
+  Expect.throwsUnsupportedError(() => l3.add(last));
+}
+
+void emptyChecks<T extends num>(List<T> list, T zero) {
+  assert(list.length == 0);
+
+  Expect.isTrue(list.isEmpty);
+
+  Expect.throwsStateError(() => list.first);
+  Expect.throwsStateError(() => list.last);
+  Expect.throwsStateError(() => list.single);
+  Expect.throwsStateError(() => list.firstWhere((x) => true));
+  Expect.throwsStateError(() => list.lastWhere((x) => true));
+  Expect.throwsStateError(() => list.singleWhere((x) => true));
+
+  Expect.isFalse(list.any((x) => true));
+  Expect.isFalse(list.contains(null));
+  Expect.throws(() => list.elementAt(0), (e) => e is RangeError);
+  Expect.isTrue(list.every((x) => false));
+  Expect.listEquals([], list.expand((x) => []).toList());
+  Expect.listEquals([], list.expand((x) => [x, x]).toList());
+  Expect.listEquals(
+      [],
+      list.expand((x) {
+        throw "should not be reached";
+      }).toList());
+  Expect.listEquals([], list.fold([], (result, x) => result..add(x)));
+  Expect.equals(list.toList().join("*"), list.join("*"));
+  Expect.listEquals(list, list.map((x) => x).toList());
+  int mapCount = 0;
+  var mappedList = list.map((x) {
+    mapCount++;
+    return x;
+  });
+  Expect.equals(0, mapCount);
+  Expect.equals(list.length, mappedList.length);
+  Expect.equals(0, mapCount);
+  mappedList.join();
+  Expect.equals(list.length, mapCount);
+
+  Expect.listEquals(list, list.where((x) => true).toList());
+  int whereCount = 0;
+  var whereList = list.where((x) {
+    whereCount++;
+    return true;
+  });
+  Expect.equals(0, whereCount);
+  Expect.equals(list.length, whereList.length);
+  Expect.equals(list.length, whereCount);
+
+  Expect.throwsStateError(() => list.reduce((x, y) => x));
+
+  Expect.isTrue(list.skip(list.length).isEmpty);
+  Expect.isTrue(list.skip(0).isEmpty);
+  Expect.isTrue(list.skipWhile((x) => true).isEmpty);
+  Expect.isTrue(list.skipWhile((x) => false).isEmpty);
+  Expect.isTrue(list.take(list.length).isEmpty);
+  Expect.isTrue(list.take(0).isEmpty);
+  Expect.isTrue(list.takeWhile((x) => false).isEmpty);
+  Expect.isTrue(list.takeWhile((x) => true).isEmpty);
+  Expect.isTrue(list.toList().isEmpty);
+  var l2 = list.toList();
+  l2.add(zero);
+  Expect.equals(zero, l2.last);
+  var l3 = list.toList(growable: false);
+  Expect.throwsUnsupportedError(() => l3.add(zero));
+}
+
+main() {
+  testIterableFunctions(new Float32List.fromList([1.5, 9.5]), 1.5, 9.5, 0.0);
+  testIterableFunctions(new Float64List.fromList([1.5, 9.5]), 1.5, 9.5, 0.0);
+  testIterableFunctions(new Int8List.fromList([3, 9]), 3, 9, 0);
+  testIterableFunctions(new Int16List.fromList([3, 9]), 3, 9, 0);
+  testIterableFunctions(new Int32List.fromList([3, 9]), 3, 9, 0);
+  testIterableFunctions(new Uint8List.fromList([3, 9]), 3, 9, 0);
+  testIterableFunctions(new Uint16List.fromList([3, 9]), 3, 9, 0);
+  testIterableFunctions(new Uint32List.fromList([3, 9]), 3, 9, 0);
+
+  emptyChecks(new Float32List(0), 0.0);
+  emptyChecks(new Float64List(0), 0.0);
+  emptyChecks(new Int8List(0), 0);
+  emptyChecks(new Int16List(0), 0);
+  emptyChecks(new Int32List(0), 0);
+  emptyChecks(new Uint8List(0), 0);
+  emptyChecks(new Uint16List(0), 0);
+  emptyChecks(new Uint32List(0), 0);
+}
diff --git a/tests/lib/typed_data/unmodifiable_typed_data_test.dart b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
new file mode 100644
index 0000000..70708c5
--- /dev/null
+++ b/tests/lib/typed_data/unmodifiable_typed_data_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+checkReadable(List<int> list) {
+  for (int i = 0; i < intList.length; i++) {
+    Expect.equals(list[i], intList[i]);
+  }
+}
+
+checkUnmodifiable(List<int> list) {
+  var zero = 0;
+  var one = 1;
+  var two = 2;
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(one));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => false));
+  Expect.throwsUnsupportedError(() => list[0] = zero);
+  Expect.throwsUnsupportedError(() => list.setRange(0, 1, [one]));
+  Expect.throwsUnsupportedError(() => list.setAll(0, [one]));
+}
+
+int8ListTest() {
+  Int8List i8l = new Int8List.fromList(intList);
+  UnmodifiableInt8ListView list = new UnmodifiableInt8ListView(i8l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint8ListTest() {
+  Uint8List u8l = new Uint8List.fromList(intList);
+  UnmodifiableUint8ListView list = new UnmodifiableUint8ListView(u8l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int16ListTest() {
+  Int16List i16l = new Int16List.fromList(intList);
+  UnmodifiableInt16ListView list = new UnmodifiableInt16ListView(i16l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint16ListTest() {
+  Uint16List u16l = new Uint16List.fromList(intList);
+  UnmodifiableUint16ListView list = new UnmodifiableUint16ListView(u16l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int32ListTest() {
+  Int32List i32l = new Int32List.fromList(intList);
+  UnmodifiableInt32ListView list = new UnmodifiableInt32ListView(i32l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint32ListTest() {
+  Uint32List u32l = new Uint32List.fromList(intList);
+  UnmodifiableUint32ListView list = new UnmodifiableUint32ListView(u32l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int64ListTest() {
+  Int64List i64l = new Int64List.fromList(intList);
+  UnmodifiableInt64ListView list = new UnmodifiableInt64ListView(i64l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint64ListTest() {
+  Uint64List u64l = new Uint64List.fromList(intList);
+  UnmodifiableUint64ListView list = new UnmodifiableUint64ListView(u64l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+List<double> doubleList = <double>[1.0, 2.0, 3.0, 4.0, 5.0];
+
+checkDoubleReadable(List<double> list) {
+  for (int i = 0; i < doubleList.length; i++) {
+    Expect.equals(list[i], doubleList[i]);
+  }
+}
+
+checkDoubleUnmodifiable(List<double> list) {
+  var zero = 0.0;
+  var one = 1.0;
+  var two = 2.0;
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(one));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => false));
+  Expect.throwsUnsupportedError(() => list[0] = zero);
+  Expect.throwsUnsupportedError(() => list.setRange(0, 1, [one]));
+  Expect.throwsUnsupportedError(() => list.setAll(0, [one]));
+}
+
+float32ListTest() {
+  Float32List f32l = new Float32List.fromList(doubleList);
+  UnmodifiableFloat32ListView list = new UnmodifiableFloat32ListView(f32l);
+  checkDoubleReadable(list);
+  checkDoubleUnmodifiable(list);
+}
+
+float64ListTest() {
+  Float64List f64l = new Float64List.fromList(doubleList);
+  UnmodifiableFloat64ListView list = new UnmodifiableFloat64ListView(f64l);
+  checkDoubleReadable(list);
+  checkDoubleUnmodifiable(list);
+}
+
+byteDataTest() {
+  ByteBuffer buffer = new Uint8List.fromList(intList).buffer;
+  ByteData bd = new ByteData.view(buffer);
+  UnmodifiableByteDataView ubdv = new UnmodifiableByteDataView(bd);
+
+  Expect.throwsUnsupportedError(() => ubdv.setInt8(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint8(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt16(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint16(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt32(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint32(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt64(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint64(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setFloat32(0, 0.0));
+  Expect.throwsUnsupportedError(() => ubdv.setFloat64(0, 0.0));
+}
+
+main() {
+  int8ListTest();
+  uint8ListTest();
+  int16ListTest();
+  uint16ListTest();
+  int32ListTest();
+  uint32ListTest();
+  int64ListTest();
+  uint64ListTest();
+  float32ListTest();
+  float64ListTest();
+  byteDataTest();
+}
diff --git a/tests/lib_2/profiler/metrics_num_test.dart b/tests/lib_2/developer/metrics_num_test.dart
similarity index 100%
rename from tests/lib_2/profiler/metrics_num_test.dart
rename to tests/lib_2/developer/metrics_num_test.dart
diff --git a/tests/lib_2/profiler/metrics_test.dart b/tests/lib_2/developer/metrics_test.dart
similarity index 100%
rename from tests/lib_2/profiler/metrics_test.dart
rename to tests/lib_2/developer/metrics_test.dart
diff --git a/tests/lib_2/profiler/user_tags_test.dart b/tests/lib_2/developer/user_tags_test.dart
similarity index 100%
rename from tests/lib_2/profiler/user_tags_test.dart
rename to tests/lib_2/developer/user_tags_test.dart
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 79d2c38..784ae82 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -5,6 +5,7 @@
 [ $compiler == dart2js ]
 convert/chunked_conversion_utf88_test: Slow
 convert/utf85_test: Slow
+developer/metrics_num_test: Skip # Because of an int / double type test.
 developer/timeline_test: Skip # Not supported
 html/async_test: SkipByDesign
 html/custom/document_register_basic_test: Slow
@@ -22,7 +23,6 @@
 html/xhr_test: Slow
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-profiler/metrics_num_test: Skip # Because of an int / double type test.
 wasm/*: SkipByDesign # dart:wasm not currently supported on web.
 
 [ $compiler != dart2js ]
@@ -95,4 +95,3 @@
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
-
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index b3c2a53..7a07129 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -22,6 +22,7 @@
 convert/json_utf8_chunk_test: Slow
 convert/streamed_conversion_utf8_decode_test: Slow # Issue 29922
 convert/utf85_test: Slow
+developer/metrics_num_test: Skip # Because of an int / double type test.
 html/callback_list_test: Skip # Test requires user interaction to accept permissions.
 html/custom/attribute_changed_callback_test: Skip # Issue 31577
 html/custom/constructor_calls_created_synchronously_test: Skip # Issue 31577
@@ -46,4 +47,3 @@
 html/notification_permission_test: Skip # Issue 32002
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-profiler/metrics_num_test: Skip # Because of an int / double type test.
diff --git a/tests/lib_2/typed_data/typed_data_view_sublist_test.dart b/tests/lib_2/typed_data/typed_data_view_sublist_test.dart
new file mode 100644
index 0000000..bcc96cb
--- /dev/null
+++ b/tests/lib_2/typed_data/typed_data_view_sublist_test.dart
@@ -0,0 +1,209 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+const bool isJS = identical(1, 1.0); // Implies no 64-bit integers.
+
+void main() {
+  testViews();
+  testErrors();
+}
+
+void testViews() {
+  var bytes = Uint8List.fromList([for (int i = 0; i < 256; i++) i]);
+
+  // Non-view classes.
+  var bd = () {
+    var bd = ByteData(256);
+    for (int i = 0; i < 256; i++) bd.setUint8(i, i);
+    return bd;
+  }();
+  var u8 = Uint8List.fromList(bytes);
+  var i8 = Int8List.fromList(bytes);
+  var c8 = Uint8ClampedList.fromList(bytes);
+  var u16 = Uint16List.fromList(Uint16List.view(bytes.buffer));
+  var i16 = Int16List.fromList(Int16List.view(bytes.buffer));
+  var u32 = Uint32List.fromList(Uint32List.view(bytes.buffer));
+  var i32 = Int32List.fromList(Int32List.view(bytes.buffer));
+  var u64 = isJS ? null : Uint64List.fromList(Uint64List.view(bytes.buffer));
+  var i64 = isJS ? null : Int64List.fromList(Int64List.view(bytes.buffer));
+  var f32 = Float32List.fromList(Float32List.view(bytes.buffer));
+  var f64 = Float64List.fromList(Float64List.view(bytes.buffer));
+  var f32x4 = Float32x4List.fromList(Float32x4List.view(bytes.buffer));
+  var i32x4 = Int32x4List.fromList(Int32x4List.view(bytes.buffer));
+  var f64x2 = Float64x2List.fromList(Float64x2List.view(bytes.buffer));
+
+  // View classes. A buffer with the right data in the middle.
+  var doubleBuffer = Uint8List(512)..setRange(128, 384, bytes);
+  var bdv = ByteData.view(doubleBuffer.buffer, 128, 256);
+  var u8v = Uint8List.view(doubleBuffer.buffer, 128, 256);
+  var i8v = Int8List.view(doubleBuffer.buffer, 128, 256);
+  var c8v = Uint8ClampedList.view(doubleBuffer.buffer, 128, 256);
+  var u16v = Uint16List.view(doubleBuffer.buffer, 128, 128);
+  var i16v = Int16List.view(doubleBuffer.buffer, 128, 128);
+  var u32v = Uint32List.view(doubleBuffer.buffer, 128, 64);
+  var i32v = Int32List.view(doubleBuffer.buffer, 128, 64);
+  var u64v = isJS ? null : Uint64List.view(doubleBuffer.buffer, 128, 32);
+  var i64v = isJS ? null : Int64List.view(doubleBuffer.buffer, 128, 32);
+  var f32v = Float32List.view(doubleBuffer.buffer, 128, 64);
+  var f64v = Float64List.view(doubleBuffer.buffer, 128, 32);
+  var f32x4v = Float32x4List.view(doubleBuffer.buffer, 128, 16);
+  var i32x4v = Int32x4List.view(doubleBuffer.buffer, 128, 16);
+  var f64x2v = Float64x2List.view(doubleBuffer.buffer, 128, 16);
+
+  var allTypedData = <TypedData>[
+    bd,
+    u8,
+    i8,
+    c8,
+    u16,
+    i16,
+    u32,
+    i32,
+    if (!isJS) u64,
+    if (!isJS) i64,
+    f32,
+    f64,
+    f32x4,
+    i32x4,
+    f64x2,
+    u8v,
+    i8v,
+    c8v,
+    u16v,
+    i16v,
+    u32v,
+    i32v,
+    if (!isJS) u64v,
+    if (!isJS) i64v,
+    f32v,
+    f64v,
+    f32x4v,
+    i32x4v,
+    f64x2v,
+  ];
+
+  for (var td in allTypedData) {
+    var tdType = td.runtimeType.toString();
+    testSame(TypedData data) {
+      expectBuffer(td.buffer, data.buffer);
+      Expect.equals(td.lengthInBytes, data.lengthInBytes);
+      Expect.equals(td.offsetInBytes, data.offsetInBytes);
+    }
+
+    testSame(ByteData.sublistView(td));
+    testSame(Int8List.sublistView(td));
+    testSame(Uint8List.sublistView(td));
+    testSame(Uint8ClampedList.sublistView(td));
+    testSame(Int16List.sublistView(td));
+    testSame(Uint16List.sublistView(td));
+    testSame(Int32List.sublistView(td));
+    testSame(Uint32List.sublistView(td));
+    if (!isJS) testSame(Int64List.sublistView(td));
+    if (!isJS) testSame(Uint64List.sublistView(td));
+    testSame(Float32List.sublistView(td));
+    testSame(Float64List.sublistView(td));
+    testSame(Float32x4List.sublistView(td));
+    testSame(Int32x4List.sublistView(td));
+    testSame(Float64x2List.sublistView(td));
+
+    var length = td.lengthInBytes ~/ td.elementSizeInBytes;
+    for (int start = 0; start < length; start += 16) {
+      for (int end = start; end < length; end += 16) {
+        void testSlice(TypedData data) {
+          var name = "$tdType -> ${data.runtimeType} $start..$end";
+          expectBuffer(td.buffer, data.buffer, name);
+          int offsetInBytes = td.offsetInBytes + start * td.elementSizeInBytes;
+          int lengthInBytes = (end - start) * td.elementSizeInBytes;
+          Expect.equals(lengthInBytes, data.lengthInBytes, name);
+          Expect.equals(offsetInBytes, data.offsetInBytes, name);
+        }
+
+        testSlice(ByteData.sublistView(td, start, end));
+        testSlice(Int8List.sublistView(td, start, end));
+        testSlice(Uint8List.sublistView(td, start, end));
+        testSlice(Uint8ClampedList.sublistView(td, start, end));
+        testSlice(Int16List.sublistView(td, start, end));
+        testSlice(Uint16List.sublistView(td, start, end));
+        testSlice(Int32List.sublistView(td, start, end));
+        testSlice(Uint32List.sublistView(td, start, end));
+        if (!isJS) testSlice(Int64List.sublistView(td, start, end));
+        if (!isJS) testSlice(Uint64List.sublistView(td, start, end));
+        testSlice(Float32List.sublistView(td, start, end));
+        testSlice(Float64List.sublistView(td, start, end));
+        testSlice(Float32x4List.sublistView(td, start, end));
+        testSlice(Int32x4List.sublistView(td, start, end));
+        testSlice(Float64x2List.sublistView(td, start, end));
+      }
+    }
+  }
+}
+
+void testErrors() {
+  // Alignment must be right for non-byte-sized results.
+  // offsetInBytes offset must be a multiple of the element size.
+  // lengthInBytes must be a multiple of the element size.
+  var bytes = Uint8List.fromList([for (int i = 0; i < 256; i++) i]);
+
+  var oddStartView = Uint8List.view(bytes.buffer, 1, 32);
+  var oddLengthView = Uint8List.view(bytes.buffer, 0, 33);
+
+  void testThrows(void Function() operation) {
+    Expect.throws<ArgumentError>(operation);
+  }
+
+  testThrows(() => Uint16List.sublistView(oddStartView));
+  testThrows(() => Int16List.sublistView(oddStartView));
+  testThrows(() => Uint32List.sublistView(oddStartView));
+  testThrows(() => Int32List.sublistView(oddStartView));
+  if (!isJS) testThrows(() => Uint64List.sublistView(oddStartView));
+  if (!isJS) testThrows(() => Int64List.sublistView(oddStartView));
+  testThrows(() => Float32List.sublistView(oddStartView));
+  testThrows(() => Float64List.sublistView(oddStartView));
+  testThrows(() => Float32x4List.sublistView(oddStartView));
+  testThrows(() => Int32x4List.sublistView(oddStartView));
+  testThrows(() => Float64x2List.sublistView(oddStartView));
+
+  testThrows(() => Uint16List.sublistView(oddLengthView));
+  testThrows(() => Int16List.sublistView(oddLengthView));
+  testThrows(() => Uint32List.sublistView(oddLengthView));
+  testThrows(() => Int32List.sublistView(oddLengthView));
+  if (!isJS) testThrows(() => Uint64List.sublistView(oddLengthView));
+  if (!isJS) testThrows(() => Int64List.sublistView(oddLengthView));
+  testThrows(() => Float32List.sublistView(oddLengthView));
+  testThrows(() => Float64List.sublistView(oddLengthView));
+  testThrows(() => Float32x4List.sublistView(oddLengthView));
+  testThrows(() => Int32x4List.sublistView(oddLengthView));
+  testThrows(() => Float64x2List.sublistView(oddLengthView));
+}
+
+void expectBuffer(ByteBuffer buffer, ByteBuffer dataBuffer, [String name]) {
+  // Buffer objects are not necessarily *identical* even though they
+  // represent the same underlying data. The VM allocates buffer objects
+  // lazily for inline typed data objects.
+  if (identical(buffer, dataBuffer)) return;
+  if (buffer.lengthInBytes != dataBuffer.lengthInBytes) {
+    Expect.fail("Different buffers${name == null ? "" : ": $name"}");
+  }
+  // Cannot distinguish empty buffers.
+  if (buffer.lengthInBytes == 0) return;
+  // Contains the same value now.
+  var l1 = Uint8List.view(buffer);
+  var l2 = Uint8List.view(dataBuffer);
+  var byte1 = l1[0];
+  var byte2 = l2[0];
+  if (byte1 != byte2) {
+    Expect.fail("Different buffers${name == null ? "" : ": $name"}");
+  }
+  // Byte written to one buffer can be read from the other.
+  var newByte1 = byte1 ^ 1;
+  l1[0] = newByte1;
+  var newByte2 = l2[0];
+  l1[0] = byte1;
+  if (newByte1 != newByte2) {
+    Expect.fail("Different buffers${name == null ? "" : ": $name"}");
+  }
+}
diff --git a/tests/standalone_2/dwarf_stack_trace_obfuscate_test.dart b/tests/standalone_2/dwarf_stack_trace_obfuscate_test.dart
index 8d5e46f..60f7bb7 100644
--- a/tests/standalone_2/dwarf_stack_trace_obfuscate_test.dart
+++ b/tests/standalone_2/dwarf_stack_trace_obfuscate_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io';
 
+import 'package:native_stack_traces/native_stack_traces.dart';
 import 'package:path/path.dart' as path;
-import 'package:vm/dwarf/dwarf.dart';
 
 import 'dwarf_stack_trace_test.dart' as base;
 
diff --git a/tests/standalone_2/dwarf_stack_trace_test.dart b/tests/standalone_2/dwarf_stack_trace_test.dart
index 0306320..9d0f3e0 100644
--- a/tests/standalone_2/dwarf_stack_trace_test.dart
+++ b/tests/standalone_2/dwarf_stack_trace_test.dart
@@ -7,10 +7,9 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:native_stack_traces/native_stack_traces.dart';
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
-import 'package:vm/dwarf/convert.dart';
-import 'package:vm/dwarf/dwarf.dart';
 
 @pragma("vm:prefer-inline")
 bar() {
@@ -58,24 +57,28 @@
   final rawLines =
       await Stream.value(rawStack).transform(const LineSplitter()).toList();
 
-  final pcAddresses =
-      collectPCOffsets(rawLines).map((pc) => pc.virtualAddress(dwarf)).toList();
+  final pcOffsets = collectPCOffsets(rawLines).toList();
 
   // We should have at least enough PC addresses to cover the frames we'll be
   // checking.
-  expect(pcAddresses.length, greaterThanOrEqualTo(expectedAllCallsInfo.length));
+  expect(pcOffsets.length, greaterThanOrEqualTo(expectedAllCallsInfo.length));
 
-  final externalFramesInfo =
-      pcAddresses.map((i) => dwarf.callInfo(i)?.toList()).toList();
+  final virtualAddresses =
+      pcOffsets.map((o) => dwarf.virtualAddressOf(o)).toList();
 
-  final allFramesInfo = pcAddresses
-      .map((i) => dwarf.callInfo(i, includeInternalFrames: true)?.toList())
-      .toList();
+  final externalFramesInfo = <List<CallInfo>>[];
+  final allFramesInfo = <List<CallInfo>>[];
+
+  for (final addr in virtualAddresses) {
+    externalFramesInfo.add(dwarf.callInfoFor(addr)?.toList());
+    allFramesInfo
+        .add(dwarf.callInfoFor(addr, includeInternalFrames: true)?.toList());
+  }
 
   print("");
   print("Call information for PC addresses:");
-  for (var i = 0; i < pcAddresses.length; i++) {
-    print("For PC 0x${pcAddresses[i].toRadixString(16)}:");
+  for (var i = 0; i < virtualAddresses.length; i++) {
+    print("For PC 0x${virtualAddresses[i].toRadixString(16)}:");
     print("  Calls corresponding to user or library code:");
     externalFramesInfo[i]?.forEach((frame) => print("    ${frame}"));
     print("  All calls:");
@@ -144,12 +147,12 @@
     CallInfo(
         function: "bar",
         filename: "dwarf_stack_trace_test.dart",
-        line: 18,
+        line: 17,
         inlined: true),
     CallInfo(
         function: "foo",
         filename: "dwarf_stack_trace_test.dart",
-        line: 24,
+        line: 23,
         inlined: false)
   ],
   // The second frame corresponds to call to foo in main.
@@ -157,7 +160,7 @@
     CallInfo(
         function: "main",
         filename: "dwarf_stack_trace_test.dart",
-        line: 30,
+        line: 29,
         inlined: false)
   ],
   // Don't assume anything about any of the frames below the call to foo
diff --git a/third_party/node-source-map-support/LICENSE.md b/third_party/node-source-map-support/LICENSE.md
deleted file mode 100644
index 6247ca9..0000000
--- a/third_party/node-source-map-support/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Evan Wallace
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/third_party/node-source-map-support/README.google b/third_party/node-source-map-support/README.google
deleted file mode 100644
index e3b18fa..0000000
--- a/third_party/node-source-map-support/README.google
+++ /dev/null
@@ -1,13 +0,0 @@
-Name: Node / Browser Source Map support for Stack Traces
-Short Name: node-source-map-support
-URL: https://github.com/requirejs/requirejs
-Version: 0.5.16
-Date: October 29, 2019
-License: MIT
-
-Description: 
-
-This directory contains a utility to map JavaScript stack traces
-back to Dart automatically.  It is used for internal testing.
-
-
diff --git a/third_party/node-source-map-support/README.md b/third_party/node-source-map-support/README.md
deleted file mode 100644
index 40228b7..0000000
--- a/third_party/node-source-map-support/README.md
+++ /dev/null
@@ -1,284 +0,0 @@
-# Source Map Support
-[![Build Status](https://travis-ci.org/evanw/node-source-map-support.svg?branch=master)](https://travis-ci.org/evanw/node-source-map-support)
-
-This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
-
-## Installation and Usage
-
-#### Node support
-
-```
-$ npm install source-map-support
-```
-
-Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
-
-```
-//# sourceMappingURL=path/to/source.map
-```
-
-If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
-respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
-The path should either be absolute or relative to the compiled file.
-
-From here you have two options.
-
-##### CLI Usage
-
-```bash
-node -r source-map-support/register compiled.js
-```
-
-##### Programmatic Usage
-
-Put the following line at the top of the compiled file.
-
-```js
-require('source-map-support').install();
-```
-
-It is also possible to install the source map support directly by
-requiring the `register` module which can be handy with ES6:
-
-```js
-import 'source-map-support/register'
-
-// Instead of:
-import sourceMapSupport from 'source-map-support'
-sourceMapSupport.install()
-```
-Note: if you're using babel-register, it includes source-map-support already.
-
-It is also very useful with Mocha:
-
-```
-$ mocha --require source-map-support/register tests/
-```
-
-#### Browser support
-
-This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
-
-This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
-
-```html
-<script src="browser-source-map-support.js"></script>
-<script>sourceMapSupport.install();</script>
-```
-
-This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
-
-```html
-<script>
-  define(['browser-source-map-support'], function(sourceMapSupport) {
-    sourceMapSupport.install();
-  });
-</script>
-```
-
-## Options
-
-This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
-
-```js
-require('source-map-support').install({
-  handleUncaughtExceptions: false
-});
-```
-
-This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
-
-```js
-require('source-map-support').install({
-  retrieveSourceMap: function(source) {
-    if (source === 'compiled.js') {
-      return {
-        url: 'original.js',
-        map: fs.readFileSync('compiled.js.map', 'utf8')
-      };
-    }
-    return null;
-  }
-});
-```
-
-The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
-In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
-
-```js
-require('source-map-support').install({
-  environment: 'node'
-});
-```
-
-To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
-
-
-```js
-require('source-map-support').install({
-  hookRequire: true
-});
-```
-
-This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
-
-## Demos
-
-#### Basic Demo
-
-original.js:
-
-```js
-throw new Error('test'); // This is the original code
-```
-
-compiled.js:
-
-```js
-require('source-map-support').install();
-
-throw new Error('test'); // This is the compiled code
-// The next line defines the sourceMapping.
-//# sourceMappingURL=compiled.js.map
-```
-
-compiled.js.map:
-
-```json
-{
-  "version": 3,
-  "file": "compiled.js",
-  "sources": ["original.js"],
-  "names": [],
-  "mappings": ";;AAAA,MAAM,IAAI"
-}
-```
-
-Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
-
-```
-$ node compiled.js
-
-original.js:1
-throw new Error('test'); // This is the original code
-      ^
-Error: test
-    at Object.<anonymous> (original.js:1:7)
-    at Module._compile (module.js:456:26)
-    at Object.Module._extensions..js (module.js:474:10)
-    at Module.load (module.js:356:32)
-    at Function.Module._load (module.js:312:12)
-    at Function.Module.runMain (module.js:497:10)
-    at startup (node.js:119:16)
-    at node.js:901:3
-```
-
-#### TypeScript Demo
-
-demo.ts:
-
-```typescript
-declare function require(name: string);
-require('source-map-support').install();
-class Foo {
-  constructor() { this.bar(); }
-  bar() { throw new Error('this is a demo'); }
-}
-new Foo();
-```
-
-Compile and run the file using the TypeScript compiler from the terminal:
-
-```
-$ npm install source-map-support typescript
-$ node_modules/typescript/bin/tsc -sourcemap demo.ts
-$ node demo.js
-
-demo.ts:5
-  bar() { throw new Error('this is a demo'); }
-                ^
-Error: this is a demo
-    at Foo.bar (demo.ts:5:17)
-    at new Foo (demo.ts:4:24)
-    at Object.<anonymous> (demo.ts:7:1)
-    at Module._compile (module.js:456:26)
-    at Object.Module._extensions..js (module.js:474:10)
-    at Module.load (module.js:356:32)
-    at Function.Module._load (module.js:312:12)
-    at Function.Module.runMain (module.js:497:10)
-    at startup (node.js:119:16)
-    at node.js:901:3
-```
-
-There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('source-map-support').install()` in the code base:
-
-```
-$ npm install source-map-support typescript
-$ node_modules/typescript/bin/tsc  -sourcemap demo.ts
-$ node -r source-map-support/register demo.js
-
-demo.ts:5
-  bar() { throw new Error('this is a demo'); }
-                ^
-Error: this is a demo
-    at Foo.bar (demo.ts:5:17)
-    at new Foo (demo.ts:4:24)
-    at Object.<anonymous> (demo.ts:7:1)
-    at Module._compile (module.js:456:26)
-    at Object.Module._extensions..js (module.js:474:10)
-    at Module.load (module.js:356:32)
-    at Function.Module._load (module.js:312:12)
-    at Function.Module.runMain (module.js:497:10)
-    at startup (node.js:119:16)
-    at node.js:901:3
-```
-
-#### CoffeeScript Demo
-
-demo.coffee:
-
-```coffee
-require('source-map-support').install()
-foo = ->
-  bar = -> throw new Error 'this is a demo'
-  bar()
-foo()
-```
-
-Compile and run the file using the CoffeeScript compiler from the terminal:
-
-```sh
-$ npm install source-map-support coffeescript
-$ node_modules/.bin/coffee --map --compile demo.coffee
-$ node demo.js
-
-demo.coffee:3
-  bar = -> throw new Error 'this is a demo'
-                     ^
-Error: this is a demo
-    at bar (demo.coffee:3:22)
-    at foo (demo.coffee:4:3)
-    at Object.<anonymous> (demo.coffee:5:1)
-    at Object.<anonymous> (demo.coffee:1:1)
-    at Module._compile (module.js:456:26)
-    at Object.Module._extensions..js (module.js:474:10)
-    at Module.load (module.js:356:32)
-    at Function.Module._load (module.js:312:12)
-    at Function.Module.runMain (module.js:497:10)
-    at startup (node.js:119:16)
-```
-
-## Tests
-
-This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
-
-* Build the tests using `build.js`
-* Launch the HTTP server (`npm run serve-tests`) and visit
-  * http://127.0.0.1:1336/amd-test
-  * http://127.0.0.1:1336/browser-test
-  * http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
-* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
-
-## License
-
-This code is available under the [MIT license](http://opensource.org/licenses/MIT).
diff --git a/third_party/node-source-map-support/browser-source-map-support.js b/third_party/node-source-map-support/browser-source-map-support.js
deleted file mode 100644
index 58be5d7..0000000
--- a/third_party/node-source-map-support/browser-source-map-support.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Support for source maps in V8 stack traces
- * https://github.com/evanw/node-source-map-support
- */
-/*
- The buffer module from node.js, for the browser.
-
- @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
- license  MIT
-*/
-(this.define||function(G,J){this.sourceMapSupport=J()})("browser-source-map-support",function(G){(function b(p,u,m){function e(d,a){if(!u[d]){if(!p[d]){var l="function"==typeof require&&require;if(!a&&l)return l(d,!0);if(g)return g(d,!0);throw Error("Cannot find module '"+d+"'");}l=u[d]={exports:{}};p[d][0].call(l.exports,function(a){var b=p[d][1][a];return e(b?b:a)},l,l.exports,b,p,u,m)}return u[d].exports}for(var g="function"==typeof require&&require,h=0;h<m.length;h++)e(m[h]);return e})({1:[function(p,
-u,m){G=p("./source-map-support")},{"./source-map-support":21}],2:[function(p,u,m){(function(b){function e(b){b=b.charCodeAt(0);if(43===b)return 62;if(47===b)return 63;if(48>b)return-1;if(58>b)return b-48+52;if(91>b)return b-65;if(123>b)return b-97+26}var g="undefined"!==typeof Uint8Array?Uint8Array:Array;b.toByteArray=function(b){function d(a){r[w++]=a}if(0<b.length%4)throw Error("Invalid string. Length must be a multiple of 4");var a=b.length;var l="="===b.charAt(a-2)?2:"="===b.charAt(a-1)?1:0;var r=
-new g(3*b.length/4-l);var q=0<l?b.length-4:b.length;var w=0;for(a=0;a<q;a+=4){var h=e(b.charAt(a))<<18|e(b.charAt(a+1))<<12|e(b.charAt(a+2))<<6|e(b.charAt(a+3));d((h&16711680)>>16);d((h&65280)>>8);d(h&255)}2===l?(h=e(b.charAt(a))<<2|e(b.charAt(a+1))>>4,d(h&255)):1===l&&(h=e(b.charAt(a))<<10|e(b.charAt(a+1))<<4|e(b.charAt(a+2))>>2,d(h>>8&255),d(h&255));return r};b.fromByteArray=function(b){var d=b.length%3,a="",l;var e=0;for(l=b.length-d;e<l;e+=3){var g=(b[e]<<16)+(b[e+1]<<8)+b[e+2];g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>
-18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g&63);a+=g}switch(d){case 1:g=b[b.length-1];a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>2);a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g<<4&63);a+="==";break;case 2:g=(b[b.length-2]<<8)+
-b[b.length-1],a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>10),a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>4&63),a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g<<2&63),a+="="}return a}})("undefined"===typeof m?this.base64js={}:m)},{}],3:[function(p,u,m){},{}],4:[function(p,u,m){(function(b){var e=Object.prototype.toString,g="function"===typeof b.alloc&&"function"===typeof b.allocUnsafe&&"function"===
-typeof b.from;u.exports=function(h,d,a){if("number"===typeof h)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===e.call(h).slice(8,-1)){d>>>=0;var l=h.byteLength-d;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===a)a=l;else if(a>>>=0,a>l)throw new RangeError("'length' is out of bounds");return g?b.from(h.slice(d,d+a)):new b(new Uint8Array(h.slice(d,d+a)))}if("string"===typeof h){a=d;if("string"!==typeof a||""===a)a="utf8";if(!b.isEncoding(a))throw new TypeError('"encoding" must be a valid string encoding');
-return g?b.from(h,a):new b(h,a)}return g?b.from(h):new b(h)}}).call(this,p("buffer").Buffer)},{buffer:5}],5:[function(p,u,m){function b(f,n,a){if(!(this instanceof b))return new b(f,n,a);var c=typeof f;if("number"===c)var d=0<f?f>>>0:0;else if("string"===c){if("base64"===n)for(f=(f.trim?f.trim():f.replace(/^\s+|\s+$/g,"")).replace(H,"");0!==f.length%4;)f+="=";d=b.byteLength(f,n)}else if("object"===c&&null!==f)"Buffer"===f.type&&F(f.data)&&(f=f.data),d=0<+f.length?Math.floor(+f.length):0;else throw new TypeError("must start with number, buffer, array or string");
-if(this.length>D)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+D.toString(16)+" bytes");if(b.TYPED_ARRAY_SUPPORT)var k=b._augment(new Uint8Array(d));else k=this,k.length=d,k._isBuffer=!0;if(b.TYPED_ARRAY_SUPPORT&&"number"===typeof f.byteLength)k._set(f);else{var C=f;if(F(C)||b.isBuffer(C)||C&&"object"===typeof C&&"number"===typeof C.length)if(b.isBuffer(f))for(n=0;n<d;n++)k[n]=f.readUInt8(n);else for(n=0;n<d;n++)k[n]=(f[n]%256+256)%256;else if("string"===c)k.write(f,
-0,n);else if("number"===c&&!b.TYPED_ARRAY_SUPPORT&&!a)for(n=0;n<d;n++)k[n]=0}return k}function e(f,n,b){var a="";for(b=Math.min(f.length,b);n<b;n++)a+=String.fromCharCode(f[n]);return a}function g(f,n,b){if(0!==f%1||0>f)throw new RangeError("offset is not uint");if(f+n>b)throw new RangeError("Trying to access beyond buffer length");}function h(f,n,a,c,d,k){if(!b.isBuffer(f))throw new TypeError("buffer must be a Buffer instance");if(n>d||n<k)throw new TypeError("value is out of bounds");if(a+c>f.length)throw new TypeError("index out of range");
-}function d(f,n,b,a){0>n&&(n=65535+n+1);for(var c=0,d=Math.min(f.length-b,2);c<d;c++)f[b+c]=(n&255<<8*(a?c:1-c))>>>8*(a?c:1-c)}function a(f,n,b,a){0>n&&(n=4294967295+n+1);for(var c=0,d=Math.min(f.length-b,4);c<d;c++)f[b+c]=n>>>8*(a?c:3-c)&255}function l(f,n,b,a,c,d){if(n>c||n<d)throw new TypeError("value is out of bounds");if(b+a>f.length)throw new TypeError("index out of range");}function r(f,n,b,a,c){c||l(f,n,b,4,3.4028234663852886E38,-3.4028234663852886E38);z.write(f,n,b,a,23,4);return b+4}function q(f,
-n,b,a,c){c||l(f,n,b,8,1.7976931348623157E308,-1.7976931348623157E308);z.write(f,n,b,a,52,8);return b+8}function w(f){for(var n=[],b=0;b<f.length;b++){var a=f.charCodeAt(b);if(127>=a)n.push(a);else{var c=b;55296<=a&&57343>=a&&b++;a=encodeURIComponent(f.slice(c,b+1)).substr(1).split("%");for(c=0;c<a.length;c++)n.push(parseInt(a[c],16))}}return n}function v(f){for(var b=[],a=0;a<f.length;a++)b.push(f.charCodeAt(a)&255);return b}function c(f,b,a,c,d){d&&(c-=c%d);for(d=0;d<c&&!(d+a>=b.length||d>=f.length);d++)b[d+
-a]=f[d];return d}function k(f){try{return decodeURIComponent(f)}catch(n){return String.fromCharCode(65533)}}var x=p("base64-js"),z=p("ieee754"),F=p("is-array");m.Buffer=b;m.SlowBuffer=b;m.INSPECT_MAX_BYTES=50;b.poolSize=8192;var D=1073741823;b.TYPED_ARRAY_SUPPORT=function(){try{var f=new ArrayBuffer(0),b=new Uint8Array(f);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(C){return!1}}();b.isBuffer=function(f){return!(null==
-f||!f._isBuffer)};b.compare=function(f,a){if(!b.isBuffer(f)||!b.isBuffer(a))throw new TypeError("Arguments must be Buffers");for(var c=f.length,n=a.length,d=0,k=Math.min(c,n);d<k&&f[d]===a[d];d++);d!==k&&(c=f[d],n=a[d]);return c<n?-1:n<c?1:0};b.isEncoding=function(f){switch(String(f).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};b.concat=function(f,a){if(!F(f))throw new TypeError("Usage: Buffer.concat(list[, length])");
-if(0===f.length)return new b(0);if(1===f.length)return f[0];var c;if(void 0===a)for(c=a=0;c<f.length;c++)a+=f[c].length;var n=new b(a),d=0;for(c=0;c<f.length;c++){var k=f[c];k.copy(n,d);d+=k.length}return n};b.byteLength=function(f,a){f+="";switch(a||"utf8"){case "ascii":case "binary":case "raw":var b=f.length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=2*f.length;break;case "hex":b=f.length>>>1;break;case "utf8":case "utf-8":b=w(f).length;break;case "base64":b=x.toByteArray(f).length;
-break;default:b=f.length}return b};b.prototype.length=void 0;b.prototype.parent=void 0;b.prototype.toString=function(f,b,a){var c=!1;b>>>=0;a=void 0===a||Infinity===a?this.length:a>>>0;f||(f="utf8");0>b&&(b=0);a>this.length&&(a=this.length);if(a<=b)return"";for(;;)switch(f){case "hex":f=b;b=a;a=this.length;if(!f||0>f)f=0;if(!b||0>b||b>a)b=a;c="";for(a=f;a<b;a++)f=c,c=this[a],c=16>c?"0"+c.toString(16):c.toString(16),c=f+c;return c;case "utf8":case "utf-8":c=f="";for(a=Math.min(this.length,a);b<a;b++)127>=
-this[b]?(f+=k(c)+String.fromCharCode(this[b]),c=""):c+="%"+this[b].toString(16);return f+k(c);case "ascii":return e(this,b,a);case "binary":return e(this,b,a);case "base64":return b=0===b&&a===this.length?x.fromByteArray(this):x.fromByteArray(this.slice(b,a)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,a);a="";for(f=0;f<b.length;f+=2)a+=String.fromCharCode(b[f]+256*b[f+1]);return a;default:if(c)throw new TypeError("Unknown encoding: "+f);f=(f+"").toLowerCase();c=!0}};
-b.prototype.equals=function(f){if(!b.isBuffer(f))throw new TypeError("Argument must be a Buffer");return 0===b.compare(this,f)};b.prototype.inspect=function(){var f="",b=m.INSPECT_MAX_BYTES;0<this.length&&(f=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(f+=" ... "));return"<Buffer "+f+">"};b.prototype.compare=function(f){if(!b.isBuffer(f))throw new TypeError("Argument must be a Buffer");return b.compare(this,f)};b.prototype.get=function(f){console.log(".get() is deprecated. Access using array indexes instead.");
-return this.readUInt8(f)};b.prototype.set=function(f,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(f,b)};b.prototype.write=function(f,b,a,d){if(isFinite(b))isFinite(a)||(d=a,a=void 0);else{var n=d;d=b;b=a;a=n}b=Number(b)||0;n=this.length-b;a?(a=Number(a),a>n&&(a=n)):a=n;d=String(d||"utf8").toLowerCase();switch(d){case "hex":b=Number(b)||0;d=this.length-b;a?(a=Number(a),a>d&&(a=d)):a=d;d=f.length;if(0!==d%2)throw Error("Invalid hex string");a>d/
-2&&(a=d/2);for(d=0;d<a;d++){n=parseInt(f.substr(2*d,2),16);if(isNaN(n))throw Error("Invalid hex string");this[b+d]=n}f=d;break;case "utf8":case "utf-8":f=c(w(f),this,b,a);break;case "ascii":f=c(v(f),this,b,a);break;case "binary":f=c(v(f),this,b,a);break;case "base64":f=c(x.toByteArray(f),this,b,a);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":n=[];for(var k=0;k<f.length;k++){var l=f.charCodeAt(k);d=l>>8;l%=256;n.push(l);n.push(d)}f=c(n,this,b,a,2);break;default:throw new TypeError("Unknown encoding: "+
-d);}return f};b.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};b.prototype.slice=function(f,a){var c=this.length;f=~~f;a=void 0===a?c:~~a;0>f?(f+=c,0>f&&(f=0)):f>c&&(f=c);0>a?(a+=c,0>a&&(a=0)):a>c&&(a=c);a<f&&(a=f);if(b.TYPED_ARRAY_SUPPORT)return b._augment(this.subarray(f,a));c=a-f;for(var d=new b(c,void 0,!0),n=0;n<c;n++)d[n]=this[n+f];return d};b.prototype.readUInt8=function(f,a){a||g(f,1,this.length);return this[f]};b.prototype.readUInt16LE=
-function(f,a){a||g(f,2,this.length);return this[f]|this[f+1]<<8};b.prototype.readUInt16BE=function(f,a){a||g(f,2,this.length);return this[f]<<8|this[f+1]};b.prototype.readUInt32LE=function(f,a){a||g(f,4,this.length);return(this[f]|this[f+1]<<8|this[f+2]<<16)+16777216*this[f+3]};b.prototype.readUInt32BE=function(f,a){a||g(f,4,this.length);return 16777216*this[f]+(this[f+1]<<16|this[f+2]<<8|this[f+3])};b.prototype.readInt8=function(f,a){a||g(f,1,this.length);return this[f]&128?-1*(255-this[f]+1):this[f]};
-b.prototype.readInt16LE=function(f,a){a||g(f,2,this.length);var b=this[f]|this[f+1]<<8;return b&32768?b|4294901760:b};b.prototype.readInt16BE=function(f,a){a||g(f,2,this.length);var b=this[f+1]|this[f]<<8;return b&32768?b|4294901760:b};b.prototype.readInt32LE=function(f,a){a||g(f,4,this.length);return this[f]|this[f+1]<<8|this[f+2]<<16|this[f+3]<<24};b.prototype.readInt32BE=function(a,b){b||g(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};b.prototype.readFloatLE=function(a,
-b){b||g(a,4,this.length);return z.read(this,a,!0,23,4)};b.prototype.readFloatBE=function(a,b){b||g(a,4,this.length);return z.read(this,a,!1,23,4)};b.prototype.readDoubleLE=function(a,b){b||g(a,8,this.length);return z.read(this,a,!0,52,8)};b.prototype.readDoubleBE=function(a,b){b||g(a,8,this.length);return z.read(this,a,!1,52,8)};b.prototype.writeUInt8=function(a,c,d){a=+a;c>>>=0;d||h(this,a,c,1,255,0);b.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[c]=a;return c+1};b.prototype.writeUInt16LE=function(a,
-c,k){a=+a;c>>>=0;k||h(this,a,c,2,65535,0);b.TYPED_ARRAY_SUPPORT?(this[c]=a,this[c+1]=a>>>8):d(this,a,c,!0);return c+2};b.prototype.writeUInt16BE=function(a,c,k){a=+a;c>>>=0;k||h(this,a,c,2,65535,0);b.TYPED_ARRAY_SUPPORT?(this[c]=a>>>8,this[c+1]=a):d(this,a,c,!1);return c+2};b.prototype.writeUInt32LE=function(f,c,d){f=+f;c>>>=0;d||h(this,f,c,4,4294967295,0);b.TYPED_ARRAY_SUPPORT?(this[c+3]=f>>>24,this[c+2]=f>>>16,this[c+1]=f>>>8,this[c]=f):a(this,f,c,!0);return c+4};b.prototype.writeUInt32BE=function(f,
-c,d){f=+f;c>>>=0;d||h(this,f,c,4,4294967295,0);b.TYPED_ARRAY_SUPPORT?(this[c]=f>>>24,this[c+1]=f>>>16,this[c+2]=f>>>8,this[c+3]=f):a(this,f,c,!1);return c+4};b.prototype.writeInt8=function(a,c,d){a=+a;c>>>=0;d||h(this,a,c,1,127,-128);b.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[c]=a;return c+1};b.prototype.writeInt16LE=function(a,c,k){a=+a;c>>>=0;k||h(this,a,c,2,32767,-32768);b.TYPED_ARRAY_SUPPORT?(this[c]=a,this[c+1]=a>>>8):d(this,a,c,!0);return c+2};b.prototype.writeInt16BE=function(a,
-c,k){a=+a;c>>>=0;k||h(this,a,c,2,32767,-32768);b.TYPED_ARRAY_SUPPORT?(this[c]=a>>>8,this[c+1]=a):d(this,a,c,!1);return c+2};b.prototype.writeInt32LE=function(c,d,k){c=+c;d>>>=0;k||h(this,c,d,4,2147483647,-2147483648);b.TYPED_ARRAY_SUPPORT?(this[d]=c,this[d+1]=c>>>8,this[d+2]=c>>>16,this[d+3]=c>>>24):a(this,c,d,!0);return d+4};b.prototype.writeInt32BE=function(c,d,k){c=+c;d>>>=0;k||h(this,c,d,4,2147483647,-2147483648);0>c&&(c=4294967295+c+1);b.TYPED_ARRAY_SUPPORT?(this[d]=c>>>24,this[d+1]=c>>>16,this[d+
-2]=c>>>8,this[d+3]=c):a(this,c,d,!1);return d+4};b.prototype.writeFloatLE=function(a,c,b){return r(this,a,c,!0,b)};b.prototype.writeFloatBE=function(a,c,b){return r(this,a,c,!1,b)};b.prototype.writeDoubleLE=function(a,c,b){return q(this,a,c,!0,b)};b.prototype.writeDoubleBE=function(a,c,b){return q(this,a,c,!1,b)};b.prototype.copy=function(a,c,d,k){d||(d=0);k||0===k||(k=this.length);c||(c=0);if(k!==d&&0!==a.length&&0!==this.length){if(k<d)throw new TypeError("sourceEnd < sourceStart");if(0>c||c>=a.length)throw new TypeError("targetStart out of bounds");
-if(0>d||d>=this.length)throw new TypeError("sourceStart out of bounds");if(0>k||k>this.length)throw new TypeError("sourceEnd out of bounds");k>this.length&&(k=this.length);a.length-c<k-d&&(k=a.length-c+d);k-=d;if(1E3>k||!b.TYPED_ARRAY_SUPPORT)for(var f=0;f<k;f++)a[f+c]=this[f+d];else a._set(this.subarray(d,d+k),c)}};b.prototype.fill=function(a,c,b){a||(a=0);c||(c=0);b||(b=this.length);if(b<c)throw new TypeError("end < start");if(b!==c&&0!==this.length){if(0>c||c>=this.length)throw new TypeError("start out of bounds");
-if(0>b||b>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;c<b;c++)this[c]=a;else{a=w(a.toString());for(var d=a.length;c<b;c++)this[c]=a[c%d]}return this}};b.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(b.TYPED_ARRAY_SUPPORT)return(new b(this)).buffer;for(var a=new Uint8Array(this.length),c=0,d=a.length;c<d;c+=1)a[c]=this[c];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var t=b.prototype;b._augment=
-function(a){a.constructor=b;a._isBuffer=!0;a._get=a.get;a._set=a.set;a.get=t.get;a.set=t.set;a.write=t.write;a.toString=t.toString;a.toLocaleString=t.toString;a.toJSON=t.toJSON;a.equals=t.equals;a.compare=t.compare;a.copy=t.copy;a.slice=t.slice;a.readUInt8=t.readUInt8;a.readUInt16LE=t.readUInt16LE;a.readUInt16BE=t.readUInt16BE;a.readUInt32LE=t.readUInt32LE;a.readUInt32BE=t.readUInt32BE;a.readInt8=t.readInt8;a.readInt16LE=t.readInt16LE;a.readInt16BE=t.readInt16BE;a.readInt32LE=t.readInt32LE;a.readInt32BE=
-t.readInt32BE;a.readFloatLE=t.readFloatLE;a.readFloatBE=t.readFloatBE;a.readDoubleLE=t.readDoubleLE;a.readDoubleBE=t.readDoubleBE;a.writeUInt8=t.writeUInt8;a.writeUInt16LE=t.writeUInt16LE;a.writeUInt16BE=t.writeUInt16BE;a.writeUInt32LE=t.writeUInt32LE;a.writeUInt32BE=t.writeUInt32BE;a.writeInt8=t.writeInt8;a.writeInt16LE=t.writeInt16LE;a.writeInt16BE=t.writeInt16BE;a.writeInt32LE=t.writeInt32LE;a.writeInt32BE=t.writeInt32BE;a.writeFloatLE=t.writeFloatLE;a.writeFloatBE=t.writeFloatBE;a.writeDoubleLE=
-t.writeDoubleLE;a.writeDoubleBE=t.writeDoubleBE;a.fill=t.fill;a.inspect=t.inspect;a.toArrayBuffer=t.toArrayBuffer;return a};var H=/[^+\/0-9A-z]/g},{"base64-js":2,ieee754:6,"is-array":7}],6:[function(p,u,m){m.read=function(b,e,g,h,d){var a=8*d-h-1;var l=(1<<a)-1,r=l>>1,q=-7;d=g?d-1:0;var w=g?-1:1,v=b[e+d];d+=w;g=v&(1<<-q)-1;v>>=-q;for(q+=a;0<q;g=256*g+b[e+d],d+=w,q-=8);a=g&(1<<-q)-1;g>>=-q;for(q+=h;0<q;a=256*a+b[e+d],d+=w,q-=8);if(0===g)g=1-r;else{if(g===l)return a?NaN:Infinity*(v?-1:1);a+=Math.pow(2,
-h);g-=r}return(v?-1:1)*a*Math.pow(2,g-h)};m.write=function(b,e,g,h,d,a){var l,r=8*a-d-1,q=(1<<r)-1,w=q>>1,v=23===d?Math.pow(2,-24)-Math.pow(2,-77):0;a=h?0:a-1;var c=h?1:-1,k=0>e||0===e&&0>1/e?1:0;e=Math.abs(e);isNaN(e)||Infinity===e?(e=isNaN(e)?1:0,h=q):(h=Math.floor(Math.log(e)/Math.LN2),1>e*(l=Math.pow(2,-h))&&(h--,l*=2),e=1<=h+w?e+v/l:e+v*Math.pow(2,1-w),2<=e*l&&(h++,l/=2),h+w>=q?(e=0,h=q):1<=h+w?(e=(e*l-1)*Math.pow(2,d),h+=w):(e=e*Math.pow(2,w-1)*Math.pow(2,d),h=0));for(;8<=d;b[g+a]=e&255,a+=
-c,e/=256,d-=8);h=h<<d|e;for(r+=d;0<r;b[g+a]=h&255,a+=c,h/=256,r-=8);b[g+a-c]|=128*k}},{}],7:[function(p,u,m){var b=Object.prototype.toString;u.exports=Array.isArray||function(e){return!!e&&"[object Array]"==b.call(e)}},{}],8:[function(p,u,m){(function(b){function e(a,b){for(var d=0,l=a.length-1;0<=l;l--){var w=a[l];"."===w?a.splice(l,1):".."===w?(a.splice(l,1),d++):d&&(a.splice(l,1),d--)}if(b)for(;d--;d)a.unshift("..");return a}function g(a,b){if(a.filter)return a.filter(b);for(var d=[],l=0;l<a.length;l++)b(a[l],
-l,a)&&d.push(a[l]);return d}var h=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;m.resolve=function(){for(var a="",d=!1,h=arguments.length-1;-1<=h&&!d;h--){var q=0<=h?arguments[h]:b.cwd();if("string"!==typeof q)throw new TypeError("Arguments to path.resolve must be strings");q&&(a=q+"/"+a,d="/"===q.charAt(0))}a=e(g(a.split("/"),function(a){return!!a}),!d).join("/");return(d?"/":"")+a||"."};m.normalize=function(a){var b=m.isAbsolute(a),h="/"===d(a,-1);(a=e(g(a.split("/"),function(a){return!!a}),
-!b).join("/"))||b||(a=".");a&&h&&(a+="/");return(b?"/":"")+a};m.isAbsolute=function(a){return"/"===a.charAt(0)};m.join=function(){var a=Array.prototype.slice.call(arguments,0);return m.normalize(g(a,function(a,b){if("string"!==typeof a)throw new TypeError("Arguments to path.join must be strings");return a}).join("/"))};m.relative=function(a,b){function d(a){for(var c=0;c<a.length&&""===a[c];c++);for(var b=a.length-1;0<=b&&""===a[b];b--);return c>b?[]:a.slice(c,b-c+1)}a=m.resolve(a).substr(1);b=m.resolve(b).substr(1);
-for(var l=d(a.split("/")),w=d(b.split("/")),e=Math.min(l.length,w.length),c=e,k=0;k<e;k++)if(l[k]!==w[k]){c=k;break}e=[];for(k=c;k<l.length;k++)e.push("..");e=e.concat(w.slice(c));return e.join("/")};m.sep="/";m.delimiter=":";m.dirname=function(a){var b=h.exec(a).slice(1);a=b[0];b=b[1];if(!a&&!b)return".";b&&(b=b.substr(0,b.length-1));return a+b};m.basename=function(a,b){var d=h.exec(a).slice(1)[2];b&&d.substr(-1*b.length)===b&&(d=d.substr(0,d.length-b.length));return d};m.extname=function(a){return h.exec(a).slice(1)[3]};
-var d="b"==="ab".substr(-1)?function(a,b,d){return a.substr(b,d)}:function(a,b,d){0>b&&(b=a.length+b);return a.substr(b,d)}}).call(this,p("g5I+bs"))},{"g5I+bs":9}],9:[function(p,u,m){function b(){}p=u.exports={};p.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(b){return window.setImmediate(b)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var b=[];window.addEventListener("message",function(e){var g=e.source;g!==window&&null!==
-g||"process-tick"!==e.data||(e.stopPropagation(),0<b.length&&b.shift()())},!0);return function(e){b.push(e);window.postMessage("process-tick","*")}}return function(b){setTimeout(b,0)}}();p.title="browser";p.browser=!0;p.env={};p.argv=[];p.on=b;p.addListener=b;p.once=b;p.off=b;p.removeListener=b;p.removeAllListeners=b;p.emit=b;p.binding=function(b){throw Error("process.binding is not supported");};p.cwd=function(){return"/"};p.chdir=function(b){throw Error("process.chdir is not supported");}},{}],
-10:[function(p,u,m){function b(){this._array=[];this._set=h?new Map:Object.create(null)}var e=p("./util"),g=Object.prototype.hasOwnProperty,h="undefined"!==typeof Map;b.fromArray=function(d,a){for(var e=new b,g=0,h=d.length;g<h;g++)e.add(d[g],a);return e};b.prototype.size=function(){return h?this._set.size:Object.getOwnPropertyNames(this._set).length};b.prototype.add=function(b,a){var d=h?b:e.toSetString(b),r=h?this.has(b):g.call(this._set,d),q=this._array.length;r&&!a||this._array.push(b);r||(h?
-this._set.set(b,q):this._set[d]=q)};b.prototype.has=function(b){if(h)return this._set.has(b);b=e.toSetString(b);return g.call(this._set,b)};b.prototype.indexOf=function(b){if(h){var a=this._set.get(b);if(0<=a)return a}else if(a=e.toSetString(b),g.call(this._set,a))return this._set[a];throw Error('"'+b+'" is not in the set.');};b.prototype.at=function(b){if(0<=b&&b<this._array.length)return this._array[b];throw Error("No element indexed by "+b);};b.prototype.toArray=function(){return this._array.slice()};
-m.ArraySet=b},{"./util":19}],11:[function(p,u,m){var b=p("./base64");m.encode=function(e){var g="",h=0>e?(-e<<1)+1:e<<1;do e=h&31,h>>>=5,0<h&&(e|=32),g+=b.encode(e);while(0<h);return g};m.decode=function(e,g,h){var d=e.length,a=0,l=0;do{if(g>=d)throw Error("Expected more digits in base 64 VLQ value.");var r=b.decode(e.charCodeAt(g++));if(-1===r)throw Error("Invalid base64 digit: "+e.charAt(g-1));var q=!!(r&32);r&=31;a+=r<<l;l+=5}while(q);e=a>>1;h.value=1===(a&1)?-e:e;h.rest=g}},{"./base64":12}],12:[function(p,
-u,m){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");m.encode=function(e){if(0<=e&&e<b.length)return b[e];throw new TypeError("Must be between 0 and 63: "+e);};m.decode=function(b){return 65<=b&&90>=b?b-65:97<=b&&122>=b?b-97+26:48<=b&&57>=b?b-48+52:43==b?62:47==b?63:-1}},{}],13:[function(p,u,m){function b(e,g,h,d,a,l){var r=Math.floor((g-e)/2)+e,q=a(h,d[r],!0);return 0===q?r:0<q?1<g-r?b(r,g,h,d,a,l):l==m.LEAST_UPPER_BOUND?g<d.length?g:-1:r:1<r-e?b(e,r,h,d,a,l):l==
-m.LEAST_UPPER_BOUND?r:0>e?-1:e}m.GREATEST_LOWER_BOUND=1;m.LEAST_UPPER_BOUND=2;m.search=function(e,g,h,d){if(0===g.length)return-1;e=b(-1,g.length,e,g,h,d||m.GREATEST_LOWER_BOUND);if(0>e)return-1;for(;0<=e-1&&0===h(g[e],g[e-1],!0);)--e;return e}},{}],14:[function(p,u,m){function b(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var e=p("./util");b.prototype.unsortedForEach=function(b,e){this._array.forEach(b,e)};b.prototype.add=function(b){var g=this._last,d=g.generatedLine,
-a=b.generatedLine,l=g.generatedColumn,r=b.generatedColumn;a>d||a==d&&r>=l||0>=e.compareByGeneratedPositionsInflated(g,b)?this._last=b:this._sorted=!1;this._array.push(b)};b.prototype.toArray=function(){this._sorted||(this._array.sort(e.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};m.MappingList=b},{"./util":19}],15:[function(p,u,m){function b(b,e,d){var a=b[e];b[e]=b[d];b[d]=a}function e(g,h,d,a){if(d<a){var l=d-1;b(g,Math.round(d+Math.random()*(a-d)),a);for(var r=g[a],
-q=d;q<a;q++)0>=h(g[q],r)&&(l+=1,b(g,l,q));b(g,l+1,q);l+=1;e(g,h,d,l-1);e(g,h,l+1,a)}}m.quickSort=function(b,h){e(b,h,0,b.length-1)}},{}],16:[function(p,u,m){function b(a,b){var c=a;"string"===typeof a&&(c=d.parseSourceMapInput(a));return null!=c.sections?new h(c,b):new e(c,b)}function e(a,b){var c=a;"string"===typeof a&&(c=d.parseSourceMapInput(a));var k=d.getArg(c,"version"),e=d.getArg(c,"sources"),w=d.getArg(c,"names",[]),g=d.getArg(c,"sourceRoot",null),h=d.getArg(c,"sourcesContent",null),q=d.getArg(c,
-"mappings");c=d.getArg(c,"file",null);if(k!=this._version)throw Error("Unsupported version: "+k);g&&(g=d.normalize(g));e=e.map(String).map(d.normalize).map(function(a){return g&&d.isAbsolute(g)&&d.isAbsolute(a)?d.relative(g,a):a});this._names=l.fromArray(w.map(String),!0);this._sources=l.fromArray(e,!0);this.sourceRoot=g;this.sourcesContent=h;this._mappings=q;this._sourceMapURL=b;this.file=c}function g(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=
-null}function h(a,e){var c=a;"string"===typeof a&&(c=d.parseSourceMapInput(a));var k=d.getArg(c,"version");c=d.getArg(c,"sections");if(k!=this._version)throw Error("Unsupported version: "+k);this._sources=new l;this._names=new l;var w={line:-1,column:0};this._sections=c.map(function(a){if(a.url)throw Error("Support for url field in sections not implemented.");var c=d.getArg(a,"offset"),k=d.getArg(c,"line"),g=d.getArg(c,"column");if(k<w.line||k===w.line&&g<w.column)throw Error("Section offsets must be ordered and non-overlapping.");
-w=c;return{generatedOffset:{generatedLine:k+1,generatedColumn:g+1},consumer:new b(d.getArg(a,"map"),e)}})}var d=p("./util"),a=p("./binary-search"),l=p("./array-set").ArraySet,r=p("./base64-vlq"),q=p("./quick-sort").quickSort;b.fromSourceMap=function(a){return e.fromSourceMap(a)};b.prototype._version=3;b.prototype.__generatedMappings=null;Object.defineProperty(b.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){this.__generatedMappings||this._parseMappings(this._mappings,
-this.sourceRoot);return this.__generatedMappings}});b.prototype.__originalMappings=null;Object.defineProperty(b.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});b.prototype._charIsMappingSeparator=function(a,b){var c=a.charAt(b);return";"===c||","===c};b.prototype._parseMappings=function(a,b){throw Error("Subclasses must implement _parseMappings");};b.GENERATED_ORDER=
-1;b.ORIGINAL_ORDER=2;b.GREATEST_LOWER_BOUND=1;b.LEAST_UPPER_BOUND=2;b.prototype.eachMapping=function(a,e,c){e=e||null;switch(c||b.GENERATED_ORDER){case b.GENERATED_ORDER:c=this._generatedMappings;break;case b.ORIGINAL_ORDER:c=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var k=this.sourceRoot;c.map(function(a){var b=null===a.source?null:this._sources.at(a.source);b=d.computeSourceURL(k,b,this._sourceMapURL);return{source:b,generatedLine:a.generatedLine,generatedColumn:a.generatedColumn,
-originalLine:a.originalLine,originalColumn:a.originalColumn,name:null===a.name?null:this._names.at(a.name)}},this).forEach(a,e)};b.prototype.allGeneratedPositionsFor=function(b){var e=d.getArg(b,"line"),c={source:d.getArg(b,"source"),originalLine:e,originalColumn:d.getArg(b,"column",0)};null!=this.sourceRoot&&(c.source=d.relative(this.sourceRoot,c.source));if(!this._sources.has(c.source))return[];c.source=this._sources.indexOf(c.source);var k=[];c=this._findMapping(c,this._originalMappings,"originalLine",
-"originalColumn",d.compareByOriginalPositions,a.LEAST_UPPER_BOUND);if(0<=c){var g=this._originalMappings[c];if(void 0===b.column)for(e=g.originalLine;g&&g.originalLine===e;)k.push({line:d.getArg(g,"generatedLine",null),column:d.getArg(g,"generatedColumn",null),lastColumn:d.getArg(g,"lastGeneratedColumn",null)}),g=this._originalMappings[++c];else for(b=g.originalColumn;g&&g.originalLine===e&&g.originalColumn==b;)k.push({line:d.getArg(g,"generatedLine",null),column:d.getArg(g,"generatedColumn",null),
-lastColumn:d.getArg(g,"lastGeneratedColumn",null)}),g=this._originalMappings[++c]}return k};m.SourceMapConsumer=b;e.prototype=Object.create(b.prototype);e.prototype.consumer=b;e.fromSourceMap=function(a,b){var c=Object.create(e.prototype),k=c._names=l.fromArray(a._names.toArray(),!0),w=c._sources=l.fromArray(a._sources.toArray(),!0);c.sourceRoot=a._sourceRoot;c.sourcesContent=a._generateSourcesContent(c._sources.toArray(),c.sourceRoot);c.file=a._file;c._sourceMapURL=b;for(var h=a._mappings.toArray().slice(),
-r=c.__generatedMappings=[],m=c.__originalMappings=[],v=0,p=h.length;v<p;v++){var f=h[v],n=new g;n.generatedLine=f.generatedLine;n.generatedColumn=f.generatedColumn;f.source&&(n.source=w.indexOf(f.source),n.originalLine=f.originalLine,n.originalColumn=f.originalColumn,f.name&&(n.name=k.indexOf(f.name)),m.push(n));r.push(n)}q(c.__originalMappings,d.compareByOriginalPositions);return c};e.prototype._version=3;Object.defineProperty(e.prototype,"sources",{get:function(){return this._sources.toArray().map(function(a){return d.computeSourceURL(this.sourceRoot,
-a,this._sourceMapURL)},this)}});e.prototype._parseMappings=function(a,b){for(var c=1,k=0,e=0,l=0,w=0,h=0,m=a.length,v=0,f={},n={},p=[],u=[],y,B,A,E,I;v<m;)if(";"===a.charAt(v))c++,v++,k=0;else if(","===a.charAt(v))v++;else{y=new g;y.generatedLine=c;for(E=v;E<m&&!this._charIsMappingSeparator(a,E);E++);B=a.slice(v,E);if(A=f[B])v+=B.length;else{for(A=[];v<E;)r.decode(a,v,n),I=n.value,v=n.rest,A.push(I);if(2===A.length)throw Error("Found a source, but no line and column");if(3===A.length)throw Error("Found a source and line, but no column");
-f[B]=A}y.generatedColumn=k+A[0];k=y.generatedColumn;1<A.length&&(y.source=w+A[1],w+=A[1],y.originalLine=e+A[2],e=y.originalLine,y.originalLine+=1,y.originalColumn=l+A[3],l=y.originalColumn,4<A.length&&(y.name=h+A[4],h+=A[4]));u.push(y);"number"===typeof y.originalLine&&p.push(y)}q(u,d.compareByGeneratedPositionsDeflated);this.__generatedMappings=u;q(p,d.compareByOriginalPositions);this.__originalMappings=p};e.prototype._findMapping=function(b,d,c,k,e,g){if(0>=b[c])throw new TypeError("Line must be greater than or equal to 1, got "+
-b[c]);if(0>b[k])throw new TypeError("Column must be greater than or equal to 0, got "+b[k]);return a.search(b,d,e,g)};e.prototype.computeColumnSpans=function(){for(var a=0;a<this._generatedMappings.length;++a){var b=this._generatedMappings[a];if(a+1<this._generatedMappings.length){var c=this._generatedMappings[a+1];if(b.generatedLine===c.generatedLine){b.lastGeneratedColumn=c.generatedColumn-1;continue}}b.lastGeneratedColumn=Infinity}};e.prototype.originalPositionFor=function(a){var e={generatedLine:d.getArg(a,
-"line"),generatedColumn:d.getArg(a,"column")};a=this._findMapping(e,this._generatedMappings,"generatedLine","generatedColumn",d.compareByGeneratedPositionsDeflated,d.getArg(a,"bias",b.GREATEST_LOWER_BOUND));if(0<=a&&(a=this._generatedMappings[a],a.generatedLine===e.generatedLine)){e=d.getArg(a,"source",null);null!==e&&(e=this._sources.at(e),e=d.computeSourceURL(this.sourceRoot,e,this._sourceMapURL));var c=d.getArg(a,"name",null);null!==c&&(c=this._names.at(c));return{source:e,line:d.getArg(a,"originalLine",
-null),column:d.getArg(a,"originalColumn",null),name:c}}return{source:null,line:null,column:null,name:null}};e.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(a){return null==a}):!1};e.prototype.sourceContentFor=function(a,b){if(!this.sourcesContent)return null;var c=a;null!=this.sourceRoot&&(c=d.relative(this.sourceRoot,c));if(this._sources.has(c))return this.sourcesContent[this._sources.indexOf(c)];
-var k=this.sources,e;for(e=0;e<k.length;++e)if(k[e]==a)return this.sourcesContent[e];var g;if(null!=this.sourceRoot&&(g=d.urlParse(this.sourceRoot))){k=c.replace(/^file:\/\//,"");if("file"==g.scheme&&this._sources.has(k))return this.sourcesContent[this._sources.indexOf(k)];if((!g.path||"/"==g.path)&&this._sources.has("/"+c))return this.sourcesContent[this._sources.indexOf("/"+c)]}if(b)return null;throw Error('"'+c+'" is not in the SourceMap.');};e.prototype.generatedPositionFor=function(a){var e=
-d.getArg(a,"source");null!=this.sourceRoot&&(e=d.relative(this.sourceRoot,e));if(!this._sources.has(e))return{line:null,column:null,lastColumn:null};e=this._sources.indexOf(e);e={source:e,originalLine:d.getArg(a,"line"),originalColumn:d.getArg(a,"column")};a=this._findMapping(e,this._originalMappings,"originalLine","originalColumn",d.compareByOriginalPositions,d.getArg(a,"bias",b.GREATEST_LOWER_BOUND));return 0<=a&&(a=this._originalMappings[a],a.source===e.source)?{line:d.getArg(a,"generatedLine",
-null),column:d.getArg(a,"generatedColumn",null),lastColumn:d.getArg(a,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};m.BasicSourceMapConsumer=e;h.prototype=Object.create(b.prototype);h.prototype.constructor=b;h.prototype._version=3;Object.defineProperty(h.prototype,"sources",{get:function(){for(var a=[],b=0;b<this._sections.length;b++)for(var c=0;c<this._sections[b].consumer.sources.length;c++)a.push(this._sections[b].consumer.sources[c]);return a}});h.prototype.originalPositionFor=
-function(b){var e={generatedLine:d.getArg(b,"line"),generatedColumn:d.getArg(b,"column")},c=a.search(e,this._sections,function(a,b){var c=a.generatedLine-b.generatedOffset.generatedLine;return c?c:a.generatedColumn-b.generatedOffset.generatedColumn});return(c=this._sections[c])?c.consumer.originalPositionFor({line:e.generatedLine-(c.generatedOffset.generatedLine-1),column:e.generatedColumn-(c.generatedOffset.generatedLine===e.generatedLine?c.generatedOffset.generatedColumn-1:0),bias:b.bias}):{source:null,
-line:null,column:null,name:null}};h.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(a){return a.consumer.hasContentsOfAllSources()})};h.prototype.sourceContentFor=function(a,b){for(var c=0;c<this._sections.length;c++){var d=this._sections[c].consumer.sourceContentFor(a,!0);if(d)return d}if(b)return null;throw Error('"'+a+'" is not in the SourceMap.');};h.prototype.generatedPositionFor=function(a){for(var b=0;b<this._sections.length;b++){var c=this._sections[b];if(-1!==
-c.consumer.sources.indexOf(d.getArg(a,"source"))){var k=c.consumer.generatedPositionFor(a);if(k)return{line:k.line+(c.generatedOffset.generatedLine-1),column:k.column+(c.generatedOffset.generatedLine===k.line?c.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};h.prototype._parseMappings=function(a,b){this.__generatedMappings=[];this.__originalMappings=[];for(var c=0;c<this._sections.length;c++)for(var k=this._sections[c],e=k.consumer._generatedMappings,g=0;g<e.length;g++){var l=
-e[g],h=k.consumer._sources.at(l.source);h=d.computeSourceURL(k.consumer.sourceRoot,h,this._sourceMapURL);this._sources.add(h);h=this._sources.indexOf(h);var r=null;l.name&&(r=k.consumer._names.at(l.name),this._names.add(r),r=this._names.indexOf(r));l={source:h,generatedLine:l.generatedLine+(k.generatedOffset.generatedLine-1),generatedColumn:l.generatedColumn+(k.generatedOffset.generatedLine===l.generatedLine?k.generatedOffset.generatedColumn-1:0),originalLine:l.originalLine,originalColumn:l.originalColumn,
-name:r};this.__generatedMappings.push(l);"number"===typeof l.originalLine&&this.__originalMappings.push(l)}q(this.__generatedMappings,d.compareByGeneratedPositionsDeflated);q(this.__originalMappings,d.compareByOriginalPositions)};m.IndexedSourceMapConsumer=h},{"./array-set":10,"./base64-vlq":11,"./binary-search":13,"./quick-sort":15,"./util":19}],17:[function(p,u,m){function b(a){a||(a={});this._file=g.getArg(a,"file",null);this._sourceRoot=g.getArg(a,"sourceRoot",null);this._skipValidation=g.getArg(a,
-"skipValidation",!1);this._sources=new h;this._names=new h;this._mappings=new d;this._sourcesContents=null}var e=p("./base64-vlq"),g=p("./util"),h=p("./array-set").ArraySet,d=p("./mapping-list").MappingList;b.prototype._version=3;b.fromSourceMap=function(a){var d=a.sourceRoot,e=new b({file:a.file,sourceRoot:d});a.eachMapping(function(a){var b={generated:{line:a.generatedLine,column:a.generatedColumn}};null!=a.source&&(b.source=a.source,null!=d&&(b.source=g.relative(d,b.source)),b.original={line:a.originalLine,
-column:a.originalColumn},null!=a.name&&(b.name=a.name));e.addMapping(b)});a.sources.forEach(function(b){var l=b;null!==d&&(l=g.relative(d,b));e._sources.has(l)||e._sources.add(l);l=a.sourceContentFor(b);null!=l&&e.setSourceContent(b,l)});return e};b.prototype.addMapping=function(a){var b=g.getArg(a,"generated"),d=g.getArg(a,"original",null),e=g.getArg(a,"source",null);a=g.getArg(a,"name",null);this._skipValidation||this._validateMapping(b,d,e,a);null!=e&&(e=String(e),this._sources.has(e)||this._sources.add(e));
-null!=a&&(a=String(a),this._names.has(a)||this._names.add(a));this._mappings.add({generatedLine:b.line,generatedColumn:b.column,originalLine:null!=d&&d.line,originalColumn:null!=d&&d.column,source:e,name:a})};b.prototype.setSourceContent=function(a,b){var d=a;null!=this._sourceRoot&&(d=g.relative(this._sourceRoot,d));null!=b?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[g.toSetString(d)]=b):this._sourcesContents&&(delete this._sourcesContents[g.toSetString(d)],
-0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};b.prototype.applySourceMap=function(a,b,d){var e=b;if(null==b){if(null==a.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');e=a.file}var l=this._sourceRoot;null!=l&&(e=g.relative(l,e));var m=new h,c=new h;this._mappings.unsortedForEach(function(b){if(b.source===e&&null!=b.originalLine){var k=a.originalPositionFor({line:b.originalLine,
-column:b.originalColumn});null!=k.source&&(b.source=k.source,null!=d&&(b.source=g.join(d,b.source)),null!=l&&(b.source=g.relative(l,b.source)),b.originalLine=k.line,b.originalColumn=k.column,null!=k.name&&(b.name=k.name))}k=b.source;null==k||m.has(k)||m.add(k);b=b.name;null==b||c.has(b)||c.add(b)},this);this._sources=m;this._names=c;a.sources.forEach(function(b){var c=a.sourceContentFor(b);null!=c&&(null!=d&&(b=g.join(d,b)),null!=l&&(b=g.relative(l,b)),this.setSourceContent(b,c))},this)};b.prototype._validateMapping=
-function(a,b,d,e){if(b&&"number"!==typeof b.line&&"number"!==typeof b.column)throw Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(a&&"line"in a&&"column"in a&&0<a.line&&0<=a.column&&!b&&!d&&!e||a&&"line"in a&&"column"in a&&b&&"line"in b&&"column"in b&&0<a.line&&0<=a.column&&0<b.line&&0<=b.column&&
-d))throw Error("Invalid mapping: "+JSON.stringify({generated:a,source:d,original:b,name:e}));};b.prototype._serializeMappings=function(){for(var a=0,b=1,d=0,h=0,m=0,p=0,c="",k,x,z,F=this._mappings.toArray(),D=0,t=F.length;D<t;D++){x=F[D];k="";if(x.generatedLine!==b)for(a=0;x.generatedLine!==b;)k+=";",b++;else if(0<D){if(!g.compareByGeneratedPositionsInflated(x,F[D-1]))continue;k+=","}k+=e.encode(x.generatedColumn-a);a=x.generatedColumn;null!=x.source&&(z=this._sources.indexOf(x.source),k+=e.encode(z-
-p),p=z,k+=e.encode(x.originalLine-1-h),h=x.originalLine-1,k+=e.encode(x.originalColumn-d),d=x.originalColumn,null!=x.name&&(x=this._names.indexOf(x.name),k+=e.encode(x-m),m=x));c+=k}return c};b.prototype._generateSourcesContent=function(a,b){return a.map(function(a){if(!this._sourcesContents)return null;null!=b&&(a=g.relative(b,a));a=g.toSetString(a);return Object.prototype.hasOwnProperty.call(this._sourcesContents,a)?this._sourcesContents[a]:null},this)};b.prototype.toJSON=function(){var a={version:this._version,
-sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(a.file=this._file);null!=this._sourceRoot&&(a.sourceRoot=this._sourceRoot);this._sourcesContents&&(a.sourcesContent=this._generateSourcesContent(a.sources,a.sourceRoot));return a};b.prototype.toString=function(){return JSON.stringify(this.toJSON())};m.SourceMapGenerator=b},{"./array-set":10,"./base64-vlq":11,"./mapping-list":14,"./util":19}],18:[function(p,u,m){function b(b,a,e,g,h){this.children=
-[];this.sourceContents={};this.line=null==b?null:b;this.column=null==a?null:a;this.source=null==e?null:e;this.name=null==h?null:h;this.$$$isSourceNode$$$=!0;null!=g&&this.add(g)}var e=p("./source-map-generator").SourceMapGenerator,g=p("./util"),h=/(\r?\n)/;b.fromStringWithSourceMap=function(d,a,e){function l(a,c){if(null===a||void 0===a.source)m.add(c);else{var d=e?g.join(e,a.source):a.source;m.add(new b(a.originalLine,a.originalColumn,d,c,a.name))}}var m=new b,p=d.split(h),v=0,c=function(){var a=
-v<p.length?p[v++]:void 0,b=(v<p.length?p[v++]:void 0)||"";return a+b},k=1,x=0,z=null;a.eachMapping(function(a){if(null!==z)if(k<a.generatedLine)l(z,c()),k++,x=0;else{var b=p[v]||"",d=b.substr(0,a.generatedColumn-x);p[v]=b.substr(a.generatedColumn-x);x=a.generatedColumn;l(z,d);z=a;return}for(;k<a.generatedLine;)m.add(c()),k++;x<a.generatedColumn&&(b=p[v]||"",m.add(b.substr(0,a.generatedColumn)),p[v]=b.substr(a.generatedColumn),x=a.generatedColumn);z=a},this);v<p.length&&(z&&l(z,c()),m.add(p.splice(v).join("")));
-a.sources.forEach(function(b){var c=a.sourceContentFor(b);null!=c&&(null!=e&&(b=g.join(e,b)),m.setSourceContent(b,c))});return m};b.prototype.add=function(b){if(Array.isArray(b))b.forEach(function(a){this.add(a)},this);else if(b.$$$isSourceNode$$$||"string"===typeof b)b&&this.children.push(b);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+b);return this};b.prototype.prepend=function(b){if(Array.isArray(b))for(var a=b.length-1;0<=a;a--)this.prepend(b[a]);
-else if(b.$$$isSourceNode$$$||"string"===typeof b)this.children.unshift(b);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+b);return this};b.prototype.walk=function(b){for(var a,d=0,e=this.children.length;d<e;d++)a=this.children[d],a.$$$isSourceNode$$$?a.walk(b):""!==a&&b(a,{source:this.source,line:this.line,column:this.column,name:this.name})};b.prototype.join=function(b){var a,d=this.children.length;if(0<d){var e=[];for(a=0;a<d-1;a++)e.push(this.children[a]),
-e.push(b);e.push(this.children[a]);this.children=e}return this};b.prototype.replaceRight=function(b,a){var d=this.children[this.children.length-1];d.$$$isSourceNode$$$?d.replaceRight(b,a):"string"===typeof d?this.children[this.children.length-1]=d.replace(b,a):this.children.push("".replace(b,a));return this};b.prototype.setSourceContent=function(b,a){this.sourceContents[g.toSetString(b)]=a};b.prototype.walkSourceContents=function(b){for(var a=0,d=this.children.length;a<d;a++)this.children[a].$$$isSourceNode$$$&&
-this.children[a].walkSourceContents(b);var e=Object.keys(this.sourceContents);a=0;for(d=e.length;a<d;a++)b(g.fromSetString(e[a]),this.sourceContents[e[a]])};b.prototype.toString=function(){var b="";this.walk(function(a){b+=a});return b};b.prototype.toStringWithSourceMap=function(b){var a="",d=1,g=0,h=new e(b),m=!1,p=null,c=null,k=null,x=null;this.walk(function(b,e){a+=b;null!==e.source&&null!==e.line&&null!==e.column?(p===e.source&&c===e.line&&k===e.column&&x===e.name||h.addMapping({source:e.source,
-original:{line:e.line,column:e.column},generated:{line:d,column:g},name:e.name}),p=e.source,c=e.line,k=e.column,x=e.name,m=!0):m&&(h.addMapping({generated:{line:d,column:g}}),p=null,m=!1);for(var l=0,z=b.length;l<z;l++)10===b.charCodeAt(l)?(d++,g=0,l+1===z?(p=null,m=!1):m&&h.addMapping({source:e.source,original:{line:e.line,column:e.column},generated:{line:d,column:g},name:e.name})):g++});this.walkSourceContents(function(a,b){h.setSourceContent(a,b)});return{code:a,map:h}};m.SourceNode=b},{"./source-map-generator":17,
-"./util":19}],19:[function(p,u,m){function b(a){return(a=a.match(w))?{scheme:a[1],auth:a[2],host:a[3],port:a[4],path:a[5]}:null}function e(a){var b="";a.scheme&&(b+=a.scheme+":");b+="//";a.auth&&(b+=a.auth+"@");a.host&&(b+=a.host);a.port&&(b+=":"+a.port);a.path&&(b+=a.path);return b}function g(a){var c=a,d=b(a);if(d){if(!d.path)return a;c=d.path}a=m.isAbsolute(c);c=c.split(/\/+/);for(var g,h=0,l=c.length-1;0<=l;l--)g=c[l],"."===g?c.splice(l,1):".."===g?h++:0<h&&(""===g?(c.splice(l+1,h),h=0):(c.splice(l,
-2),h--));c=c.join("/");""===c&&(c=a?"/":".");return d?(d.path=c,e(d)):c}function h(a,d){""===a&&(a=".");""===d&&(d=".");var c=b(d),k=b(a);k&&(a=k.path||"/");if(c&&!c.scheme)return k&&(c.scheme=k.scheme),e(c);if(c||d.match(v))return d;if(k&&!k.host&&!k.path)return k.host=d,e(k);c="/"===d.charAt(0)?d:g(a.replace(/\/+$/,"")+"/"+d);return k?(k.path=c,e(k)):c}function d(a){return a}function a(a){return r(a)?"$"+a:a}function l(a){return r(a)?a.slice(1):a}function r(a){if(!a)return!1;var b=a.length;if(9>
-b||95!==a.charCodeAt(b-1)||95!==a.charCodeAt(b-2)||111!==a.charCodeAt(b-3)||116!==a.charCodeAt(b-4)||111!==a.charCodeAt(b-5)||114!==a.charCodeAt(b-6)||112!==a.charCodeAt(b-7)||95!==a.charCodeAt(b-8)||95!==a.charCodeAt(b-9))return!1;for(b-=10;0<=b;b--)if(36!==a.charCodeAt(b))return!1;return!0}function q(a,b){return a===b?0:null===a?1:null===b?-1:a>b?1:-1}m.getArg=function(a,b,d){if(b in a)return a[b];if(3===arguments.length)return d;throw Error('"'+b+'" is a required argument.');};var w=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,
-v=/^data:.+,.+$/;m.urlParse=b;m.urlGenerate=e;m.normalize=g;m.join=h;m.isAbsolute=function(a){return"/"===a.charAt(0)||w.test(a)};m.relative=function(a,b){""===a&&(a=".");a=a.replace(/\/$/,"");for(var c=0;0!==b.indexOf(a+"/");){var d=a.lastIndexOf("/");if(0>d)return b;a=a.slice(0,d);if(a.match(/^([^\/]+:\/)?\/*$/))return b;++c}return Array(c+1).join("../")+b.substr(a.length+1)};p=!("__proto__"in Object.create(null));m.toSetString=p?d:a;m.fromSetString=p?d:l;m.compareByOriginalPositions=function(a,
-b,d){var c=q(a.source,b.source);if(0!==c)return c;c=a.originalLine-b.originalLine;if(0!==c)return c;c=a.originalColumn-b.originalColumn;if(0!==c||d)return c;c=a.generatedColumn-b.generatedColumn;if(0!==c)return c;c=a.generatedLine-b.generatedLine;return 0!==c?c:q(a.name,b.name)};m.compareByGeneratedPositionsDeflated=function(a,b,d){var c=a.generatedLine-b.generatedLine;if(0!==c)return c;c=a.generatedColumn-b.generatedColumn;if(0!==c||d)return c;c=q(a.source,b.source);if(0!==c)return c;c=a.originalLine-
-b.originalLine;if(0!==c)return c;c=a.originalColumn-b.originalColumn;return 0!==c?c:q(a.name,b.name)};m.compareByGeneratedPositionsInflated=function(a,b){var c=a.generatedLine-b.generatedLine;if(0!==c)return c;c=a.generatedColumn-b.generatedColumn;if(0!==c)return c;c=q(a.source,b.source);if(0!==c)return c;c=a.originalLine-b.originalLine;if(0!==c)return c;c=a.originalColumn-b.originalColumn;return 0!==c?c:q(a.name,b.name)};m.parseSourceMapInput=function(a){return JSON.parse(a.replace(/^\)]}'[^\n]*\n/,
-""))};m.computeSourceURL=function(a,d,l){d=d||"";a&&("/"!==a[a.length-1]&&"/"!==d[0]&&(a+="/"),d=a+d);if(l){a=b(l);if(!a)throw Error("sourceMapURL could not be parsed");a.path&&(l=a.path.lastIndexOf("/"),0<=l&&(a.path=a.path.substring(0,l+1)));d=h(e(a),d)}return g(d)}},{}],20:[function(p,u,m){m.SourceMapGenerator=p("./lib/source-map-generator").SourceMapGenerator;m.SourceMapConsumer=p("./lib/source-map-consumer").SourceMapConsumer;m.SourceNode=p("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16,
-"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(p,u,m){(function(b){function e(){return"browser"===f?!0:"node"===f?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function g(a){return function(b){for(var c=0;c<a.length;c++){var d=a[c](b);if(d)return d}return null}}function h(a,b){if(!a)return b;var c=x.dirname(a),d=/^\w+:\/\/[^\/]*/.exec(c);d=d?d[0]:"";var e=c.slice(d.length);
-return d&&/^\/\w:/.test(e)?(d+="/",d+x.resolve(c.slice(d.length),b).replace(/\\/g,"/")):d+x.resolve(c.slice(d.length),b)}function d(a){var b=C[a.source];if(!b){var c=E(a.source);c?(b=C[a.source]={url:c.url,map:new k(c.map)},b.map.sourcesContent&&b.map.sources.forEach(function(a,c){var d=b.map.sourcesContent[c];if(d){var e=h(b.url,a);n[e]=d}})):b=C[a.source]={url:null,map:null}}return b&&b.map&&"function"===typeof b.map.originalPositionFor&&(c=b.map.originalPositionFor(a),null!==c.source)?(c.source=
-h(b.url,c.source),c):a}function a(b){var c=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(b);return c?(b=d({source:c[2],line:+c[3],column:c[4]-1}),"eval at "+c[1]+" ("+b.source+":"+b.line+":"+(b.column+1)+")"):(c=/^eval at ([^(]+) \((.+)\)$/.exec(b))?"eval at "+c[1]+" ("+a(c[2])+")":b}function l(){var a="";if(this.isNative())a="native";else{var b=this.getScriptNameOrSourceURL();!b&&this.isEval()&&(a=this.getEvalOrigin(),a+=", ");a=b?a+b:a+"<anonymous>";b=this.getLineNumber();null!=b&&(a+=":"+b,(b=
-this.getColumnNumber())&&(a+=":"+b))}b="";var c=this.getFunctionName(),d=!0,e=this.isConstructor();if(this.isToplevel()||e)e?b+="new "+(c||"<anonymous>"):c?b+=c:(b+=a,d=!1);else{e=this.getTypeName();"[object Object]"===e&&(e="null");var f=this.getMethodName();c?(e&&0!=c.indexOf(e)&&(b+=e+"."),b+=c,f&&c.indexOf("."+f)!=c.length-f.length-1&&(b+=" [as "+f+"]")):b+=e+"."+(f||"<anonymous>")}d&&(b+=" ("+a+")");return b}function r(a){var b={};Object.getOwnPropertyNames(Object.getPrototypeOf(a)).forEach(function(c){b[c]=
-/^(?:is|get)/.test(c)?function(){return a[c].call(a)}:a[c]});b.toString=l;return b}function q(c,f){void 0===f&&(f={nextPosition:null,curPosition:null});if(c.isNative())return f.curPosition=null,c;var g=c.getFileName()||c.getScriptNameOrSourceURL();if(g){var h=c.getLineNumber(),k=c.getColumnNumber()-1,l=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/.test(b.version)?0:62;1===h&&k>l&&!e()&&!c.isEval()&&(k-=l);var m=d({source:g,line:h,column:k});f.curPosition=m;c=r(c);var p=
-c.getFunctionName;c.getFunctionName=function(){return null==f.nextPosition?p():f.nextPosition.name||p()};c.getFileName=function(){return m.source};c.getLineNumber=function(){return m.line};c.getColumnNumber=function(){return m.column+1};c.getScriptNameOrSourceURL=function(){return m.source};return c}var n=c.isEval()&&c.getEvalOrigin();n&&(n=a(n),c=r(c),c.getEvalOrigin=function(){return n});return c}function w(a,b){H&&(n={},C={});for(var c=(a.name||"Error")+": "+(a.message||""),d={nextPosition:null,
-curPosition:null},e=[],f=b.length-1;0<=f;f--)e.push("\n    at "+q(b[f],d)),d.nextPosition=d.curPosition;d.curPosition=d.nextPosition=null;return c+e.reverse().join("")}function v(a){var b=/\n    at [^(]+ \((.*):(\d+):(\d+)\)/.exec(a.stack);if(b){a=b[1];var c=+b[2];b=+b[3];var d=n[a];if(!d&&u&&u.existsSync(a))try{d=u.readFileSync(a,"utf8")}catch(N){d=""}if(d&&(d=d.split(/(?:\r\n|\r|\n)/)[c-1]))return a+":"+c+"\n"+d+"\n"+Array(b).join(" ")+"^"}return null}function c(){var a=b.emit;b.emit=function(c){if("uncaughtException"===
-c){var d=arguments[1]&&arguments[1].stack,e=0<this.listeners(c).length;if(d&&!e){d=arguments[1];e=v(d);b.stderr._handle&&b.stderr._handle.setBlocking&&b.stderr._handle.setBlocking(!0);e&&(console.error(),console.error(e));console.error(d.stack);b.exit(1);return}}return a.apply(this,arguments)}}var k=p("source-map").SourceMapConsumer,x=p("path");try{var u=p("fs");u.existsSync&&u.readFileSync||(u=null)}catch(M){}var F=p("buffer-from"),D=!1,t=!1,H=!1,f="auto",n={},C={},G=/^data:application\/json[^,]+base64,/,
-y=[],B=[],A=g(y);y.push(function(a){a=a.trim();/^file:/.test(a)&&(a=a.replace(/file:\/\/\/(\w:)?/,function(a,b){return b?"":"/"}));if(a in n)return n[a];var b="";try{if(u)u.existsSync(a)&&(b=u.readFileSync(a,"utf8"));else{var c=new XMLHttpRequest;c.open("GET",a,!1);c.send(null);4===c.readyState&&200===c.status&&(b=c.responseText)}}catch(K){}return n[a]=b});var E=g(B);B.push(function(a){a:{if(e())try{var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);var c=b.getResponseHeader("SourceMap")||b.getResponseHeader("X-SourceMap");
-if(c){var d=c;break a}}catch(O){}d=A(a);b=/(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;for(var f;c=b.exec(d);)f=c;d=f?f[1]:null}if(!d)return null;G.test(d)?(f=d.slice(d.indexOf(",")+1),f=F(f,"base64").toString(),d=a):(d=h(a,d),f=A(d));return f?{url:d,map:f}:null});var I=y.slice(0),L=B.slice(0);m.wrapCallSite=q;m.getErrorSource=v;m.mapSourcePosition=d;m.retrieveSourceMap=E;m.install=function(a){a=a||{};if(a.environment&&(f=
-a.environment,-1===["node","browser","auto"].indexOf(f)))throw Error("environment "+f+" was unknown. Available options are {auto, browser, node}");a.retrieveFile&&(a.overrideRetrieveFile&&(y.length=0),y.unshift(a.retrieveFile));a.retrieveSourceMap&&(a.overrideRetrieveSourceMap&&(B.length=0),B.unshift(a.retrieveSourceMap));if(a.hookRequire&&!e()){try{var d=p("module")}catch(K){}var g=d.prototype._compile;g.__sourceMapSupport||(d.prototype._compile=function(a,b){n[b]=a;C[b]=void 0;return g.call(this,
-a,b)},d.prototype._compile.__sourceMapSupport=!0)}H||(H="emptyCacheBetweenOperations"in a?a.emptyCacheBetweenOperations:!1);D||(D=!0,Error.prepareStackTrace=w);!t&&("handleUncaughtExceptions"in a?a.handleUncaughtExceptions:1)&&"object"===typeof b&&null!==b&&"function"===typeof b.on&&(t=!0,c())};m.resetRetrieveHandlers=function(){y.length=0;B.length=0;y=I.slice(0);B=L.slice(0);E=g(B);A=g(y)}}).call(this,p("g5I+bs"))},{"buffer-from":4,fs:3,"g5I+bs":9,module:3,path:8,"source-map":20}]},{},[1]);return G});
diff --git a/third_party/node-source-map-support/source-map-support.js b/third_party/node-source-map-support/source-map-support.js
deleted file mode 100644
index 1561cee..0000000
--- a/third_party/node-source-map-support/source-map-support.js
+++ /dev/null
@@ -1,587 +0,0 @@
-var SourceMapConsumer = require('source-map').SourceMapConsumer;
-var path = require('path');
-
-var fs;
-try {
-  fs = require('fs');
-  if (!fs.existsSync || !fs.readFileSync) {
-    // fs doesn't have all methods we need
-    fs = null;
-  }
-} catch (err) {
-  /* nop */
-}
-
-var bufferFrom = require('buffer-from');
-
-// Only install once if called multiple times
-var errorFormatterInstalled = false;
-var uncaughtShimInstalled = false;
-
-// If true, the caches are reset before a stack trace formatting operation
-var emptyCacheBetweenOperations = false;
-
-// Supports {browser, node, auto}
-var environment = "auto";
-
-// Maps a file path to a string containing the file contents
-var fileContentsCache = {};
-
-// Maps a file path to a source map for that file
-var sourceMapCache = {};
-
-// Regex for detecting source maps
-var reSourceMap = /^data:application\/json[^,]+base64,/;
-
-// Priority list of retrieve handlers
-var retrieveFileHandlers = [];
-var retrieveMapHandlers = [];
-
-function isInBrowser() {
-  if (environment === "browser")
-    return true;
-  if (environment === "node")
-    return false;
-  return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
-}
-
-function hasGlobalProcessEventEmitter() {
-  return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
-}
-
-function handlerExec(list) {
-  return function(arg) {
-    for (var i = 0; i < list.length; i++) {
-      var ret = list[i](arg);
-      if (ret) {
-        return ret;
-      }
-    }
-    return null;
-  };
-}
-
-var retrieveFile = handlerExec(retrieveFileHandlers);
-
-retrieveFileHandlers.push(function(path) {
-  // Trim the path to make sure there is no extra whitespace.
-  path = path.trim();
-  if (/^file:/.test(path)) {
-    // existsSync/readFileSync can't handle file protocol, but once stripped, it works
-    path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
-      return drive ?
-        '' : // file:///C:/dir/file -> C:/dir/file
-        '/'; // file:///root-dir/file -> /root-dir/file
-    });
-  }
-  if (path in fileContentsCache) {
-    return fileContentsCache[path];
-  }
-
-  var contents = '';
-  try {
-    if (!fs) {
-      // Use SJAX if we are in the browser
-      var xhr = new XMLHttpRequest();
-      xhr.open('GET', path, /** async */ false);
-      xhr.send(null);
-      if (xhr.readyState === 4 && xhr.status === 200) {
-        contents = xhr.responseText;
-      }
-    } else if (fs.existsSync(path)) {
-      // Otherwise, use the filesystem
-      contents = fs.readFileSync(path, 'utf8');
-    }
-  } catch (er) {
-    /* ignore any errors */
-  }
-
-  return fileContentsCache[path] = contents;
-});
-
-// Support URLs relative to a directory, but be careful about a protocol prefix
-// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
-function supportRelativeURL(file, url) {
-  if (!file) return url;
-  var dir = path.dirname(file);
-  var match = /^\w+:\/\/[^\/]*/.exec(dir);
-  var protocol = match ? match[0] : '';
-  var startPath = dir.slice(protocol.length);
-  if (protocol && /^\/\w\:/.test(startPath)) {
-    // handle file:///C:/ paths
-    protocol += '/';
-    return protocol + path.resolve(dir.slice(protocol.length), url).replace(/\\/g, '/');
-  }
-  return protocol + path.resolve(dir.slice(protocol.length), url);
-}
-
-function retrieveSourceMapURL(source) {
-  var fileData;
-
-  if (isInBrowser()) {
-     try {
-       var xhr = new XMLHttpRequest();
-       xhr.open('GET', source, false);
-       xhr.send(null);
-       fileData = xhr.readyState === 4 ? xhr.responseText : null;
-
-       // Support providing a sourceMappingURL via the SourceMap header
-       var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
-                             xhr.getResponseHeader("X-SourceMap");
-       if (sourceMapHeader) {
-         return sourceMapHeader;
-       }
-     } catch (e) {
-     }
-  }
-
-  // Get the URL of the source map
-  fileData = retrieveFile(source);
-  var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
-  // Keep executing the search to find the *last* sourceMappingURL to avoid
-  // picking up sourceMappingURLs from comments, strings, etc.
-  var lastMatch, match;
-  while (match = re.exec(fileData)) lastMatch = match;
-  if (!lastMatch) return null;
-  return lastMatch[1];
-};
-
-// Can be overridden by the retrieveSourceMap option to install. Takes a
-// generated source filename; returns a {map, optional url} object, or null if
-// there is no source map.  The map field may be either a string or the parsed
-// JSON object (ie, it must be a valid argument to the SourceMapConsumer
-// constructor).
-var retrieveSourceMap = handlerExec(retrieveMapHandlers);
-retrieveMapHandlers.push(function(source) {
-  var sourceMappingURL = retrieveSourceMapURL(source);
-  if (!sourceMappingURL) return null;
-
-  // Read the contents of the source map
-  var sourceMapData;
-  if (reSourceMap.test(sourceMappingURL)) {
-    // Support source map URL as a data url
-    var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
-    sourceMapData = bufferFrom(rawData, "base64").toString();
-    sourceMappingURL = source;
-  } else {
-    // Support source map URLs relative to the source URL
-    sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
-    sourceMapData = retrieveFile(sourceMappingURL);
-  }
-
-  if (!sourceMapData) {
-    return null;
-  }
-
-  return {
-    url: sourceMappingURL,
-    map: sourceMapData
-  };
-});
-
-function mapSourcePosition(position) {
-  var sourceMap = sourceMapCache[position.source];
-  if (!sourceMap) {
-    // Call the (overrideable) retrieveSourceMap function to get the source map.
-    var urlAndMap = retrieveSourceMap(position.source);
-    if (urlAndMap) {
-      sourceMap = sourceMapCache[position.source] = {
-        url: urlAndMap.url,
-        map: new SourceMapConsumer(urlAndMap.map)
-      };
-
-      // Load all sources stored inline with the source map into the file cache
-      // to pretend like they are already loaded. They may not exist on disk.
-      if (sourceMap.map.sourcesContent) {
-        sourceMap.map.sources.forEach(function(source, i) {
-          var contents = sourceMap.map.sourcesContent[i];
-          if (contents) {
-            var url = supportRelativeURL(sourceMap.url, source);
-            fileContentsCache[url] = contents;
-          }
-        });
-      }
-    } else {
-      sourceMap = sourceMapCache[position.source] = {
-        url: null,
-        map: null
-      };
-    }
-  }
-
-  // Resolve the source URL relative to the URL of the source map
-  if (sourceMap && sourceMap.map && typeof sourceMap.map.originalPositionFor === 'function') {
-    var originalPosition = sourceMap.map.originalPositionFor(position);
-
-    // Only return the original position if a matching line was found. If no
-    // matching line is found then we return position instead, which will cause
-    // the stack trace to print the path and line for the compiled file. It is
-    // better to give a precise location in the compiled file than a vague
-    // location in the original file.
-    if (originalPosition.source !== null) {
-      originalPosition.source = supportRelativeURL(
-        sourceMap.url, originalPosition.source);
-      return originalPosition;
-    }
-  }
-
-  return position;
-}
-
-// Parses code generated by FormatEvalOrigin(), a function inside V8:
-// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
-function mapEvalOrigin(origin) {
-  // Most eval() calls are in this format
-  var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
-  if (match) {
-    var position = mapSourcePosition({
-      source: match[2],
-      line: +match[3],
-      column: match[4] - 1
-    });
-    return 'eval at ' + match[1] + ' (' + position.source + ':' +
-      position.line + ':' + (position.column + 1) + ')';
-  }
-
-  // Parse nested eval() calls using recursion
-  match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
-  if (match) {
-    return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
-  }
-
-  // Make sure we still return useful information if we didn't find anything
-  return origin;
-}
-
-// This is copied almost verbatim from the V8 source code at
-// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
-// implementation of wrapCallSite() used to just forward to the actual source
-// code of CallSite.prototype.toString but unfortunately a new release of V8
-// did something to the prototype chain and broke the shim. The only fix I
-// could find was copy/paste.
-function CallSiteToString() {
-  var fileName;
-  var fileLocation = "";
-  if (this.isNative()) {
-    fileLocation = "native";
-  } else {
-    fileName = this.getScriptNameOrSourceURL();
-    if (!fileName && this.isEval()) {
-      fileLocation = this.getEvalOrigin();
-      fileLocation += ", ";  // Expecting source position to follow.
-    }
-
-    if (fileName) {
-      fileLocation += fileName;
-    } else {
-      // Source code does not originate from a file and is not native, but we
-      // can still get the source position inside the source string, e.g. in
-      // an eval string.
-      fileLocation += "<anonymous>";
-    }
-    var lineNumber = this.getLineNumber();
-    if (lineNumber != null) {
-      fileLocation += ":" + lineNumber;
-      var columnNumber = this.getColumnNumber();
-      if (columnNumber) {
-        fileLocation += ":" + columnNumber;
-      }
-    }
-  }
-
-  var line = "";
-  var functionName = this.getFunctionName();
-  var addSuffix = true;
-  var isConstructor = this.isConstructor();
-  var isMethodCall = !(this.isToplevel() || isConstructor);
-  if (isMethodCall) {
-    var typeName = this.getTypeName();
-    // Fixes shim to be backward compatable with Node v0 to v4
-    if (typeName === "[object Object]") {
-      typeName = "null";
-    }
-    var methodName = this.getMethodName();
-    if (functionName) {
-      if (typeName && functionName.indexOf(typeName) != 0) {
-        line += typeName + ".";
-      }
-      line += functionName;
-      if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
-        line += " [as " + methodName + "]";
-      }
-    } else {
-      line += typeName + "." + (methodName || "<anonymous>");
-    }
-  } else if (isConstructor) {
-    line += "new " + (functionName || "<anonymous>");
-  } else if (functionName) {
-    line += functionName;
-  } else {
-    line += fileLocation;
-    addSuffix = false;
-  }
-  if (addSuffix) {
-    line += " (" + fileLocation + ")";
-  }
-  return line;
-}
-
-function cloneCallSite(frame) {
-  var object = {};
-  Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
-    object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
-  });
-  object.toString = CallSiteToString;
-  return object;
-}
-
-function wrapCallSite(frame, state) {
-  // provides interface backward compatibility
-  if (state === undefined) {
-    state = { nextPosition: null, curPosition: null }
-  }
-  if(frame.isNative()) {
-    state.curPosition = null;
-    return frame;
-  }
-
-  // Most call sites will return the source file from getFileName(), but code
-  // passed to eval() ending in "//# sourceURL=..." will return the source file
-  // from getScriptNameOrSourceURL() instead
-  var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
-  if (source) {
-    var line = frame.getLineNumber();
-    var column = frame.getColumnNumber() - 1;
-
-    // Fix position in Node where some (internal) code is prepended.
-    // See https://github.com/evanw/node-source-map-support/issues/36
-    // Header removed in node at ^10.16 || >=11.11.0
-    // v11 is not an LTS candidate, we can just test the one version with it.
-    // Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
-    var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
-    var headerLength = noHeader.test(process.version) ? 0 : 62;
-    if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
-      column -= headerLength;
-    }
-
-    var position = mapSourcePosition({
-      source: source,
-      line: line,
-      column: column
-    });
-    state.curPosition = position;
-    frame = cloneCallSite(frame);
-    var originalFunctionName = frame.getFunctionName;
-    frame.getFunctionName = function() {
-      if (state.nextPosition == null) {
-        return originalFunctionName();
-      }
-      return state.nextPosition.name || originalFunctionName();
-    };
-    frame.getFileName = function() { return position.source; };
-    frame.getLineNumber = function() { return position.line; };
-    frame.getColumnNumber = function() { return position.column + 1; };
-    frame.getScriptNameOrSourceURL = function() { return position.source; };
-    return frame;
-  }
-
-  // Code called using eval() needs special handling
-  var origin = frame.isEval() && frame.getEvalOrigin();
-  if (origin) {
-    origin = mapEvalOrigin(origin);
-    frame = cloneCallSite(frame);
-    frame.getEvalOrigin = function() { return origin; };
-    return frame;
-  }
-
-  // If we get here then we were unable to change the source position
-  return frame;
-}
-
-// This function is part of the V8 stack trace API, for more info see:
-// https://v8.dev/docs/stack-trace-api
-function prepareStackTrace(error, stack) {
-  if (emptyCacheBetweenOperations) {
-    fileContentsCache = {};
-    sourceMapCache = {};
-  }
-
-  var name = error.name || 'Error';
-  var message = error.message || '';
-  var errorString = name + ": " + message;
-
-  var state = { nextPosition: null, curPosition: null };
-  var processedStack = [];
-  for (var i = stack.length - 1; i >= 0; i--) {
-    processedStack.push('\n    at ' + wrapCallSite(stack[i], state));
-    state.nextPosition = state.curPosition;
-  }
-  state.curPosition = state.nextPosition = null;
-  return errorString + processedStack.reverse().join('');
-}
-
-// Generate position and snippet of original source with pointer
-function getErrorSource(error) {
-  var match = /\n    at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
-  if (match) {
-    var source = match[1];
-    var line = +match[2];
-    var column = +match[3];
-
-    // Support the inline sourceContents inside the source map
-    var contents = fileContentsCache[source];
-
-    // Support files on disk
-    if (!contents && fs && fs.existsSync(source)) {
-      try {
-        contents = fs.readFileSync(source, 'utf8');
-      } catch (er) {
-        contents = '';
-      }
-    }
-
-    // Format the line from the original source code like node does
-    if (contents) {
-      var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
-      if (code) {
-        return source + ':' + line + '\n' + code + '\n' +
-          new Array(column).join(' ') + '^';
-      }
-    }
-  }
-  return null;
-}
-
-function printErrorAndExit (error) {
-  var source = getErrorSource(error);
-
-  // Ensure error is printed synchronously and not truncated
-  if (process.stderr._handle && process.stderr._handle.setBlocking) {
-    process.stderr._handle.setBlocking(true);
-  }
-
-  if (source) {
-    console.error();
-    console.error(source);
-  }
-
-  console.error(error.stack);
-  process.exit(1);
-}
-
-function shimEmitUncaughtException () {
-  var origEmit = process.emit;
-
-  process.emit = function (type) {
-    if (type === 'uncaughtException') {
-      var hasStack = (arguments[1] && arguments[1].stack);
-      var hasListeners = (this.listeners(type).length > 0);
-
-      if (hasStack && !hasListeners) {
-        return printErrorAndExit(arguments[1]);
-      }
-    }
-
-    return origEmit.apply(this, arguments);
-  };
-}
-
-var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0);
-var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0);
-
-exports.wrapCallSite = wrapCallSite;
-exports.getErrorSource = getErrorSource;
-exports.mapSourcePosition = mapSourcePosition;
-exports.retrieveSourceMap = retrieveSourceMap;
-
-exports.install = function(options) {
-  options = options || {};
-
-  if (options.environment) {
-    environment = options.environment;
-    if (["node", "browser", "auto"].indexOf(environment) === -1) {
-      throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
-    }
-  }
-
-  // Allow sources to be found by methods other than reading the files
-  // directly from disk.
-  if (options.retrieveFile) {
-    if (options.overrideRetrieveFile) {
-      retrieveFileHandlers.length = 0;
-    }
-
-    retrieveFileHandlers.unshift(options.retrieveFile);
-  }
-
-  // Allow source maps to be found by methods other than reading the files
-  // directly from disk.
-  if (options.retrieveSourceMap) {
-    if (options.overrideRetrieveSourceMap) {
-      retrieveMapHandlers.length = 0;
-    }
-
-    retrieveMapHandlers.unshift(options.retrieveSourceMap);
-  }
-
-  // Support runtime transpilers that include inline source maps
-  if (options.hookRequire && !isInBrowser()) {
-    var Module;
-    try {
-      Module = require('module');
-    } catch (err) {
-      // NOP: Loading in catch block to convert webpack error to warning.
-    }
-    var $compile = Module.prototype._compile;
-
-    if (!$compile.__sourceMapSupport) {
-      Module.prototype._compile = function(content, filename) {
-        fileContentsCache[filename] = content;
-        sourceMapCache[filename] = undefined;
-        return $compile.call(this, content, filename);
-      };
-
-      Module.prototype._compile.__sourceMapSupport = true;
-    }
-  }
-
-  // Configure options
-  if (!emptyCacheBetweenOperations) {
-    emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
-      options.emptyCacheBetweenOperations : false;
-  }
-
-  // Install the error reformatter
-  if (!errorFormatterInstalled) {
-    errorFormatterInstalled = true;
-    Error.prepareStackTrace = prepareStackTrace;
-  }
-
-  if (!uncaughtShimInstalled) {
-    var installHandler = 'handleUncaughtExceptions' in options ?
-      options.handleUncaughtExceptions : true;
-
-    // Provide the option to not install the uncaught exception handler. This is
-    // to support other uncaught exception handlers (in test frameworks, for
-    // example). If this handler is not installed and there are no other uncaught
-    // exception handlers, uncaught exceptions will be caught by node's built-in
-    // exception handler and the process will still be terminated. However, the
-    // generated JavaScript code will be shown above the stack trace instead of
-    // the original source code.
-    if (installHandler && hasGlobalProcessEventEmitter()) {
-      uncaughtShimInstalled = true;
-      shimEmitUncaughtException();
-    }
-  }
-};
-
-exports.resetRetrieveHandlers = function() {
-  retrieveFileHandlers.length = 0;
-  retrieveMapHandlers.length = 0;
-
-  retrieveFileHandlers = originalRetrieveFileHandlers.slice(0);
-  retrieveMapHandlers = originalRetrieveMapHandlers.slice(0);
-
-  retrieveSourceMap = handlerExec(retrieveMapHandlers);
-  retrieveFile = handlerExec(retrieveFileHandlers);
-}
diff --git a/tools/VERSION b/tools/VERSION
index eeb5240..3140836 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 8
 PATCH 0
-PRERELEASE 5
+PRERELEASE 6
 PRERELEASE_PATCH 0
-ABI_VERSION 27
-OLDEST_SUPPORTED_ABI_VERSION 27
+ABI_VERSION 28
+OLDEST_SUPPORTED_ABI_VERSION 28
diff --git a/tools/bots/README.md b/tools/bots/README.md
index 706c5b4..52dd12f 100644
--- a/tools/bots/README.md
+++ b/tools/bots/README.md
@@ -90,6 +90,7 @@
 - `${mode}`: the mode in which to run the tests; e.g., `release`, `debug`
 - `${arch}`: architecture to run the tests on; e.g., `ia32`, `x64`
 - `$[system}`: the system on which to run the tests; e.g., `win`, `linux`, `mac`
+- `${runtime}`: the runtime to use to run the tests; e.g., `vm`, `chrome`, `d8`
 
 ```json
 "steps": [
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 97fcce5..a3128d6 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -48,7 +48,6 @@
       "tests/ffi/",
       "third_party/babel/babel.min.js",
       "third_party/d8/",
-      "third_party/node-source-map-support/",
       "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
@@ -90,7 +89,6 @@
       "tests/ffi/",
       "third_party/babel/babel.min.js",
       "third_party/d8/",
-      "third_party/node-source-map-support/",
       "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
@@ -131,7 +129,6 @@
       "tests/standalone_2/",
       "tests/ffi/",
       "third_party/d8/",
-      "third_party/node-source-map-support/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "third_party/requirejs/",
@@ -212,7 +209,6 @@
       "tests/standalone_2/",
       "tests/ffi/",
       "third_party/d8/",
-      "third_party/node-source-map-support/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "third_party/requirejs/",
@@ -314,11 +310,13 @@
       "pkg/build_integration/",
       "pkg/dart_internal/",
       "pkg/dart2native/",
+      "pkg/dart2js_tools/",
       "pkg/expect/",
       "pkg/front_end/",
       "pkg/js/",
       "pkg/kernel/",
       "pkg/meta/",
+      "pkg/native_stack_traces/",
       "pkg/pkg.status",
       "pkg/smith/",
       "pkg/status_file/",
@@ -1290,7 +1288,8 @@
           "name": "vm weak tests with asserts",
           "arguments": [
             "-ndartk-weak-asserts-${system}-${mode}-${arch}",
-            "language"
+            "language",
+            "lib/mirrors"
           ]
         }
       ]
@@ -1570,6 +1569,13 @@
             "lib",
             "dartdevc_native"
           ]
+        },
+        {
+          "name": "ddc nnbd strong co19 tests",
+          "arguments": [
+            "-ndartdevk-strong-linux-release-chrome",
+            "co19/LanguageFeatures/nnbd"
+          ]
         }
       ]
     },
@@ -2331,13 +2337,17 @@
           "name": "analyze nnbd strong tests enable-asserts",
           "arguments": [
             "-nanalyzer-asserts-strong-${system}",
-            "language"]
+            "language",
+            "lib/mirrors"
+          ]
         },
         {
           "name": "analyze nnbd weak tests enable-asserts",
           "arguments": [
             "-nanalyzer-asserts-weak-${system}",
-            "language"]
+            "language",
+            "lib/mirrors"
+          ]
         },
         {
           "name": "analyze nnbd strong co19 tests",
@@ -2458,6 +2468,11 @@
           "arguments": ["--fatal-warnings", "pkg/meta"]
         },
         {
+          "name": "analyze pkg/native_stack_traces",
+          "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
+          "arguments": ["--fatal-warnings", "pkg/native_stack_traces"]
+        },
+        {
           "name": "analyze pkg/smith",
           "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
           "arguments": ["--fatal-warnings", "pkg/smith"]
diff --git a/tools/run_offsets_extractor.sh b/tools/run_offsets_extractor.sh
index e7bf651..c55cc24 100755
--- a/tools/run_offsets_extractor.sh
+++ b/tools/run_offsets_extractor.sh
@@ -16,25 +16,54 @@
 
 # We're regenerating the file, but we want to keep all the comments etc at the
 # top of the file. So just delete everything after the first "#if defined".
-LINE=$(grep "#if defined" "$FILE" -n | head -n 1 | sed "s/^\([0-9]*\):.*/\1/")
+LINE=$(grep "#if " "$FILE" -n | head -n 1 | sed "s/^\([0-9]*\):.*/\1/")
 TEMP="${FILE}.temp"
-head -n $(expr $LINE - 1) "$FILE" >"$TEMP"
+TEMP_HEADER="${FILE}.header.temp"
+TEMP_JIT="${FILE}.jit.temp"
+TEMP_AOT="${FILE}.aot.temp"
+head -n $(expr $LINE - 1) "$FILE" >"$TEMP_HEADER"
 
 # Run offsets_extractor for every architecture and append the results.
 run() {
-  echo "" >>"$TEMP"
-  tools/gn.py --mode=release --arch=$1
-  tools/build.py --mode=release --arch=$1 offsets_extractor
-  out/$2/offsets_extractor >>"$TEMP"
+  tools/gn.py --mode=$1 --arch=$2
+  tools/build.py --mode=$1 --arch=$2 offsets_extractor offsets_extractor_precompiled_runtime
+  echo "" >>"$TEMP_JIT"
+  out/$3/offsets_extractor >>"$TEMP_JIT"
+  echo "" >>"$TEMP_AOT"
+  out/$3/offsets_extractor_precompiled_runtime >>"$TEMP_AOT"
 }
-run simarm ReleaseSIMARM
-run x64 ReleaseX64
-run ia32 ReleaseIA32
-run simarm64 ReleaseSIMARM64
+echo "" >>"$TEMP_JIT"
+echo "" >>"$TEMP_AOT"
+echo "#if !defined(PRODUCT)" >>"$TEMP_JIT"
+echo "#if !defined(PRODUCT)" >>"$TEMP_AOT"
+run release simarm ReleaseSIMARM
+run release x64 ReleaseX64
+run release ia32 ReleaseIA32
+run release simarm64 ReleaseSIMARM64
+echo "" >>"$TEMP_JIT"
+echo "" >>"$TEMP_AOT"
+echo "#else  // !defined(PRODUCT)" >>"$TEMP_JIT"
+echo "#else  // !defined(PRODUCT)" >>"$TEMP_AOT"
+run product simarm ProductSIMARM
+run product x64 ProductX64
+run product ia32 ProductIA32
+run product simarm64 ProductSIMARM64
+echo "" >>"$TEMP_JIT"
+echo "" >>"$TEMP_AOT"
+echo "#endif  // !defined(PRODUCT)" >>"$TEMP_JIT"
+echo "#endif  // !defined(PRODUCT)" >>"$TEMP_AOT"
 
-# Cleanup.
+cat $TEMP_HEADER >>"$TEMP"
+cat $TEMP_JIT >>"$TEMP"
+cat $TEMP_AOT >>"$TEMP"
+
 echo "" >>"$TEMP"
 echo "#endif  // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_EXTRACTED_H_" >>"$TEMP"
 mv "$TEMP" "$FILE"
+
+# Cleanup.
 git cl format "$FILE"
+rm "$TEMP_HEADER"
+rm "$TEMP_JIT"
+rm "$TEMP_AOT"
 echo -e "\n\nSuccessfully generated $FILE :)"
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index 7d35041..2ee2a70 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -827,7 +827,7 @@
     ;
 
 argumentPart
-    :    typeArguments? arguments
+    :    '?'? typeArguments? arguments
     ;
 
 incrementOperator
@@ -854,7 +854,7 @@
 assignableSelector
     :    unconditionalAssignableSelector
     |    '?.' identifier
-    |    '?.[' expression ']'
+    |    '?' '[' expression ']'
     ;
 
 identifierNotFUNCTION
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index 7665d74..35b88d7 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -46,9 +46,17 @@
   outputs = [
     output,
   ]
-  args = [
-    "build-strong",
-    rebase_path(output),
-    rebase_path("../../sdk"),
-  ]
+  if (use_nnbd) {
+    args = [
+      "build-non-nullable",
+      rebase_path(output),
+      rebase_path("../../sdk_nnbd"),
+    ]
+  } else {
+    args = [
+      "build-legacy",
+      rebase_path(output),
+      rebase_path("../../sdk"),
+    ]
+  }
 }