Version 2.2.1-dev.4.0

Merge commit '523e3789e05ea07cdd21feadb04dc8ea0174204e' into dev
diff --git a/.packages b/.packages
index cf69a8b..08c0d29 100644
--- a/.packages
+++ b/.packages
@@ -97,7 +97,6 @@
 typed_data:third_party/pkg/typed_data/lib
 unittest:third_party/pkg/unittest/lib
 usage:third_party/pkg/usage/lib
-utf:third_party/pkg/utf/lib
 vm:pkg/vm/lib
 watcher:third_party/pkg/watcher/lib
 web_components:third_party/pkg/web_components/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3ef64c7..8aa7a1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,21 @@
+## 2.2.1-dev.4.0
+
+### Dart VM
+
+* The VM service now requires an authentication code by default. This behavior
+  can be disabled by providing the `--disable-service-auth-codes` flag.
+
+### Tool Changes
+
+#### Linter
+
+The Linter was updated to `0.1.85` which includes the following changes:
+
+* (**BREAKING**) renamed `spread_collections` to `prefer_spread_collections`
+* new lint: `prefer_for_elements_to_map_fromIterable`
+* new lint: `prefer_if_elements_to_conditional_expressions`
+* new lint: `diagnostic_describe_all_properties`
+
 ## 2.2.1-dev.3.1
 
 * Cherry-pick 245576a096a2da54ef21d664d37d1f50f6f8dbb7 to dev
@@ -13,6 +31,10 @@
 
 ## 2.2.1-dev.3.0
 
+### Dart VM
+
+* Support for deprecated flags '-c' and '--checked' has been removed
+
 ### Core library changes
 
 #### `dart:isolate`
@@ -33,13 +55,10 @@
 The Linter was updated to `0.1.83` which includes the following changes:
 
 * updated `file_names` to skip prefixed-extension Dart files (e.g., `.css.dart`, `.g.dart`)
-* updated SDK constraint to `2.2.0`
 * miscellaneous rule documentation fixes
-* (internal) updated sources to use Set literals
 * fixed NPE in `avoid_shadowing_type_parameters`
 * added linter version numbering for use in analyzer summaries
 * fixed type utilities to handle inheritance cycles
-* (internal) changes to adopt new `package:analyzer` APIs
 * fixed `unnecessary_parenthesis` false positives
 
 ## 2.2.1-dev.2.0
diff --git a/DEPS b/DEPS
index 5c76e5a..9d0806f 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_2_rev": "c3b33ee90c5ee7f88fdb0ead08fdbb40c54954d2",
+  "co19_2_rev": "7e743ef29b4c06f1a2b8b9dc70ead60b31aab526",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
@@ -84,7 +84,7 @@
   "dartdoc_tag" : "v0.28.2",
   "fixnum_tag": "0.10.9",
   "glob_tag": "1.1.7",
-  "html_tag" : "0.13.4+1",
+  "html_tag" : "0.14.0",
   "http_io_rev": "57da05a66f5bf7df3dd7aebe7b7efe0dfc477baa",
   "http_multi_server_tag" : "2.0.5",
   "http_parser_tag" : "3.1.3",
@@ -95,7 +95,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.83",
+  "linter_tag": "0.1.85",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.0.2",
@@ -135,7 +135,6 @@
   "typed_data_tag": "1.1.6",
   "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
   "usage_tag": "3.4.0",
-  "utf_tag": "0.9.0+5",
   "watcher_rev": "0.9.7+12",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_tag": "1.0.9",
@@ -156,7 +155,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.2.1-dev.1.1",
+          "version": "version:2.2.1-dev.3.1",
       }],
       "dep_type": "cipd",
   },
@@ -362,8 +361,6 @@
       "@" + Var("unittest_rev"),
   Var("dart_root") + "/third_party/pkg/usage":
       Var("dart_git") + "usage.git" + "@" + Var("usage_tag"),
-  Var("dart_root") + "/third_party/pkg/utf":
-      Var("dart_git") + "utf.git" + "@" + Var("utf_tag"),
   Var("dart_root") + "/third_party/pkg/watcher":
       Var("dart_git") + "watcher.git" + "@" + Var("watcher_rev"),
   Var("dart_root") + "/third_party/pkg/web_components":
diff --git a/WATCHLISTS b/WATCHLISTS
index 598f0ab..415a9bd 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -80,7 +80,7 @@
                 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
     'mirrors' : [ 'rmacnak@google.com' ],
-    'observatory': [ 'rmacnak@google.com' ],
+    'observatory': [ 'bkonyi@google.com', 'rmacnak@google.com' ],
     'package_vm': [ 'alexmarkov@google.com' ],
     'runtime': [ 'vm-dev@dartlang.org' ],
     'vm_compiler': [ 'dart-vm-compiler-team+reviews@google.com' ],
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index f384766..204d162 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.25.0
+  1.26.0
 </h1>
 <p>
   This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 0125a30..35174b9 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.25.0';
+const String PROTOCOL_VERSION = '1.26.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -201,6 +201,7 @@
 const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file';
+const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE =
     'edit.isPostfixCompletionApplicable';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index ad7e249..6e7da59 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -10312,6 +10313,8 @@
 
   List<ImportedElements> _elements;
 
+  int _offset;
+
   /**
    * The file in which the specified elements are to be made accessible.
    */
@@ -10338,9 +10341,29 @@
     this._elements = value;
   }
 
-  EditImportElementsParams(String file, List<ImportedElements> elements) {
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  void set offset(int value) {
+    this._offset = value;
+  }
+
+  EditImportElementsParams(String file, List<ImportedElements> elements,
+      {int offset}) {
     this.file = file;
     this.elements = elements;
+    this.offset = offset;
   }
 
   factory EditImportElementsParams.fromJson(
@@ -10365,7 +10388,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "elements");
       }
-      return new EditImportElementsParams(file, elements);
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      }
+      return new EditImportElementsParams(file, elements, offset: offset);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json);
     }
@@ -10382,6 +10409,9 @@
     result["file"] = file;
     result["elements"] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    if (offset != null) {
+      result["offset"] = offset;
+    }
     return result;
   }
 
@@ -10398,7 +10428,8 @@
     if (other is EditImportElementsParams) {
       return file == other.file &&
           listEqual(elements, other.elements,
-              (ImportedElements a, ImportedElements b) => a == b);
+              (ImportedElements a, ImportedElements b) => a == b) &&
+          offset == other.offset;
     }
     return false;
   }
@@ -10408,6 +10439,7 @@
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -21541,7 +21573,7 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  *
@@ -21555,12 +21587,12 @@
   List<String> _validElementKinds;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   String get lexeme => _lexeme;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   void set lexeme(String value) {
     assert(value != null);
@@ -21568,31 +21600,38 @@
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   String get type => _type;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   void set type(String value) {
-    assert(value != null);
     this._type = value;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   List<String> get validElementKinds => _validElementKinds;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   void set validElementKinds(List<String> value) {
     this._validElementKinds = value;
   }
 
-  TokenDetails(String lexeme, String type, {List<String> validElementKinds}) {
+  TokenDetails(String lexeme, {String type, List<String> validElementKinds}) {
     this.lexeme = lexeme;
     this.type = type;
     this.validElementKinds = validElementKinds;
@@ -21613,8 +21652,6 @@
       String type;
       if (json.containsKey("type")) {
         type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, "type");
       }
       List<String> validElementKinds;
       if (json.containsKey("validElementKinds")) {
@@ -21623,8 +21660,8 @@
             json["validElementKinds"],
             jsonDecoder.decodeString);
       }
-      return new TokenDetails(lexeme, type,
-          validElementKinds: validElementKinds);
+      return new TokenDetails(lexeme,
+          type: type, validElementKinds: validElementKinds);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json);
     }
@@ -21634,7 +21671,9 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["lexeme"] = lexeme;
-    result["type"] = type;
+    if (type != null) {
+      result["type"] = type;
+    }
     if (validElementKinds != null) {
       result["validElementKinds"] = validElementKinds;
     }
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 50834b3..3ed2774 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -70,7 +70,8 @@
     '**/*.${AnalysisEngine.SUFFIX_HTM}',
     '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
     '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
-    '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
+    '**/${AnalysisEngine.PUBSPEC_YAML_FILE}',
+    '**/${AnalysisEngine.ANDROID_MANIFEST_FILE}'
   ];
 
   /// The [ResourceProvider] using which paths are converted into [Resource]s.
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index f9ce8ac..b8adeca 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/plugin/resolver_provider.dart';
+import 'package:analyzer/src/manifest/manifest_validator.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/source/path_filter.dart';
@@ -394,6 +395,11 @@
   static const String LIB_DIR_NAME = 'lib';
 
   /**
+   * File name of Android manifest files.
+   */
+  static const String MANIFEST_NAME = 'AndroidManifest.xml';
+
+  /**
    * File name of pubspec files.
    */
   static const String PUBSPEC_NAME = 'pubspec.yaml';
@@ -891,6 +897,32 @@
         convertedErrors ?? <protocol.AnalysisError>[]);
   }
 
+  /**
+   * Use the given analysis [driver] to analyze the content of the 
+   * AndroidManifest file at the given [path].
+   */
+  void _analyzeManifestFile(AnalysisDriver driver, String path) {
+    List<protocol.AnalysisError> convertedErrors;
+    try {
+      String content = _readFile(path);
+      ManifestValidator validator =
+          new ManifestValidator(resourceProvider.getFile(path).createSource());
+      LineInfo lineInfo = _computeLineInfo(content);
+      List<AnalysisError> errors = validator.validate(
+          content, driver.analysisOptions.chromeOsManifestChecks);
+      AnalyzerConverter converter = new AnalyzerConverter();
+      convertedErrors = converter.convertAnalysisErrors(errors,
+          lineInfo: lineInfo, options: driver.analysisOptions);
+    } catch (exception) {
+      // If the file cannot be analyzed, fall through to clear any previous
+      // errors.
+    }
+    callbacks.notificationManager.recordAnalysisErrors(
+        NotificationManager.serverId,
+        path,
+        convertedErrors ?? <protocol.AnalysisError>[]);
+  }
+
   void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) {
     if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
       AnalysisDriver driver = info.analysisDriver;
@@ -936,6 +968,19 @@
     }
   }
 
+  void _checkForManifestUpdate(String path, ContextInfo info) {
+    if (_isManifest(path)) {
+      AnalysisDriver driver = info.analysisDriver;
+      if (driver == null) {
+        // I suspect that this happens as a result of a race condition: server
+        // has determined that the file (at [path]) is in a context, but hasn't
+        // yet created a driver for that context.
+        return;
+      }
+      _analyzeManifestFile(driver, path);
+    }
+  }
+
   /**
    * Compute the set of files that are being flushed, this is defined as
    * the set of sources in the removed context (context.sources), that are
@@ -1094,6 +1139,10 @@
     if (pubspecFile.exists) {
       _analyzePubspecFile(info.analysisDriver, pubspecFile.path);
     }
+    File manifestFile = folder.getChildAssumingFile(MANIFEST_NAME);
+    if (manifestFile.exists) {
+      _analyzeManifestFile(info.analysisDriver, manifestFile.path);
+    }
     return info;
   }
 
@@ -1409,6 +1458,7 @@
     _checkForPackagespecUpdate(path, info);
     _checkForAnalysisOptionsUpdate(path, info);
     _checkForPubspecUpdate(path, info);
+    _checkForManifestUpdate(path, info);
   }
 
   /**
@@ -1465,6 +1515,8 @@
 
   bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
 
+  bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
+
   /**
    * Merges [info] context into its parent.
    */
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index e5d221d..3951541 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -39,7 +39,7 @@
   /**
    * The completion services that the client is currently subscribed.
    */
-  final Set<CompletionService> _subscriptions = Set<CompletionService>();
+  final Set<CompletionService> subscriptions = Set<CompletionService>();
 
   /**
    * The next completion response id.
@@ -365,7 +365,7 @@
     // create the kinds set, so signal the completion manager about opt-in.
     Set<ElementKind> includedElementKinds;
     List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
-    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+    if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
       includedElementKinds = Set<ElementKind>();
       includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
     }
@@ -461,10 +461,10 @@
   Response setSubscriptions(Request request) {
     var params = CompletionSetSubscriptionsParams.fromRequest(request);
 
-    _subscriptions.clear();
-    _subscriptions.addAll(params.subscriptions);
+    subscriptions.clear();
+    subscriptions.addAll(params.subscriptions);
 
-    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+    if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
       server.createDeclarationsTracker((change) {
         server.sendNotification(
           createCompletionAvailableSuggestionsNotification(change),
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index c3085a7..bbe879f 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -72,13 +72,7 @@
 ) {
   return protocol.CompletionAvailableSuggestionsParams(
     changedLibraries: change.changed.map((library) {
-      return protocol.AvailableSuggestionSet(
-        library.id,
-        library.uriStr,
-        library.declarations.map((declaration) {
-          return _protocolAvailableSuggestion(declaration);
-        }).toList(),
-      );
+      return _protocolAvailableSuggestionSet(library);
     }).toList(),
     removedLibraries: change.removed,
   ).toNotification();
@@ -103,13 +97,13 @@
     Declaration declaration) {
   var label = declaration.name;
   if (declaration.kind == DeclarationKind.CONSTRUCTOR) {
-    label = declaration.name2;
+    label = declaration.parent.name;
     if (declaration.name.isNotEmpty) {
       label += '.${declaration.name}';
     }
   }
   if (declaration.kind == DeclarationKind.ENUM_CONSTANT) {
-    label = '${declaration.name2}.${declaration.name}';
+    label = '${declaration.parent.name}.${declaration.name}';
   }
 
   List<String> relevanceTags;
@@ -134,6 +128,23 @@
   );
 }
 
+protocol.AvailableSuggestionSet _protocolAvailableSuggestionSet(
+    Library library) {
+  var items = <protocol.AvailableSuggestion>[];
+
+  void addItem(Declaration declaration) {
+    var suggestion = _protocolAvailableSuggestion(declaration);
+    items.add(suggestion);
+    declaration.children.forEach(addItem);
+  }
+
+  for (var declaration in library.declarations) {
+    addItem(declaration);
+  }
+
+  return protocol.AvailableSuggestionSet(library.id, library.uriStr, items);
+}
+
 protocol.Element _protocolElement(Declaration declaration) {
   return protocol.Element(
     _protocolElementKind(declaration.kind),
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index 931932e..0525b77 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -21,6 +21,7 @@
   final AnalysisServer server;
 
   final Request request;
+  final pkgFolders = <Folder>[];
   final fixFolders = <Folder>[];
   final fixFiles = <File>[];
 
@@ -78,6 +79,11 @@
               contextManager.isInAnalysisRoot(filePath))) {
         return new Response.fileNotAnalyzed(request, filePath);
       }
+      var pkgFolder =
+          findPkgFolder(contextManager.getContextFolderFor(filePath));
+      if (pkgFolder != null && !pkgFolders.contains(pkgFolder)) {
+        pkgFolders.add(pkgFolder);
+      }
       if (res is Folder) {
         fixFolders.add(res);
       } else {
@@ -85,6 +91,11 @@
       }
     }
 
+    // Process each package
+    for (Folder pkgFolder in pkgFolders) {
+      await processPackage(pkgFolder);
+    }
+
     // Process each source file.
     bool hasErrors = false;
     String changedPath;
@@ -135,6 +146,17 @@
     ).toResponse(request.id);
   }
 
+  Folder findPkgFolder(Folder folder) {
+    while (folder != null) {
+      if (folder.getChild('analysis_options.yaml').exists ||
+          folder.getChild('pubspec.yaml').exists) {
+        return folder;
+      }
+      folder = folder.parent;
+    }
+    return null;
+  }
+
   /// Return `true` if the path in within the set of `included` files
   /// or is within an `included` directory.
   bool isIncluded(String filePath) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 6b7a5a9..12a1d18 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -22,6 +22,7 @@
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analysis_server/src/services/correction/organize_directives.dart';
 import 'package:analysis_server/src/services/correction/sort_members.dart';
@@ -33,16 +34,23 @@
 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/file_system/file_system.dart';
+// ignore: deprecated_member_use
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
 import 'package:analyzer/src/error/codes.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart' as engine;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:dart_style/dart_style.dart';
+import 'package:yaml/yaml.dart';
 
 int test_resetCount = 0;
 
@@ -231,9 +239,7 @@
       new EditGetDartfixInfoResult(allFixes.map((i) => i.asDartFix()).toList())
           .toResponse(request.id);
 
-  Future getFixes(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+  Future<void> getFixes(Request request) async {
     EditGetFixesParams params = new EditGetFixesParams.fromRequest(request);
     String file = params.file;
     int offset = params.offset;
@@ -241,7 +247,6 @@
     if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
-
     //
     // Allow plugins to start computing fixes.
     //
@@ -569,12 +574,49 @@
   }
 
   /**
-   * Compute and return the fixes associated with server-generated errors.
+   * Compute and return the fixes associated with server-generated errors in
+   * analysis options files.
    */
-  Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
+  Future<List<AnalysisErrorFixes>> _computeAnalysisOptionsFixes(
       String file, int offset) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+    List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
+    File optionsFile = server.resourceProvider.getFile(file);
+    String content = _safelyRead(optionsFile);
+    if (content == null) {
+      return errorFixesList;
+    }
+    LineInfo lineInfo = new LineInfo.fromContent(content);
+    SourceFactory sourceFactory = server.getAnalysisDriver(file).sourceFactory;
+    List<engine.AnalysisError> errors = analyzeAnalysisOptions(
+        optionsFile.createSource(), content, sourceFactory);
+    YamlMap options = _getOptions(sourceFactory, content);
+    if (options == null) {
+      return errorFixesList;
+    }
+    for (engine.AnalysisError error in errors) {
+      AnalysisOptionsFixGenerator generator =
+          new AnalysisOptionsFixGenerator(error, content, options);
+      List<Fix> fixes = await generator.computeFixes();
+      if (fixes.isNotEmpty) {
+        fixes.sort(Fix.SORT_BY_RELEVANCE);
+        AnalysisError serverError =
+            newAnalysisError_fromEngine(lineInfo, error);
+        AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
+        errorFixesList.add(errorFixes);
+        fixes.forEach((fix) {
+          errorFixes.fixes.add(fix.change);
+        });
+      }
+    }
+    return errorFixesList;
+  }
+
+  /**
+   * Compute and return the fixes associated with server-generated errors in
+   * Dart files.
+   */
+  Future<List<AnalysisErrorFixes>> _computeDartFixes(
+      String file, int offset) async {
     List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
     var result = await server.getResolvedUnit(file);
     if (result != null) {
@@ -603,6 +645,20 @@
     return errorFixesList;
   }
 
+  /**
+   * Compute and return the fixes associated with server-generated errors.
+   */
+  Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
+      String file, int offset) async {
+    if (AnalysisEngine.isDartFileName(file)) {
+      return _computeDartFixes(file, offset);
+    } else if (AnalysisEngine.isAnalysisOptionsFileName(
+        file, server.resourceProvider.pathContext)) {
+      return _computeAnalysisOptionsFixes(file, offset);
+    }
+    return <AnalysisErrorFixes>[];
+  }
+
   Response _getAvailableRefactorings(Request request) {
     _getAvailableRefactoringsImpl(request);
     return Response.DELAYED_RESPONSE;
@@ -676,6 +732,16 @@
     server.sendResponse(result.toResponse(request.id));
   }
 
+  YamlMap _getOptions(SourceFactory sourceFactory, String content) {
+    AnalysisOptionsProvider optionsProvider =
+        new AnalysisOptionsProvider(sourceFactory);
+    try {
+      return optionsProvider.getOptionsFromString(content);
+    } on OptionsFormatException {
+      return null;
+    }
+  }
+
   Response _getRefactoring(Request request) {
     if (refactoringManager.hasPendingRequest) {
       refactoringManager.cancel();
@@ -692,6 +758,16 @@
     refactoringManager = new _RefactoringManager(server, refactoringWorkspace);
   }
 
+  /// Return the contents of the [file], or `null` if the file does not exist or
+  /// cannot be read.
+  String _safelyRead(File file) {
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      return null;
+    }
+  }
+
   static int _getNumberOfScanParseErrors(List<engine.AnalysisError> errors) {
     int numScanParseErrors = 0;
     for (engine.AnalysisError error in errors) {
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 3e6c9c8..728bb580 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -8,8 +8,11 @@
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
 import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart';
 import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart';
 import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_spread_collections_fix.dart';
 
 const allFixes = <DartFixInfo>[
   //
@@ -33,22 +36,40 @@
   const DartFixInfo(
     'double-to-int',
     'Find double literals ending in .0 and remove the .0\n'
-        'wherever double context can be inferred.',
+    'wherever double context can be inferred.',
     PreferIntLiteralsFix.task,
   ),
   //
-  // Expermimental fixes
+  // Experimental fixes
   //
   const DartFixInfo(
     'non-nullable',
     // TODO(danrubel) update description and make default/required
     // when NNBD fix is ready
     'Experimental: Update sources to be non-nullable by default.\n'
-        'Requires the experimental non-nullable flag to be enabled.\n'
-        'This is not applied unless explicitly included.',
+    'Requires the experimental non-nullable flag to be enabled.\n'
+    'This is not applied unless explicitly included.',
     NonNullableFix.task,
     isDefault: false,
   ),
+  const DartFixInfo(
+    'use-spread-collections',
+    'Convert to using collection spread operators.',
+    PreferSpreadCollectionsFix.task,
+    isDefault: false,
+  ),
+  const DartFixInfo(
+    'collection-if-elements',
+    'Convert to using if elements when building collections.',
+    PreferIfElementsToConditionalExpressionsFix.task,
+    isDefault: false,
+  ),
+  const DartFixInfo(
+    'map-for-elements',
+    'Convert to for elements when building maps from iterables.',
+    PreferForElementsToMapFromIterableFix.task,
+    isDefault: false,
+  ),
 ];
 
 /// [DartFixInfo] represents a fix that can be applied by [EditDartFix].
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
index eaa28ad..e4f0b2e 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -6,12 +6,17 @@
 
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
 
 /// A general task for performing a fix.
 abstract class FixCodeTask {
   /// Number of times [processUnit] should be called for each compilation unit.
   int get numPhases;
 
+  /// [processPackage] is called once for each package
+  /// before [processUnit] is called for any compilation unit in any package.
+  Future<void> processPackage(Folder pkgFolder);
+
   /// [processUnit] is called for each phase and compilation unit.
   ///
   /// First [processUnit] will be called once for each compilation unit with
@@ -44,6 +49,12 @@
     }
   }
 
+  void processPackage(Folder pkgFolder) async {
+    for (FixCodeTask task in _codeTasks) {
+      await task.processPackage(pkgFolder);
+    }
+  }
+
   void registerCodeTask(FixCodeTask task) {
     _codeTasks.add(task);
     _numPhases = max(_numPhases, task.numPhases);
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 bc5b11b..61d3984 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
@@ -7,7 +7,12 @@
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
 import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:yaml/yaml.dart';
+import 'package:source_span/source_span.dart';
 
 /// [NonNullableFix] visits each named type in a resolved compilation unit
 /// and determines whether the associated variable or parameter can be null
@@ -21,6 +26,11 @@
 
   final NullabilityMigration migration;
 
+  /// If this flag has a value of `false`, then something happened to prevent
+  /// at least one package from being marked as non-nullable.
+  /// If this occurs, then don't update any code.
+  bool _packageIsNNBD = true;
+
   NonNullableFix(this.listener)
       : migration = new NullabilityMigration(
             new NullabilityMigrationAdapter(listener),
@@ -34,8 +44,123 @@
     migration.finish();
   }
 
+  /// If the package contains an analysis_options.yaml file, then update the
+  /// file to enabled NNBD. If that file does not exist, but the package
+  /// contains a pubspec.yaml, then create the analysis_options.yaml file.
+  @override
+  Future<void> processPackage(Folder pkgFolder) async {
+    if (!_packageIsNNBD) {
+      return;
+    }
+
+    // TODO(danrubel): Update pubspec.yaml to enable NNBD
+
+    File optionsFile = pkgFolder.getChildAssumingFile('analysis_options.yaml');
+    String optionsContent;
+    YamlNode optionsMap;
+    if (optionsFile.exists) {
+      try {
+        optionsContent = optionsFile.readAsStringSync();
+      } on FileSystemException catch (e) {
+        processYamlException('read', optionsFile.path, e);
+        return;
+      }
+      try {
+        optionsMap = loadYaml(optionsContent);
+      } on YamlException catch (e) {
+        processYamlException('parse', optionsFile.path, e);
+        return;
+      }
+    }
+
+    SourceSpan parentSpan;
+    String content;
+    YamlNode analyzerOptions;
+    if (optionsMap is YamlMap) {
+      analyzerOptions = optionsMap.nodes[AnalyzerOptions.analyzer];
+    }
+    if (analyzerOptions == null) {
+      var start = new SourceLocation(0, line: 0, column: 0);
+      parentSpan = new SourceSpan(start, start, '');
+      content = '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+
+''';
+    } else if (analyzerOptions is YamlMap) {
+      YamlNode experiments =
+          analyzerOptions.nodes[AnalyzerOptions.enableExperiment];
+      if (experiments == null) {
+        parentSpan = analyzerOptions.span;
+        content = '''
+
+  enable-experiment:
+    - non-nullable''';
+      } else if (experiments is YamlList) {
+        experiments.nodes.firstWhere(
+          (node) => node.span.text == EnableString.non_nullable,
+          orElse: () {
+            parentSpan = experiments.span;
+            content = '''
+
+    - non-nullable''';
+          },
+        );
+      }
+    }
+
+    if (parentSpan != null) {
+      final space = ' '.codeUnitAt(0);
+      final cr = '\r'.codeUnitAt(0);
+      final lf = '\n'.codeUnitAt(0);
+
+      int line = parentSpan.end.line;
+      int offset = parentSpan.end.offset;
+      while (offset > 0) {
+        int ch = optionsContent.codeUnitAt(offset - 1);
+        if (ch == space || ch == cr) {
+          --offset;
+        } else if (ch == lf) {
+          --offset;
+          --line;
+        } else {
+          break;
+        }
+      }
+      listener.addSourceFileEdit(
+          'enable non-nullable analysis',
+          new Location(
+            optionsFile.path,
+            offset,
+            content.length,
+            line,
+            0,
+          ),
+          new SourceFileEdit(optionsFile.path, 0,
+              edits: [new SourceEdit(offset, 0, content)]));
+    }
+  }
+
+  void processYamlException(String action, String optionsFilePath, error) {
+    listener.addRecommendation('''Failed to $action options file
+  $optionsFilePath
+  $error
+
+  Manually update this file to enable non-nullable by adding:
+
+    analyzer:
+      enable-experiment:
+        - non-nullable
+''');
+    _packageIsNNBD = false;
+  }
+
   @override
   Future<void> processUnit(int phase, ResolvedUnitResult result) async {
+    if (!_packageIsNNBD) {
+      return;
+    }
     switch (phase) {
       case 0:
         migration.prepareInput(result);
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart
new file mode 100644
index 0000000..84ecff9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart
@@ -0,0 +1,69 @@
+// 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/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/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferForElementsToMapFromIterableFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferForElementsToMapFromIterableFix(DartFixListener listener)
+      : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            node.length),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_FOR_ELEMENT);
+
+      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 {
+        listener.addRecommendation(
+            'Convert to for elements assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_for_elements_to_map_fromIterable'],
+      new PreferForElementsToMapFromIterableFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart
new file mode 100644
index 0000000..0dbdf26
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart
@@ -0,0 +1,69 @@
+// 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/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/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferIfElementsToConditionalExpressionsFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferIfElementsToConditionalExpressionsFix(DartFixListener listener)
+      : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            node.length),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_IF_ELEMENT);
+
+      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 {
+        listener.addRecommendation(
+            'Convert to if elements assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_if_elements_to_conditional_expressions'],
+      new PreferIfElementsToConditionalExpressionsFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart
new file mode 100644
index 0000000..caff2e6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart
@@ -0,0 +1,68 @@
+// 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/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/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferSpreadCollectionsFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferSpreadCollectionsFix(DartFixListener listener) : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            0),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_SPREAD);
+
+      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 {
+        listener.addRecommendation(
+            'Convert to spread assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_spread_collections'],
+      new PreferSpreadCollectionsFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart b/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
index 4b47370..3e09ed4 100644
--- a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
+++ b/pkg/analysis_server/lib/src/nullability/conditional_discard.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:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 
 /// Container for information gathered during nullability migration about a
@@ -11,15 +12,21 @@
 /// whose boolean value influences control flow (e.g. the condition of an `if`
 /// statement).
 class ConditionalDiscard {
-  /// Constraint variable whose value will be `true` if the code path that
-  /// results from the condition evaluating to `true` will be reachable after
+  /// Nullability node that will be `nullable` if the code path that results
+  /// from the condition evaluating to `true` will be reachable after
   /// nullability migration, and therefore should be kept.
-  final ConstraintVariable keepTrue;
+  ///
+  /// `null` if the code path should be kept regardless of the outcome of
+  /// migration.
+  final NullabilityNode trueGuard;
 
-  /// Constraint variable whose value will be `false` if the code path that
-  /// results from the condition evaluating to `false` will be reachable after
+  /// Nullability node that will be `nullable` if the code path that results
+  /// from the condition evaluating to `false` will be reachable after
   /// nullability migration, and therefore should be kept.
-  final ConstraintVariable keepFalse;
+  ///
+  /// `null` if the code path should be kept regardless of the outcome of
+  /// migration.
+  final NullabilityNode falseGuard;
 
   /// Indicates whether the condition is pure (free from side effects).
   ///
@@ -27,11 +34,19 @@
   /// variable or static variable), because evaluating it has no user-visible
   /// effect other than returning a boolean value.
   ///
-  /// If [pureCondition] is `false`, and either [keepTrue] or [keepFalse] is
+  /// If [pureCondition] is `false`, and either [trueGuard] or [falseGuard] is
   /// `false`, that it is safe to delete the condition expression as well as the
   /// dead code branch (e.g. it means that `if (x == null) f(); else g();` could
   /// be changed to simply `g();`).
   final bool pureCondition;
 
-  ConditionalDiscard(this.keepTrue, this.keepFalse, this.pureCondition);
+  ConditionalDiscard(this.trueGuard, this.falseGuard, this.pureCondition);
+
+  /// Indicates whether the code path that results from the condition evaluating
+  /// to `false` is reachable after migration.
+  bool get keepFalse => falseGuard == null || falseGuard.isNullable;
+
+  /// Indicates whether the code path that results from the condition evaluating
+  /// to `true` is reachable after migration.
+  bool get keepTrue => trueGuard == null || trueGuard.isNullable;
 }
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
index d0802ad..a723c9a 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -63,13 +64,13 @@
   /// boolean value could possibly affect nullability analysis.
   _ConditionInfo _conditionInfo;
 
-  /// The set of constraint variables that would have to be assigned the value
-  /// of `true` for the code currently being visited to be reachable.
+  /// The set of nullability nodes that would have to be `nullable` for the code
+  /// currently being visited to be reachable.
   ///
   /// Guard variables are attached to the left hand side of any generated
   /// constraints, so that constraints do not take effect if they come from
   /// code that can be proven unreachable by the migration tool.
-  final _guards = <ConstraintVariable>[];
+  final _guards = <NullabilityNode>[];
 
   /// Indicates whether the statement or expression being visited is within
   /// conditional control flow.  If `true`, this means that the enclosing
@@ -79,11 +80,14 @@
 
   ConstraintGatherer(TypeProvider typeProvider, this._variables,
       this._constraints, this._source, this._permissive, this.assumptions)
-      : _notNullType = DecoratedType(typeProvider.objectType, null),
-        _nonNullableBoolType = DecoratedType(typeProvider.boolType, null),
-        _nonNullableTypeType = DecoratedType(typeProvider.typeType, null),
+      : _notNullType =
+            DecoratedType(typeProvider.objectType, NullabilityNode.never),
+        _nonNullableBoolType =
+            DecoratedType(typeProvider.boolType, NullabilityNode.never),
+        _nonNullableTypeType =
+            DecoratedType(typeProvider.typeType, NullabilityNode.never),
         _nullType =
-            DecoratedType(typeProvider.nullType, ConstraintVariable.always);
+            DecoratedType(typeProvider.nullType, NullabilityNode.always);
 
   /// Gets the decorated type of [element] from [_variables], performing any
   /// necessary substitutions.
@@ -132,7 +136,8 @@
     if (identical(_conditionInfo?.condition, node.condition)) {
       if (!_inConditionalControlFlow &&
           _conditionInfo.trueDemonstratesNonNullIntent != null) {
-        _recordFact(_conditionInfo.trueDemonstratesNonNullIntent);
+        _conditionInfo.trueDemonstratesNonNullIntent
+            ?.recordNonNullIntent(_constraints, _guards);
       }
     }
     node.message?.accept(this);
@@ -154,8 +159,8 @@
           bool isPure = node.leftOperand is SimpleIdentifier;
           var conditionInfo = _ConditionInfo(node,
               isPure: isPure,
-              trueGuard: leftType.nullable,
-              falseDemonstratesNonNullIntent: leftType.nonNullIntent);
+              trueGuard: leftType.node,
+              falseDemonstratesNonNullIntent: leftType.node);
           _conditionInfo = node.operator.type == TokenType.EQ_EQ
               ? conditionInfo
               : conditionInfo.not(node);
@@ -182,7 +187,7 @@
 
   @override
   DecoratedType visitBooleanLiteral(BooleanLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
@@ -199,8 +204,10 @@
     assert(_isSimple(thenType)); // TODO(paulberry)
     var elseType = node.elseExpression.accept(this);
     assert(_isSimple(elseType)); // TODO(paulberry)
-    var overallType = DecoratedType(node.staticType,
-        _joinNullabilities(node, thenType.nullable, elseType.nullable));
+    var overallType = DecoratedType(
+        node.staticType,
+        NullabilityNode.forConditionalexpression(
+            node, thenType.node, elseType.node, _joinNullabilities));
     _variables.recordDecoratedExpressionType(node, overallType);
     return overallType;
   }
@@ -215,7 +222,13 @@
       } else if (node.declaredElement.isOptionalPositional ||
           assumptions.namedNoDefaultParameterHeuristic ==
               NamedNoDefaultParameterHeuristic.assumeNullable) {
-        _recordFact(getOrComputeElementType(node.declaredElement).nullable);
+        NullabilityNode.recordAssignment(
+            NullabilityNode.always,
+            getOrComputeElementType(node.declaredElement).node,
+            null,
+            _guards,
+            _constraints,
+            false);
       } else {
         assert(assumptions.namedNoDefaultParameterHeuristic ==
             NamedNoDefaultParameterHeuristic.assumeRequired);
@@ -255,16 +268,13 @@
     // treated like an implicit `assert(b != null)`?  Probably.
     _handleAssignment(_notNullType, node.condition);
     _inConditionalControlFlow = true;
-    ConstraintVariable trueGuard;
-    ConstraintVariable falseGuard;
+    NullabilityNode trueGuard;
+    NullabilityNode falseGuard;
     if (identical(_conditionInfo?.condition, node.condition)) {
       trueGuard = _conditionInfo.trueGuard;
       falseGuard = _conditionInfo.falseGuard;
-      _variables.recordConditionalDiscard(
-          _source,
-          node,
-          ConditionalDiscard(trueGuard ?? ConstraintVariable.always,
-              falseGuard ?? ConstraintVariable.always, _conditionInfo.isPure));
+      _variables.recordConditionalDiscard(_source, node,
+          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
     }
     if (trueGuard != null) {
       _guards.add(trueGuard);
@@ -291,7 +301,7 @@
 
   @override
   DecoratedType visitIntegerLiteral(IntegerLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
@@ -337,10 +347,9 @@
       }
     }
     // Any parameters not supplied must be optional.
-    for (var entry in calleeType.namedParameterOptionalVariables.entries) {
-      assert(entry.value != null);
+    for (var entry in calleeType.namedParameters.entries) {
       if (suppliedNamedParameters.contains(entry.key)) continue;
-      _recordFact(entry.value);
+      entry.value.node.recordNamedParameterNotSupplied(_constraints, _guards);
     }
     return calleeType.returnType;
   }
@@ -393,24 +402,24 @@
 
   @override
   DecoratedType visitStringLiteral(StringLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitThrowExpression(ThrowExpression node) {
     node.expression.accept(this);
     // TODO(paulberry): do we need to check the expression type?  I think not.
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitTypeName(TypeName typeName) {
-    return DecoratedType(typeName.type, null);
+    return DecoratedType(typeName.type, NullabilityNode.never);
   }
 
   /// Creates the necessary constraint(s) for an assignment from [sourceType] to
@@ -419,40 +428,14 @@
   /// where a nullable source is assigned to a non-nullable destination.
   void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
       Expression expression) {
-    if (sourceType.nullable != null) {
-      _guards.add(sourceType.nullable);
-      var destinationNonNullIntent = destinationType.nonNullIntent;
-      try {
-        CheckExpression checkNotNull;
-        if (expression != null) {
-          checkNotNull = CheckExpression(expression);
-          _variables.recordExpressionChecks(
-              _source, expression, ExpressionChecks(checkNotNull));
-        }
-        // nullable_src => nullable_dst | check_expr
-        _recordFact(ConstraintVariable.or(
-            _constraints, destinationType.nullable, checkNotNull));
-        if (checkNotNull != null) {
-          // nullable_src & nonNullIntent_dst => check_expr
-          if (destinationNonNullIntent != null) {
-            _recordConstraint(destinationNonNullIntent, checkNotNull);
-          }
-        }
-      } finally {
-        _guards.removeLast();
-      }
-      var sourceNonNullIntent = sourceType.nonNullIntent;
-      if (!_inConditionalControlFlow && sourceNonNullIntent != null) {
-        if (destinationType.nullable == null) {
-          // The destination type can never be nullable so this demonstrates
-          // non-null intent.
-          _recordFact(sourceNonNullIntent);
-        } else if (destinationNonNullIntent != null) {
-          // Propagate non-null intent from the destination to the source.
-          _recordConstraint(destinationNonNullIntent, sourceNonNullIntent);
-        }
-      }
+    CheckExpression checkNotNull;
+    if (expression != null) {
+      checkNotNull = CheckExpression(expression);
+      _variables.recordExpressionChecks(
+          _source, expression, ExpressionChecks(checkNotNull));
     }
+    NullabilityNode.recordAssignment(sourceType.node, destinationType.node,
+        checkNotNull, _guards, _constraints, _inConditionalControlFlow);
     // TODO(paulberry): it's a cheat to pass in expression=null for the
     // recursive checks.  Really we want to unify all the checks in a single
     // ExpressionChecks object.
@@ -524,31 +507,11 @@
       return ConstraintVariable.always;
     }
     var result = TypeIsNullable(node.offset);
-    _recordConstraint(a, result);
-    _recordConstraint(b, result);
-    _recordConstraint(result, ConstraintVariable.or(_constraints, a, b));
+    _constraints.record([a], result);
+    _constraints.record([b], result);
+    _constraints.record([result], ConstraintVariable.or(_constraints, a, b));
     return result;
   }
-
-  /// Records a constraint having [condition] as its left hand side and
-  /// [consequence] as its right hand side.  Any [_guards] are included in the
-  /// left hand side.
-  void _recordConstraint(
-      ConstraintVariable condition, ConstraintVariable consequence) {
-    _guards.add(condition);
-    try {
-      _recordFact(consequence);
-    } finally {
-      _guards.removeLast();
-    }
-  }
-
-  /// Records a constraint having [consequence] as its right hand side.  Any
-  /// [_guards] are used as the right hand side.
-  void _recordFact(ConstraintVariable consequence) {
-    assert(consequence != null);
-    _constraints.record(_guards, consequence);
-  }
 }
 
 /// Information about a binary expression whose boolean value could possibly
@@ -564,21 +527,21 @@
   /// effect other than returning a boolean value.
   final bool isPure;
 
-  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
   /// order for [condition] to evaluate to `true`.
-  final ConstraintVariable trueGuard;
+  final NullabilityNode trueGuard;
 
-  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
   /// order for [condition] to evaluate to `false`.
-  final ConstraintVariable falseGuard;
+  final NullabilityNode falseGuard;
 
-  /// If not `null`, the [ConstraintVariable] whose value should be set to
-  /// `true` if [condition] is asserted to be `true`.
-  final ConstraintVariable trueDemonstratesNonNullIntent;
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  //  /// non-null intent if [condition] is asserted to be `true`.
+  final NullabilityNode trueDemonstratesNonNullIntent;
 
-  /// If not `null`, the [ConstraintVariable] whose value should be set to
-  /// `true` if [condition] is asserted to be `false`.
-  final ConstraintVariable falseDemonstratesNonNullIntent;
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  /// non-null intent if [condition] is asserted to be `false`.
+  final NullabilityNode falseDemonstratesNonNullIntent;
 
   _ConditionInfo(this.condition,
       {@required this.isPure,
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
index f917e72..8f5f170 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/nullability/conditional_discard.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -50,28 +51,19 @@
         // TODO(danrubel): Return something other than this
         // to indicate that we should insert a type for the declaration
         // that is missing a type reference.
-        ? new DecoratedType(DynamicTypeImpl.instance, ConstraintVariable.always)
+        ? new DecoratedType(
+            DynamicTypeImpl.instance, NullabilityNode.forInferredDynamicType())
         : type.accept(this);
   }
 
   @override
   DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
     var decoratedType = node.parameter.accept(this);
-    ConstraintVariable optional;
-    if (node.declaredElement.hasRequired) {
-      optional = null;
-    } else if (node.defaultValue != null) {
-      optional = ConstraintVariable.always;
-    } else {
-      optional = decoratedType.nullable;
-      _variables.recordPossiblyOptional(_source, node, optional);
+    if (node.declaredElement.hasRequired || node.defaultValue != null) {
+      return null;
     }
-    if (optional != null) {
-      _currentFunctionType
-              .namedParameterOptionalVariables[node.declaredElement.name] =
-          optional;
-    }
-    return null;
+    decoratedType.node.trackPossiblyOptional();
+    _variables.recordPossiblyOptional(_source, node, decoratedType.node);
   }
 
   @override
@@ -117,8 +109,7 @@
   DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
     var type = decorateType(node.type);
     var declaredElement = node.declaredElement;
-    assert(type.nonNullIntent == null);
-    type.nonNullIntent = NonNullIntent(node.offset);
+    type.node.trackNonNullIntent(node.offset);
     _variables.recordDecoratedElementType(declaredElement, type);
     if (declaredElement.isNamed) {
       _currentFunctionType.namedParameters[declaredElement.name] = type;
@@ -133,7 +124,10 @@
     assert(node != null); // TODO(paulberry)
     assert(node is NamedType); // TODO(paulberry)
     var type = node.type;
-    if (type.isVoid) return DecoratedType(type, ConstraintVariable.always);
+    if (type.isVoid) {
+      return DecoratedType(
+          type, NullabilityNode.forTypeAnnotation(node.end, always: true));
+    }
     assert(
         type is InterfaceType || type is TypeParameterType); // TODO(paulberry)
     var typeArguments = const <DecoratedType>[];
@@ -146,10 +140,11 @@
         assert(false); // TODO(paulberry): is this possible?
       }
     }
-    var nullable = node.question == null
-        ? TypeIsNullable(node.end)
-        : ConstraintVariable.always;
-    var decoratedType = DecoratedTypeAnnotation(type, nullable, node.end,
+    var decoratedType = DecoratedTypeAnnotation(
+        type,
+        NullabilityNode.forTypeAnnotation(node.end,
+            always: node.question != null),
+        node.end,
         typeArguments: typeArguments);
     _variables.recordDecoratedTypeAnnotation(_source, node, decoratedType);
     return decoratedType;
@@ -165,11 +160,11 @@
     var previousFunctionType = _currentFunctionType;
     // TODO(paulberry): test that it's correct to use `null` for the nullability
     // of the function type
-    var functionType = DecoratedType(declaredElement.type, null,
+    var functionType = DecoratedType(
+        declaredElement.type, NullabilityNode.never,
         returnType: decoratedReturnType,
         positionalParameters: [],
-        namedParameters: {},
-        namedParameterOptionalVariables: {});
+        namedParameters: {});
     _currentFunctionType = functionType;
     try {
       parameters.accept(this);
@@ -194,11 +189,11 @@
   void recordDecoratedTypeAnnotation(
       Source source, TypeAnnotation node, DecoratedTypeAnnotation type);
 
-  /// Associates a constraint variable with the question of whether the given
-  /// named parameter should be optional (should not have a `required`
+  /// Records that [node] is associated with the question of whether the named
+  /// [parameter] should be optional (should not have a `required`
   /// annotation added to it).
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable);
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node);
 }
 
 /// Repository of constraint variables and decorated types corresponding to the
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
index 2dde11f..41fef69 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type.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:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -15,18 +16,7 @@
 class DecoratedType {
   final DartType type;
 
-  /// [ConstraintVariable] whose value will be set to `true` if this type needs
-  /// to be nullable.
-  ///
-  /// If `null`, that means that an external constraint (outside the code being
-  /// migrated) forces this type to be non-nullable.
-  final ConstraintVariable nullable;
-
-  /// [ConstraintVariable] whose value will be set to `true` if the usage of
-  /// this type suggests that it is intended to be non-null (because of the
-  /// presence of a statement or expression that would unconditionally lead to
-  /// an exception being thrown in the case of a `null` value at runtime).
-  ConstraintVariable nonNullIntent;
+  final NullabilityNode node;
 
   /// If `this` is a function type, the [DecoratedType] of its return type.
   final DecoratedType returnType;
@@ -40,31 +30,21 @@
   /// parameters.
   final Map<String, DecoratedType> namedParameters;
 
-  /// If `this` is a function type, [ConstraintVariable] for each of its named
-  /// parameters indicating whether the given named parameter needs to be
-  /// optional (no `required` annotation).
-  ///
-  /// If there is no entry in this map corresponding to a given named parameter,
-  /// that means that it has already been decided (prior to migration) that the
-  /// given named parameter is required.  TODO(paulberry): test that this works
-  /// for already-migrated code.
-  final Map<String, ConstraintVariable> namedParameterOptionalVariables;
-
   /// If `this` is a parameterized type, the [DecoratedType] of each of its
   /// type parameters.
   ///
   /// TODO(paulberry): how should we handle generic typedefs?
   final List<DecoratedType> typeArguments;
 
-  DecoratedType(this.type, this.nullable,
+  DecoratedType(this.type, this.node,
       {this.returnType,
       this.positionalParameters = const [],
       this.namedParameters = const {},
-      this.namedParameterOptionalVariables = const {},
       this.typeArguments = const []}) {
+    assert(node != null);
     // The type system doesn't have a non-nullable version of `dynamic`.  So if
     // the type is `dynamic`, verify that `nullable` is `always`.
-    assert(!type.isDynamic || identical(nullable, ConstraintVariable.always));
+    assert(!type.isDynamic || node.isAlwaysNullable);
   }
 
   /// Creates a [DecoratedType] corresponding to the given [element], which is
@@ -74,7 +54,7 @@
       assert((type as TypeImpl).nullability ==
           Nullability.indeterminate); // TODO(paulberry)
       if (type is FunctionType) {
-        var decoratedType = DecoratedType(type, null,
+        var decoratedType = DecoratedType(type, NullabilityNode.never,
             returnType: decorate(type.returnType), positionalParameters: []);
         for (var parameter in type.parameters) {
           assert(parameter.isPositional); // TODO(paulberry)
@@ -83,7 +63,7 @@
         return decoratedType;
       } else if (type is InterfaceType) {
         assert(type.typeParameters.isEmpty); // TODO(paulberry)
-        return DecoratedType(type, null);
+        return DecoratedType(type, NullabilityNode.never);
       } else {
         throw type.runtimeType; // TODO(paulberry)
       }
@@ -112,7 +92,7 @@
 
   @override
   String toString() {
-    var trailing = nullable == null ? '' : '?($nullable)';
+    var trailing = node.debugSuffix;
     var type = this.type;
     if (type is TypeParameterType || type is VoidType) {
       return '$type$trailing';
@@ -155,14 +135,14 @@
         newPositionalParameters.add(positionalParameters[i]
             ._substitute(constraints, substitution, undecoratedParameterType));
       }
-      return DecoratedType(undecoratedResult, nullable,
+      return DecoratedType(undecoratedResult, node,
           returnType: returnType._substitute(
               constraints, substitution, undecoratedResult.returnType),
           positionalParameters: newPositionalParameters);
     } else if (type is TypeParameterType) {
       var inner = substitution[type.element];
       return DecoratedType(undecoratedResult,
-          ConstraintVariable.or(constraints, inner?.nullable, nullable));
+          NullabilityNode.forSubstitution(constraints, inner?.node, node));
     } else if (type is VoidType) {
       return this;
     }
@@ -180,13 +160,12 @@
   final int _offset;
 
   DecoratedTypeAnnotation(
-      DartType type, ConstraintVariable nullable, this._offset,
+      DartType type, NullabilityNode nullabilityNode, this._offset,
       {List<DecoratedType> typeArguments = const []})
-      : super(type, nullable, typeArguments: typeArguments);
+      : super(type, nullabilityNode, typeArguments: typeArguments);
 
   @override
-  bool get isEmpty =>
-      identical(nullable, ConstraintVariable.always) || !nullable.value;
+  bool get isEmpty => node.isAlwaysNullable || !node.isNullable;
 
   @override
   Iterable<SourceEdit> get modifications =>
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
new file mode 100644
index 0000000..fd7d82b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
@@ -0,0 +1,201 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:meta/meta.dart';
+
+/// Representation of a single node in the nullability inference graph.
+///
+/// Initially, this is just a wrapper over constraint variables, and the
+/// nullability inference graph is encoded into the wrapped constraint
+/// variables.  Over time this will be replaced by a first class representation
+/// of the nullability inference graph.
+class NullabilityNode {
+  /// [NullabilityNode] used for types that are known a priori to be nullable
+  /// (e.g. the type of the `null` literal).
+  static final always = NullabilityNode._(ConstraintVariable.always);
+
+  /// [NullabilityNode] used for types that are known a priori to be
+  /// non-nullable (e.g. the type of an integer literal).
+  static final never = NullabilityNode._(null);
+
+  /// [ConstraintVariable] whose value will be set to `true` if this type needs
+  /// to be nullable.
+  ///
+  /// If `null`, that means that an external constraint (outside the code being
+  /// migrated) forces this type to be non-nullable.
+  final ConstraintVariable nullable;
+
+  ConstraintVariable _nonNullIntent;
+
+  bool _isPossiblyOptional = false;
+
+  /// Creates a [NullabilityNode] representing the nullability of a conditional
+  /// expression which is nullable iff both [a] and [b] are nullable.
+  ///
+  /// The constraint variable contained in the new node is created using the
+  /// [joinNullabilities] callback.  TODO(paulberry): this should become
+  /// unnecessary once constraint solving is performed directly using
+  /// [NullabilityNode] objects.
+  NullabilityNode.forConditionalexpression(
+      ConditionalExpression conditionalExpression,
+      NullabilityNode a,
+      NullabilityNode b,
+      ConstraintVariable Function(
+              ConditionalExpression, ConstraintVariable, ConstraintVariable)
+          joinNullabilities)
+      : this._(
+            joinNullabilities(conditionalExpression, a.nullable, b.nullable));
+
+  /// Creates a [NullabilityNode] representing the nullability of a variable
+  /// whose type is `dynamic` due to type inference.
+  ///
+  /// TODO(paulberry): this should go away; we should decorate the actual
+  /// inferred type rather than assuming `dynamic`.
+  NullabilityNode.forInferredDynamicType() : this._(ConstraintVariable.always);
+
+  /// Creates a [NullabilityNode] representing the nullability of a type
+  /// substitution where [outerNode] is the nullability node for the type
+  /// variable being eliminated by the substitution, and [innerNode] is the
+  /// nullability node for the type being substituted in its place.
+  ///
+  /// [innerNode] may be `null`.  TODO(paulberry): when?
+  ///
+  /// Additional constraints are recorded in [constraints] as necessary to make
+  /// the new nullability node behave consistently with the old nodes.
+  /// TODO(paulberry): this should become unnecessary once constraint solving is
+  /// performed directly using [NullabilityNode] objects.
+  NullabilityNode.forSubstitution(Constraints constraints,
+      NullabilityNode innerNode, NullabilityNode outerNode)
+      : this._(ConstraintVariable.or(
+            constraints, innerNode?.nullable, outerNode.nullable));
+
+  /// Creates a [NullabilityNode] representing the nullability of a type
+  /// annotation appearing explicitly in the user's program.
+  NullabilityNode.forTypeAnnotation(int endOffset, {@required bool always})
+      : this._(always ? ConstraintVariable.always : TypeIsNullable(endOffset));
+
+  NullabilityNode._(this.nullable);
+
+  /// Gets a string that can be appended to a type name during debugging to help
+  /// annotate the nullability of that type.
+  String get debugSuffix => nullable == null ? '' : '?($nullable)';
+
+  /// Indicates whether this node is always nullable, by construction.
+  bool get isAlwaysNullable => identical(nullable, ConstraintVariable.always);
+
+  /// After constraint solving, this getter can be used to query whether the
+  /// type associated with this node should be considered nullable.
+  bool get isNullable => nullable.value;
+
+  /// Indicates whether this node is associated with a named parameter for which
+  /// nullability migration needs to decide whether it is optional or required.
+  bool get isPossiblyOptional => _isPossiblyOptional;
+
+  /// [ConstraintVariable] whose value will be set to `true` if the usage of
+  /// this type suggests that it is intended to be non-null (because of the
+  /// presence of a statement or expression that would unconditionally lead to
+  /// an exception being thrown in the case of a `null` value at runtime).
+  ConstraintVariable get nonNullIntent => _nonNullIntent;
+
+  /// Records the fact that an invocation was made to a function with named
+  /// parameters, and the named parameter associated with this node was not
+  /// supplied.
+  void recordNamedParameterNotSupplied(
+      Constraints constraints, List<NullabilityNode> guards) {
+    if (isPossiblyOptional) {
+      _recordConstraints(constraints, guards, const [], nullable);
+    }
+  }
+
+  void recordNonNullIntent(
+      Constraints constraints, List<NullabilityNode> guards) {
+    _recordConstraints(constraints, guards, const [], nonNullIntent);
+  }
+
+  /// Tracks that the possibility that this nullability node might demonstrate
+  /// non-null intent, based on the fact that it corresponds to a formal
+  /// parameter declaration at location [offset].
+  ///
+  /// TODO(paulberry): consider eliminating this method altogether, and simply
+  /// allowing all nullability nodes to track non-null intent if necessary.
+  void trackNonNullIntent(int offset) {
+    assert(_nonNullIntent == null);
+    _nonNullIntent = NonNullIntent(offset);
+  }
+
+  /// Tracks the possibility that this node is associated with a named parameter
+  /// for which nullability migration needs to decide whether it is optional or
+  /// required.
+  void trackPossiblyOptional() {
+    _isPossiblyOptional = true;
+  }
+
+  /// Connect the nullability nodes [sourceNode] and [destinationNode]
+  /// appopriately to account for an assignment in the source code being
+  /// analyzed.  Any constraints generated are recorded in [constraints].
+  ///
+  /// If [checkNotNull] is non-null, then it tracks the expression that may
+  /// require null-checking.
+  ///
+  /// [inConditionalControlFlow] indicates whether the assignment being analyzed
+  /// is reachable conditionally or unconditionally from the entry point of the
+  /// function; this affects how non-null intent is back-propagated.
+  static void recordAssignment(
+      NullabilityNode sourceNode,
+      NullabilityNode destinationNode,
+      CheckExpression checkNotNull,
+      List<NullabilityNode> guards,
+      Constraints constraints,
+      bool inConditionalControlFlow) {
+    var additionalConditions = <ConstraintVariable>[];
+    if (sourceNode.nullable != null) {
+      additionalConditions.add(sourceNode.nullable);
+      var destinationNonNullIntent = destinationNode.nonNullIntent;
+      // nullable_src => nullable_dst | check_expr
+      _recordConstraints(
+          constraints,
+          guards,
+          additionalConditions,
+          ConstraintVariable.or(
+              constraints, destinationNode.nullable, checkNotNull));
+      if (checkNotNull != null) {
+        // nullable_src & nonNullIntent_dst => check_expr
+        if (destinationNonNullIntent != null) {
+          additionalConditions.add(destinationNonNullIntent);
+          _recordConstraints(
+              constraints, guards, additionalConditions, checkNotNull);
+        }
+      }
+      additionalConditions.clear();
+      var sourceNonNullIntent = sourceNode.nonNullIntent;
+      if (!inConditionalControlFlow && sourceNonNullIntent != null) {
+        if (destinationNode.nullable == null) {
+          // The destination type can never be nullable so this demonstrates
+          // non-null intent.
+          _recordConstraints(
+              constraints, guards, additionalConditions, sourceNonNullIntent);
+        } else if (destinationNonNullIntent != null) {
+          // Propagate non-null intent from the destination to the source.
+          additionalConditions.add(destinationNonNullIntent);
+          _recordConstraints(
+              constraints, guards, additionalConditions, sourceNonNullIntent);
+        }
+      }
+    }
+  }
+
+  static void _recordConstraints(
+      Constraints constraints,
+      List<NullabilityNode> guards,
+      List<ConstraintVariable> additionalConditions,
+      ConstraintVariable consequence) {
+    var conditions = guards.map((node) => node.nullable).toList();
+    conditions.addAll(additionalConditions);
+    constraints.record(conditions, consequence);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
index 3fa023b..99080c9 100644
--- a/pkg/analysis_server/lib/src/nullability/provisional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
@@ -18,6 +18,10 @@
 
 /// Kinds of fixes that might be performed by nullability migration.
 class NullabilityFixKind {
+  /// An import needs to be added.
+  static const addImport =
+      const NullabilityFixKind._(appliedMessage: 'Add an import');
+
   /// A formal parameter needs to have a required annotation added.
   static const addRequired =
       const NullabilityFixKind._(appliedMessage: 'Add a required annotation');
@@ -144,9 +148,11 @@
     } else if (potentialModification is analyzer.DecoratedTypeAnnotation) {
       kind = NullabilityFixKind.makeTypeNullable;
     } else if (potentialModification is analyzer.ConditionalModification) {
-      kind = potentialModification.discard.keepFalse.value
+      kind = potentialModification.discard.keepFalse
           ? NullabilityFixKind.discardThen
           : NullabilityFixKind.discardElse;
+    } else if (potentialModification is analyzer.PotentiallyAddImport) {
+      kind = NullabilityFixKind.addImport;
     } else if (potentialModification is analyzer.PotentiallyAddRequired) {
       kind = NullabilityFixKind.addRequired;
     } else {
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
index ff2a53f..7a1b505 100644
--- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -60,7 +61,7 @@
       this.discard, this.condition, this.thenStatement, this.elseStatement);
 
   @override
-  bool get isEmpty => discard.keepTrue.value && discard.keepFalse.value;
+  bool get isEmpty => discard.keepTrue && discard.keepFalse;
 
   @override
   Iterable<SourceEdit> get modifications {
@@ -72,10 +73,10 @@
     if (!discard.pureCondition) {
       keepNodes.add(condition); // TODO(paulberry): test
     }
-    if (discard.keepTrue.value) {
+    if (discard.keepTrue) {
       keepNodes.add(thenStatement); // TODO(paulberry): test
     }
-    if (discard.keepFalse.value) {
+    if (discard.keepFalse) {
       keepNodes.add(elseStatement); // TODO(paulberry): test
     }
     // TODO(paulberry): test thoroughly
@@ -196,19 +197,54 @@
           NamedNoDefaultParameterHeuristic.assumeNullable});
 }
 
+/// Records information about the possible addition of an import
+/// to the source code.
+class PotentiallyAddImport extends PotentialModification {
+  final _usages = <PotentialModification>[];
+
+  final int _offset;
+  final String _importPath;
+
+  PotentiallyAddImport(
+      AstNode beforeNode, this._importPath, PotentialModification usage)
+      : _offset = beforeNode.offset {
+    _usages.add(usage);
+  }
+
+  get importPath => _importPath;
+
+  @override
+  bool get isEmpty {
+    for (PotentialModification usage in _usages) {
+      if (!usage.isEmpty) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // TODO(danrubel): change all of dartfix NNBD to use DartChangeBuilder
+  @override
+  Iterable<SourceEdit> get modifications =>
+      isEmpty ? const [] : [SourceEdit(_offset, 0, "import '$_importPath';\n")];
+
+  void addUsage(PotentialModification usage) {
+    _usages.add(usage);
+  }
+}
+
 /// Records information about the possible addition of a `@required` annotation
 /// to the source code.
 class PotentiallyAddRequired extends PotentialModification {
-  final ConstraintVariable _optionalVariable;
+  final NullabilityNode _node;
 
   final int _offset;
 
-  PotentiallyAddRequired(
-      DefaultFormalParameter parameter, this._optionalVariable)
+  PotentiallyAddRequired(DefaultFormalParameter parameter, this._node)
       : _offset = parameter.offset;
 
   @override
-  bool get isEmpty => _optionalVariable.value;
+  bool get isEmpty => _node.isNullable;
 
   @override
   Iterable<SourceEdit> get modifications =>
@@ -264,10 +300,57 @@
   }
 
   @override
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable) {
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
+    var modification = PotentiallyAddRequired(parameter, node);
+    _addPotentialModification(source, modification);
+    _addPotentialImport(
+        source, parameter, modification, 'package:meta/meta.dart');
+  }
+
+  void _addPotentialImport(Source source, AstNode node,
+      PotentialModification usage, String importPath) {
+    // Get the compilation unit - assume not null
+    while (node is! CompilationUnit) {
+      node = node.parent;
+    }
+    var unit = node as CompilationUnit;
+
+    // Find an existing import
+    for (var directive in unit.directives) {
+      if (directive is ImportDirective) {
+        if (directive.uri.stringValue == importPath) {
+          return;
+        }
+      }
+    }
+
+    // Add the usage to an existing modification if possible
+    for (var modification in (_potentialModifications[source] ??= [])) {
+      if (modification is PotentiallyAddImport) {
+        if (modification.importPath == importPath) {
+          modification.addUsage(usage);
+          return;
+        }
+      }
+    }
+
+    // Create a new import modification
+    AstNode beforeNode;
+    for (var directive in unit.directives) {
+      if (directive is ImportDirective || directive is ExportDirective) {
+        beforeNode = directive;
+        break;
+      }
+    }
+    if (beforeNode == null) {
+      for (var declaration in unit.declarations) {
+        beforeNode = declaration;
+        break;
+      }
+    }
     _addPotentialModification(
-        source, PotentiallyAddRequired(parameter, variable));
+        source, PotentiallyAddImport(beforeNode, importPath, usage));
   }
 
   void _addPotentialModification(
diff --git a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
index 1add712..b587e33 100644
--- a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
+++ b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
@@ -66,7 +66,7 @@
 
   /// The value assigned to this constraint variable by the solution currently
   /// being computed.
-  get value => _value;
+  bool get value => _value;
 
   @override
   String toString() =>
diff --git a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
index 7da4335..693b94e 100644
--- a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
@@ -6,6 +6,8 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /// An object used to build the details for each token in the code being
 /// analyzed.
@@ -21,15 +23,29 @@
   void visitNode(AstNode node) {
     for (SyntacticEntity entity in node.childEntities) {
       if (entity is Token) {
-        _createDetails(entity, null);
+        _createDetails(entity, null, null);
       } else if (entity is SimpleIdentifier) {
+        String type = _getType(entity);
+        if (_isTypeName(entity)) {
+          type = 'dart:core;Type<$type>';
+        }
         List<String> kinds = [];
         if (entity.inDeclarationContext()) {
           kinds.add('declaration');
         } else {
-          kinds.add('identifier');
+          kinds.add('reference');
         }
-        _createDetails(entity.token, kinds);
+        _createDetails(entity.token, type, kinds);
+      } else if (entity is BooleanLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is DoubleLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is IntegerLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is SimpleStringLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is Comment) {
+        // Ignore comments and the references within them.
       } else if (entity is AstNode) {
         visitNode(entity);
       }
@@ -37,8 +53,68 @@
   }
 
   /// Create the details for a single [token], using the given list of [kinds].
-  void _createDetails(Token token, List<String> kinds) {
-    details.add(new TokenDetails(token.lexeme, token.type.name,
-        validElementKinds: kinds));
+  void _createDetails(Token token, String type, List<String> kinds) {
+    details.add(
+        new TokenDetails(token.lexeme, type: type, validElementKinds: kinds));
+  }
+
+  /// Return a unique identifier for the type of the given [expression].
+  String _getType(Expression expression) {
+    StringBuffer buffer = new StringBuffer();
+    _writeType(buffer, expression.staticType);
+    return buffer.toString();
+  }
+
+  /// Return `true` if the [identifier] represents the name of a type.
+  bool _isTypeName(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
+    if (parent is TypeName && identifier == parent.name) {
+      return true;
+    } else if (parent is PrefixedIdentifier &&
+        parent.identifier == identifier) {
+      AstNode parent2 = parent.parent;
+      if (parent2 is TypeName && parent == parent2.name) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return a unique identifier for the type of the given [expression].
+  void _writeType(StringBuffer buffer, DartType type) {
+    if (type == null) {
+      // This should never happen if the AST has been resolved.
+      buffer.write('dynamic');
+    } else if (type is FunctionType) {
+      _writeType(buffer, type.returnType);
+      buffer.write(' Function(');
+      bool first = true;
+      for (var parameter in type.parameters) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write(', ');
+        }
+        _writeType(buffer, parameter.type);
+      }
+      buffer.write(')');
+    } else if (type is InterfaceType) {
+      Element element = type.element;
+      if (element == null || element.isSynthetic) {
+        buffer.write(type.displayName);
+      } else {
+        String uri = element.library.source.uri.toString();
+        String name = element.name;
+        if (element is ClassMemberElement) {
+          String className = element.enclosingElement.name;
+          buffer.write('$uri;$className;$name');
+        } else {
+          buffer.write('$uri;$name');
+        }
+      }
+    } else {
+      // Handle `void` and `dynamic`.
+      buffer.write(type.displayName);
+    }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index bb459c1..5f64118 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -88,8 +88,16 @@
       'dart.assist.convert.toConstructorFieldParameter',
       30,
       "Convert to field formal parameter");
+  static const CONVERT_TO_FOR_ELEMENT = const AssistKind(
+      'dart.assist.convertToForElement', 30, "Convert to a 'for' element",
+      associatedErrorCodes: <String>[
+        'prefer_for_elements_to_map_fromIterable'
+      ]);
   static const CONVERT_TO_IF_ELEMENT = const AssistKind(
-      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element");
+      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element",
+      associatedErrorCodes: <String>[
+        'prefer_if_elements_to_conditional_expressions'
+      ]);
   static const CONVERT_TO_INT_LITERAL = const AssistKind(
       'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal",
       associatedErrorCodes: <String>['prefer_int_literals']);
@@ -122,7 +130,8 @@
       "Convert to single quoted string",
       associatedErrorCodes: <String>['prefer_single_quotes']);
   static const CONVERT_TO_SPREAD = const AssistKind(
-      'dart.assist.convertToSpread', 30, "Convert to a spread");
+      'dart.assist.convertToSpread', 30, "Convert to a spread",
+      associatedErrorCodes: <String>['spread_collections']);
   static const ENCAPSULATE_FIELD =
       const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
   static const EXCHANGE_OPERANDS =
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index b373465..64d8880 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -150,7 +150,7 @@
 
     if (experimentStatus.control_flow_collections) {
       await _addProposal_convertConditionalExpressionToIfElement();
-      await _addProposal_convertMapFromIterableToIfLiteral();
+      await _addProposal_convertMapFromIterableToForLiteral();
     }
     if (experimentStatus.spread_collections) {
       await _addProposal_convertAddAllToSpread();
@@ -169,6 +169,18 @@
       await _addProposal_convertClassToMixin();
     } else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) {
       await _addProposal_convertToIntLiteral();
+    } else if (assistKind == DartAssistKind.CONVERT_TO_SPREAD) {
+      if (experimentStatus.spread_collections) {
+        await _addProposal_convertAddAllToSpread();
+      }
+    } else if (assistKind == DartAssistKind.CONVERT_TO_FOR_ELEMENT) {
+      if (experimentStatus.control_flow_collections) {
+        await _addProposal_convertMapFromIterableToForLiteral();
+      }
+    } else if (assistKind == DartAssistKind.CONVERT_TO_IF_ELEMENT) {
+      if (experimentStatus.control_flow_collections) {
+        await _addProposal_convertConditionalExpressionToIfElement();
+      }
     }
     return assists;
   }
@@ -484,7 +496,13 @@
     elementText ??= '...${utils.getNodeText(argument)}';
     DartChangeBuilder changeBuilder = _newDartChangeBuilder();
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      // ['a']..addAll(['b', 'c']);
+      if (list.elements.isNotEmpty) {
+        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      } else {
+        //
+        builder.addSimpleInsertion(list.leftBracket.end, elementText);
+      } // []..addAll(['b', 'c']);
       builder.addDeletion(range.node(invocation));
     });
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SPREAD);
@@ -547,8 +565,8 @@
   }
 
   Future<void> _addProposal_convertConditionalExpressionToIfElement() async {
-    AstNode node = this.node;
-    if (node is! ConditionalExpression) {
+    AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
+    if (node == null) {
       _coverageMarker();
       return;
     }
@@ -923,7 +941,7 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_MAP_LITERAL);
   }
 
-  Future<void> _addProposal_convertMapFromIterableToIfLiteral() async {
+  Future<void> _addProposal_convertMapFromIterableToForLiteral() async {
     //
     // Ensure that the selection is inside an invocation of Map.fromIterable.
     //
@@ -1077,7 +1095,7 @@
         builder.write(' }');
       });
     });
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_FOR_ELEMENT);
   }
 
   Future<void> _addProposal_convertPartOfToUri() async {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b800b5d..3c54bcb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -11,9 +11,7 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
-/**
- * Return true if this [errorCode] is likely to have a fix associated with it.
- */
+/// Return true if this [errorCode] is likely to have a fix associated with it.
 bool hasFix(ErrorCode errorCode) =>
     errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN ||
     errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER ||
@@ -103,9 +101,14 @@
             errorCode.name == LintNames.unnecessary_this ||
             errorCode.name == LintNames.use_rethrow_when_possible));
 
-/**
- * The implementation of [DartFixContext].
- */
+/// An enumeration of quick fix kinds for the errors found in an analysis
+/// options file.
+class AnalysisOptionsFixKind {
+  static const REMOVE_SETTING =
+      const FixKind('REMOVE_SETTING', 50, "Remove '{0}'");
+}
+
+/// The implementation of [DartFixContext].
 class DartFixContextImpl implements DartFixContext {
   @override
   final ChangeWorkspace workspace;
@@ -119,9 +122,7 @@
   DartFixContextImpl(this.workspace, this.resolveResult, this.error);
 }
 
-/**
- * An enumeration of possible quick fix kinds.
- */
+/// An enumeration of quick fix kinds found in a Dart file.
 class DartFixKind {
   static const ADD_ASYNC =
       const FixKind('ADD_ASYNC', 50, "Add 'async' modifier");
@@ -304,6 +305,10 @@
       'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??=");
   static const REPLACE_WITH_IDENTIFIER =
       const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier");
+  static const REPLACE_WITH_IS_EMPTY =
+      const FixKind('REPLACE_WITH_IS_EMPTY', 50, "Replace with 'isEmpty'");
+  static const REPLACE_WITH_IS_NOT_EMPTY = const FixKind(
+      'REPLACE_WITH_IS_NOT_EMPTY', 50, "Replace with 'isNotEmpty'");
   static const REPLACE_WITH_NULL_AWARE = const FixKind(
       'REPLACE_WITH_NULL_AWARE',
       50,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
new file mode 100644
index 0000000..f558372
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -0,0 +1,238 @@
+// 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' as math;
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/analysis_options/error/option_codes.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show SourceChange;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:meta/meta.dart';
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
+
+/// The generator used to generate fixes in analysis options files.
+class AnalysisOptionsFixGenerator {
+  final AnalysisError error;
+
+  final int errorOffset;
+
+  final int errorLength;
+
+  final String content;
+
+  final YamlMap options;
+
+  final LineInfo lineInfo;
+
+  final List<Fix> fixes = <Fix>[];
+
+  List<YamlNode> coveringNodePath;
+
+  AnalysisOptionsFixGenerator(this.error, this.content, this.options)
+      : errorOffset = error.offset,
+        errorLength = error.length,
+        lineInfo = new LineInfo.fromContent(content);
+
+  /// Return the absolute, normalized path to the file in which the error was
+  /// reported.
+  String get file => error.source.fullName;
+
+  /// Return the list of fixes that apply to the error being fixed.
+  Future<List<Fix>> computeFixes() async {
+    YamlNodeLocator locator = new YamlNodeLocator(
+        start: errorOffset, end: errorOffset + errorLength - 1);
+    coveringNodePath = locator.searchWithin(options);
+    if (coveringNodePath.isEmpty) {
+      return fixes;
+    }
+
+    ErrorCode errorCode = error.errorCode;
+//    if (errorCode == AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR) {
+//    } else if (errorCode == AnalysisOptionsErrorCode.PARSE_ERROR) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED) {
+//    } else
+    if (errorCode == AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED) {
+      await _addFix_removeSetting();
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INVALID_OPTION) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.SPEC_MODE_REMOVED) {
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE) {
+    } else if (errorCode ==
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES) {
+      await _addFix_removeSetting();
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE) {
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.UNSUPPORTED_VALUE) {
+    }
+    return fixes;
+  }
+
+  void _addFix_removeSetting() async {
+    if (coveringNodePath[0] is YamlScalar) {
+      SourceRange deletionRange;
+      int index = 1;
+      while (index < coveringNodePath.length) {
+        YamlNode parent = coveringNodePath[index];
+        if (parent is YamlList) {
+          if (parent.nodes.length > 1) {
+            YamlNode nodeToDelete = coveringNodePath[index - 1];
+            deletionRange = _lines(
+                nodeToDelete.span.start.offset, nodeToDelete.span.end.offset);
+            break;
+          }
+        } else if (parent is YamlMap) {
+          Map<dynamic, YamlNode> nodes = parent.nodes;
+          if (nodes.length > 1) {
+            YamlNode key;
+            YamlNode value;
+            YamlNode child = coveringNodePath[index - 1];
+            if (nodes.containsKey(child)) {
+              key = child;
+              value = nodes[child];
+            } else if (nodes.containsValue(child)) {
+              for (var entry in nodes.entries) {
+                if (child == entry.value) {
+                  key = entry.key;
+                  value = child;
+                  break;
+                }
+              }
+            }
+            if (key == null || value == null) {
+              throw StateError(
+                  'Child is neither a key nor a value in the parent');
+            }
+            deletionRange = _lines(key.span.start.offset,
+                _firstNonWhitespaceBefore(value.span.end.offset));
+            break;
+          }
+        } else if (parent is YamlDocument) {
+          break;
+        }
+        index++;
+      }
+      YamlNode nodeToDelete = coveringNodePath[index - 1];
+      deletionRange ??=
+          _lines(nodeToDelete.span.start.offset, nodeToDelete.span.end.offset);
+      ChangeBuilder builder = new ChangeBuilder();
+      await builder.addFileEdit(file, (builder) {
+        builder.addDeletion(deletionRange);
+      });
+      _addFixFromBuilder(builder, AnalysisOptionsFixKind.REMOVE_SETTING,
+          args: [coveringNodePath[0].toString()]);
+    }
+  }
+
+  /// Add a fix whose edits were built by the [builder] that has the given
+  /// [kind]. If [args] are provided, they will be used to fill in the message
+  /// for the fix.
+  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
+      {List args: null}) {
+    SourceChange change = builder.sourceChange;
+    if (change.edits.isEmpty) {
+      return;
+    }
+    change.message = formatList(kind.message, args);
+    fixes.add(new Fix(kind, change));
+  }
+
+  int _firstNonWhitespaceBefore(int offset) {
+    while (offset > 0 && isWhitespace(content.codeUnitAt(offset - 1))) {
+      offset--;
+    }
+    return offset;
+  }
+
+  SourceRange _lines(int start, int end) {
+    CharacterLocation startLocation = lineInfo.getLocation(start);
+    int startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
+    CharacterLocation endLocation = lineInfo.getLocation(end);
+    int endOffset = lineInfo.getOffsetOfLine(
+        math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
+    return new SourceRange(startOffset, endOffset - startOffset);
+  }
+}
+
+/// An object used to locate the [YamlNode] associated with a source range.
+/// More specifically, it will return the deepest [YamlNode] which completely
+/// encompasses the specified range.
+class YamlNodeLocator {
+  /// The inclusive start offset of the range used to identify the node.
+  int _startOffset = 0;
+
+  /// The inclusive end offset of the range used to identify the node.
+  int _endOffset = 0;
+
+  /// Initialize a newly created locator to locate the deepest [YamlNode] for
+  /// which `node.offset <= [start]` and `[end] < node.end`.
+  ///
+  /// If the [end] offset is not provided, then it is considered the same as the
+  /// [start] offset.
+  YamlNodeLocator({@required int start, int end})
+      : this._startOffset = start,
+        this._endOffset = end ?? start;
+
+  /// Search within the given Yaml [node] and return the path to the most deeply
+  /// nested node that includes the whole target range, or an empty list if no
+  /// node was found. The path is represented by all of the elements from the
+  /// starting [node] to the most deeply nested node, in reverse order.
+  List<YamlNode> searchWithin(YamlNode node) {
+    List<YamlNode> path = [];
+    _searchWithin(path, node);
+    return path;
+  }
+
+  void _searchWithin(List<YamlNode> path, YamlNode node) {
+    SourceSpan span = node.span;
+    if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
+      return;
+    }
+    if (node is YamlList) {
+      for (YamlNode element in node.nodes) {
+        _searchWithin(path, element);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+      }
+    } else if (node is YamlMap) {
+      Map<dynamic, YamlNode> nodeMap = node.nodes;
+      for (YamlNode key in nodeMap.keys) {
+        _searchWithin(path, key);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+        _searchWithin(path, nodeMap[key]);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+      }
+    }
+    path.add(node);
+  }
+}
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 05d16f0..e605378 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -621,6 +621,9 @@
       if (name == LintNames.prefer_final_locals) {
         await _addFix_makeVariableFinal();
       }
+      if (name == LintNames.prefer_is_empty) {
+        await _addFix_replaceWithIsEmpty();
+      }
       if (name == LintNames.prefer_is_not_empty) {
         await _addFix_isNotEmpty();
       }
@@ -1146,7 +1149,7 @@
           sessionHelper,
           namedExpression.parent.parent,
         );
-        return parameters.namedNames;
+        return parameters?.namedNames;
       }
       return null;
     }
@@ -2373,7 +2376,8 @@
         DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async'));
   }
 
-  Future<void> _addFix_importLibrary(FixKind kind, Uri library) async {
+  Future<void> _addFix_importLibrary(FixKind kind, Uri library,
+      [String relativeURI = null]) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     String uriText;
@@ -2382,6 +2386,16 @@
       uriText = builder.importLibrary(library);
     });
     _addFixFromBuilder(changeBuilder, kind, args: [uriText]);
+
+    if (relativeURI != null && relativeURI.isNotEmpty) {
+      var changeBuilder2 = _newDartChangeBuilder();
+      await changeBuilder2.addFileEdit(file, (DartFileEditBuilder builder) {
+        if (builder is DartFileEditBuilderImpl) {
+          builder.importLibraryWithRelativeUri(relativeURI);
+        }
+      });
+      _addFixFromBuilder(changeBuilder2, kind, args: [relativeURI]);
+    }
   }
 
   Future<void> _addFix_importLibrary_withElement(
@@ -2486,7 +2500,9 @@
           fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
         }
         // Add the fix.
-        await _addFix_importLibrary(fixKind, librarySource.uri);
+        var relativeURI =
+            _getRelativeURIFromLibrary(unitLibraryElement, librarySource);
+        await _addFix_importLibrary(fixKind, librarySource.uri, relativeURI);
       }
     }
   }
@@ -3392,6 +3408,100 @@
     }
   }
 
+  Future<void> _addFix_replaceWithIsEmpty() async {
+    /// Return the value of an integer literal or prefix expression with a
+    /// minus and then an integer literal. For anything else, returns `null`.
+    int getIntValue(Expression expressions) {
+      // Copied from package:linter/src/rules/prefer_is_empty.dart.
+      if (expressions is IntegerLiteral) {
+        return expressions.value;
+      } else if (expressions is PrefixExpression) {
+        var operand = expressions.operand;
+        if (expressions.operator.type == TokenType.MINUS &&
+            operand is IntegerLiteral) {
+          return -operand.value;
+        }
+      }
+      return null;
+    }
+
+    /// Return the expression producing the object on which `length` is being
+    /// invoked, or `null` if there is no such expression.
+    Expression getLengthTarget(Expression expression) {
+      if (expression is PropertyAccess &&
+          expression.propertyName.name == 'length') {
+        return expression.target;
+      } else if (expression is PrefixedIdentifier &&
+          expression.identifier.name == 'length') {
+        return expression.prefix;
+      }
+      return null;
+    }
+
+    BinaryExpression binary = node.thisOrAncestorOfType();
+    TokenType operator = binary.operator.type;
+    String getter;
+    FixKind kind;
+    Expression lengthTarget;
+    int rightValue = getIntValue(binary.rightOperand);
+    if (rightValue != null) {
+      lengthTarget = getLengthTarget(binary.leftOperand);
+      if (rightValue == 0) {
+        if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
+          getter = 'isEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+        } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
+          getter = 'isNotEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+        }
+      } else if (rightValue == 1) {
+        // 'length >= 1' is same as 'isNotEmpty',
+        // and 'length < 1' is same as 'isEmpty'
+        if (operator == TokenType.GT_EQ) {
+          getter = 'isNotEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+        } else if (operator == TokenType.LT) {
+          getter = 'isEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+        }
+      }
+    } else {
+      int leftValue = getIntValue(binary.leftOperand);
+      if (leftValue != null) {
+        lengthTarget = getLengthTarget(binary.rightOperand);
+        if (leftValue == 0) {
+          if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
+            getter = 'isEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          } else if (operator == TokenType.LT ||
+              operator == TokenType.BANG_EQ) {
+            getter = 'isNotEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          }
+        } else if (leftValue == 1) {
+          // '1 <= length' is same as 'isNotEmpty',
+          // and '1 > length' is same as 'isEmpty'
+          if (operator == TokenType.LT_EQ) {
+            getter = 'isNotEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          } else if (operator == TokenType.GT) {
+            getter = 'isEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          }
+        }
+      }
+    }
+    if (lengthTarget == null || getter == null || kind == null) {
+      return;
+    }
+    String target = utils.getNodeText(lengthTarget);
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleReplacement(range.node(binary), '$target.$getter');
+    });
+    _addFixFromBuilder(changeBuilder, kind);
+  }
+
   Future<void> _addFix_replaceWithRethrow() async {
     if (coveredNode is ThrowExpression) {
       var changeBuilder = _newDartChangeBuilder();
@@ -4134,6 +4244,27 @@
   }
 
   /**
+   * Return the relative uri from the passed [library] to the passed
+   * [source]. If the [source] is not in the LibraryElement, `null` is returned.
+   */
+  String _getRelativeURIFromLibrary(LibraryElement library, Source source) {
+    var librarySource = library?.librarySource;
+    if (librarySource == null) {
+      return null;
+    }
+    var pathCtx = resourceProvider.pathContext;
+    var libraryDirectory = pathCtx.dirname(librarySource.fullName);
+    var sourceDirectory = pathCtx.dirname(source.fullName);
+    if (pathCtx.isWithin(libraryDirectory, source.fullName) ||
+        pathCtx.isWithin(sourceDirectory, libraryDirectory)) {
+      String relativeFile =
+          pathCtx.relative(source.fullName, from: libraryDirectory);
+      return pathCtx.split(relativeFile).join('/');
+    }
+    return null;
+  }
+
+  /**
    * Returns an expected [DartType] of [expression], may be `null` if cannot be
    * inferred.
    */
@@ -4485,6 +4616,7 @@
       'prefer_equal_for_default_values';
   static const String prefer_final_fields = 'prefer_final_fields';
   static const String prefer_final_locals = 'prefer_final_locals';
+  static const String prefer_is_empty = 'prefer_is_empty';
   static const String prefer_is_not_empty = 'prefer_is_not_empty';
   static const String type_init_formals = 'type_init_formals';
   static const String unawaited_futures = 'unawaited_futures';
@@ -4541,11 +4673,15 @@
   factory _ExecutableParameters(
       AnalysisSessionHelper sessionHelper, AstNode invocation) {
     Element element;
-    if (invocation is InstanceCreationExpression) {
+    // This doesn't handle FunctionExpressionInvocation.
+    if (invocation is Annotation) {
+      element = invocation.element;
+    } else if (invocation is InstanceCreationExpression) {
       element = invocation.staticElement;
-    }
-    if (invocation is MethodInvocation) {
+    } else if (invocation is MethodInvocation) {
       element = invocation.methodName.staticElement;
+    } else if (invocation is ConstructorReferenceNode) {
+      element = invocation.staticElement;
     }
     if (element is ExecutableElement && !element.isSynthetic) {
       return new _ExecutableParameters._(sessionHelper, element);
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 57c725a..2723c18 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -40,6 +40,7 @@
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:path/path.dart' as pathPackage;
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 
 final String kCustomCss = '''
 .lead, .page-title+.markdown-body>p:first-child {
@@ -174,9 +175,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     List<CompletionPerformance> completions = performanceItems;
 
     if (completions.isEmpty) {
@@ -246,8 +244,6 @@
 
   @override
   Future<void> generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = params['file'];
     if (path == null) {
       p('No file path provided.');
@@ -274,8 +270,6 @@
 
   @override
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       _description = params['file'];
       await super.generatePage(params);
@@ -293,9 +287,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     void writeRow(List<String> data, {List<String> classes}) {
       buf.write("<tr>");
       for (int i = 0; i < data.length; i++) {
@@ -420,8 +411,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     Map<Folder, AnalysisDriver> driverMap = server.driverMap;
     if (driverMap.isEmpty) {
       blankslate('No contexts.');
@@ -560,6 +549,13 @@
         buf.write('</p>');
       }
     }
+
+    h3('Dartdoc template info');
+    DartdocDirectiveInfo info = (server as AnalysisServer).declarationsTracker
+        ?.getContext(driver.analysisContext)
+        ?.dartdocDirectiveInfo ??
+        new DartdocDirectiveInfo();
+    writeMap(info.templateMap);
   }
 
   void writeList<E>(List<E> list) {
@@ -600,14 +596,10 @@
   AbstractAnalysisServer get server => site.socketServer.analysisServer;
 
   Future<void> generateContainer(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<div class="columns docs-layout">');
     buf.writeln('<div class="three-fourths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       p(description);
       await generateContent(params);
     }, classes: 'markdown-body');
@@ -646,8 +638,6 @@
   }
 
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<!DOCTYPE html><html lang="en">');
     buf.write('<head>');
     buf.write('<meta charset="utf-8">');
@@ -686,8 +676,6 @@
   bool get showInNav => true;
 
   Future<void> generateContainer(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<div class="columns docs-layout">');
 
     bool shouldShowInNav(Page page) {
@@ -711,8 +699,6 @@
     buf.writeln('<div class="four-fifths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       p(description);
       await generateContent(params);
     }, classes: 'markdown-body');
@@ -792,8 +778,6 @@
 
   @override
   Future<void> generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = params['file'];
     if (path == null) {
       p('No file path provided.');
@@ -820,8 +804,6 @@
 
   @override
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       _description = params['file'];
       await super.generatePage(params);
@@ -839,8 +821,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<table>');
     buf.writeln('<tr><th>Variable</th><th>Value</th></tr>');
     for (String key in Platform.environment.keys.toList()..sort()) {
@@ -858,8 +838,6 @@
       : super(site, '', '500 Oops', description: message);
 
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     p(trace.toString(), style: 'white-space: pre');
   }
 }
@@ -875,8 +853,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (exceptions.isEmpty) {
       blankslate('No exceptions encountered!');
     } else {
@@ -899,12 +875,10 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     final String issuesUrl = 'https://github.com/dart-lang/sdk/issues';
     p(
       'To file issues or feature requests, see our '
-          '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:',
+      '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:',
       raw: true,
     );
     ul([
@@ -941,8 +915,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     p(
         'Instrumentation can be enabled by starting the analysis server with the '
         '<code>--instrumentation-log-file=path/to/file</code> flag.',
@@ -1025,8 +997,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     UsageInfo usage = await profiler.getProcessUsage(pid);
 
     developer.ServiceProtocolInfo serviceProtocolInfo =
@@ -1090,8 +1060,6 @@
       : super(site, '', '404 Not found', description: "'$path' not found.");
 
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
   }
 }
 
@@ -1181,8 +1149,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     h3('Profiling performance tag data');
 
     // prepare sorted tags
@@ -1330,9 +1296,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     buf.writeln('<div class="columns">');
 
     buf.writeln('<div class="column one-half">');
@@ -1369,9 +1332,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     // server domain
     h3('Server domain subscriptions');
     ul(ServerService.VALUES, (item) {
@@ -1390,5 +1350,18 @@
         buf.write('$item');
       });
     }
+
+    // completion domain
+    CompletionDomainHandler handler = server.handlers.firstWhere(
+        (handler) => handler is CompletionDomainHandler,
+        orElse: () => null);
+    h3('Completion domain subscriptions');
+    ul(CompletionService.VALUES, (service) {
+      if (handler.subscriptions.contains(service)) {
+        buf.write('$service (has subscriptions)');
+      } else {
+        buf.write('$service (no subscriptions)');
+      }
+    });
   }
 }
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 0af04a9..8588391 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -13,7 +13,7 @@
 /**
  * A base class for classes containing completion tests.
  */
-class CompletionTestCase extends CompletionDomainHandlerTest {
+class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
   static const String CURSOR_MARKER = '!';
 
   List get suggestedCompletions => suggestions
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index c98af16..3f0e266 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -24,7 +24,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
-    defineReflectiveTests(CompletionDomainHandlerTest);
+    defineReflectiveTests(CompletionDomainHandlerListTokenDetailsTest);
   });
 }
 
@@ -866,77 +866,348 @@
 }
 
 @reflectiveTest
-class CompletionDomainHandlerTest extends AbstractCompletionDomainTest {
-  test_listTokenDetails() async {
-    newFile(testFile, content: '''
-class A {
-  static A b(String s) {}
-  c(int i) {}
-}
-main() {
-  A.b('s').c(3);
-}
-''');
+class CompletionDomainHandlerListTokenDetailsTest
+    extends AbstractCompletionDomainTest {
+  String testFileUri;
+
+  void expectTokens(String content, List<TokenDetails> expectedTokens) async {
+    newFile(testFile, content: content);
     Request request =
         new CompletionListTokenDetailsParams(testFile).toRequest('0');
     Response response = await waitResponse(request);
     List<Map<String, dynamic>> tokens = response.result['tokens'];
-    _expectTokens(tokens, [
-      _token('class', 'CLASS', null),
-      _token('A', 'STRING_INT', ['declaration']),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('static', 'STATIC', null),
-      _token('A', 'STRING_INT', ['identifier']),
-      _token('b', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('String', 'STRING_INT', ['identifier']),
-      _token('s', 'STRING_INT', ['declaration']),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('c', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('int', 'STRING_INT', ['identifier']),
-      _token('i', 'STRING_INT', ['declaration']),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('main', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('A', 'STRING_INT', ['identifier']),
-      _token('.', 'PERIOD', null),
-      _token('b', 'STRING_INT', ['identifier']),
-      _token('(', 'OPEN_PAREN', null),
-      _token("'s'", 'STRING', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('.', 'PERIOD', null),
-      _token('c', 'STRING_INT', ['identifier']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('3', 'INT', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token(';', 'SEMICOLON', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
+    _compareTokens(tokens, expectedTokens);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    testFileUri = toUriStr(testFile);
+  }
+
+  test_classDeclaration() async {
+    await expectTokens('''
+class A {}
+class B extends A {}
+class C implements B {}
+class D with C {}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('B', 'dart:core;Type', ['declaration']),
+      token('extends', null, null),
+      token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('C', 'dart:core;Type', ['declaration']),
+      token('implements', null, null),
+      token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('D', 'dart:core;Type', ['declaration']),
+      token('with', null, null),
+      token('C', 'dart:core;Type<$testFileUri;C>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
     ]);
   }
 
-  void _expectTokens(List<Map<String, dynamic>> actualTokens,
+  test_genericType() async {
+    await expectTokens('''
+List<int> x = null;
+''', [
+      token('List', 'dart:core;Type<dart:core;List>', ['reference']),
+      token('<', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('x', 'dart:core;List', ['declaration']),
+      token('=', null, null),
+      token('null', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_getterInvocation() async {
+    await expectTokens('''
+var x = 'a'.length;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token("'a'", 'dart:core;String', null),
+      token('.', null, null),
+      token('length', 'dart:core;int', ['reference']),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_bool() async {
+    await expectTokens('''
+var x = true;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;bool', ['declaration']),
+      token('=', null, null),
+      token('true', 'dart:core;bool', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_double() async {
+    await expectTokens('''
+var x = 3.4;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;double', ['declaration']),
+      token('=', null, null),
+      token('3.4', 'dart:core;double', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_int() async {
+    await expectTokens('''
+var x = 7;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token('7', 'dart:core;int', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_list() async {
+    await expectTokens('''
+var x = <int>[];
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;List', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('[', null, null),
+      token(']', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_map() async {
+    await expectTokens('''
+var x = <int, int>{};
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;Map', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+//      token(',', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_null() async {
+    await expectTokens('''
+var x = null;
+''', [
+      token('var', null, null),
+      token('x', 'dynamic', ['declaration']),
+      token('=', null, null),
+      token('null', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_set() async {
+    await expectTokens('''
+var x = <int>{};
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;Set', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_string() async {
+    await expectTokens('''
+var x = 'a';
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;String', ['declaration']),
+      token('=', null, null),
+      token("'a'", 'dart:core;String', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_methodDeclaration() async {
+    await expectTokens('''
+class A {
+  String c(int x, int y) {}
+}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('String', 'dart:core;Type<dart:core;String>', ['reference']),
+      token('c', 'dart:core;String Function(dart:core;int, dart:core;int)',
+          ['declaration']),
+      token('(', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('x', 'dart:core;int', ['declaration']),
+//      token(',', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('y', 'dart:core;int', ['declaration']),
+      token(')', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_methodInvocation() async {
+    await expectTokens('''
+var x = 'radar'.indexOf('r', 1);
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token("'radar'", 'dart:core;String', null),
+      token('.', null, null),
+      token(
+          'indexOf',
+          'dart:core;int Function(dart:core;Pattern, dart:core;int)',
+          ['reference']),
+      token('(', null, null),
+      token("'r'", 'dart:core;String', null),
+//      token(',', null, null),
+      token('1', 'dart:core;int', null),
+      token(')', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_mixinDeclaration() async {
+    await expectTokens('''
+class A {}
+class B {}
+mixin D on A implements B {}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('B', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('mixin', null, null),
+      token('D', 'dart:core;Type', ['declaration']),
+      token('on', null, null),
+      token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+      token('implements', null, null),
+      token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_parameterReference() async {
+    await expectTokens('''
+int f(int p) {
+  return p;
+}
+''', [
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('f', 'dart:core;int Function(dart:core;int)', ['declaration']),
+      token('(', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('p', 'dart:core;int', ['declaration']),
+      token(')', null, null),
+      token('{', null, null),
+      token('return', null, null),
+      token('p', 'dart:core;int', ['reference']),
+      token(';', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_topLevelVariable_withDocComment() async {
+    await expectTokens('''
+/// Doc comment [x] with reference.
+int x;
+''', [
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('x', 'dart:core;int', ['declaration']),
+      token(';', null, null),
+    ]);
+  }
+
+  TokenDetails token(String lexeme, String type, List<String> kinds) {
+    return new TokenDetails(lexeme, type: type, validElementKinds: kinds);
+  }
+
+  void _compareTokens(List<Map<String, dynamic>> actualTokens,
       List<TokenDetails> expectedTokens) {
     int length = expectedTokens.length;
     expect(actualTokens, hasLength(length));
+    List<String> errors = [];
     for (int i = 0; i < length; i++) {
       Map<String, dynamic> actual = actualTokens[i];
       TokenDetails expected = expectedTokens[i];
-      expect(actual['lexeme'], expected.lexeme);
-      expect(actual['type'], expected.type);
-      expect(actual['validElementKinds'], expected.validElementKinds);
+      if (actual['lexeme'] != expected.lexeme) {
+        errors.add('Lexeme at $i: '
+            'expected "${expected.lexeme}", '
+            'actual "${actual['lexeme']}"');
+      }
+      if (actual['type'] != expected.type) {
+        errors.add('Type at $i ("${expected.lexeme}"): '
+            'expected "${expected.type}", '
+            'actual "${actual['type']}"');
+      }
+      if (_differentKinds(
+          actual['validElementKinds'], expected.validElementKinds)) {
+        errors.add('Kinds at $i ("${expected.lexeme}"): '
+            'expected "${expected.validElementKinds}", '
+            'actual "${actual['validElementKinds']}"');
+      }
     }
+    expect(errors, isEmpty);
   }
 
-  TokenDetails _token(String lexeme, String type, List<String> kinds) {
-    return new TokenDetails(lexeme, type, validElementKinds: kinds);
+  /// Return `true` if the two lists of kinds are different.
+  bool _differentKinds(List<String> actual, List<String> expected) {
+    if (actual == null) {
+      return expected != null;
+    } else if (expected == null) {
+      return true;
+    }
+    int expectedLength = expected.length;
+    if (actual.length != expectedLength) {
+      return true;
+    }
+    for (int i = 0; i < expectedLength; i++) {
+      if (actual[i] != expected[i]) {
+        return true;
+      }
+    }
+    return false;
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 3f322e6..8a0e7b0 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -28,11 +28,12 @@
   void expectEdits(List<SourceFileEdit> fileEdits, String expectedSource) {
     expect(fileEdits, hasLength(1));
     expect(fileEdits[0].file, testFile);
-    List<SourceEdit> edits = fileEdits[0].edits;
-    String source = testCode;
-    for (SourceEdit edit in edits) {
-      source = edit.apply(source);
-    }
+    expectFileEdits(testCode, fileEdits[0], expectedSource);
+  }
+
+  void expectFileEdits(
+      String originalSource, SourceFileEdit fileEdit, String expectedSource) {
+    String source = SourceEdit.applySequence(originalSource, fileEdit.edits);
     expect(source, expectedSource);
   }
 
@@ -144,6 +145,78 @@
 ''');
   }
 
+  test_dartfix_non_nullable_analysis_options_created() async {
+    // Add pubspec for nnbd migration to detect
+    newFile('/project/pubspec.yaml', content: '''
+name: testnnbd
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits('', result.edits[0], '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+
+''');
+  }
+
+  test_dartfix_non_nullable_analysis_options_experiments_added() async {
+    String originalOptions = '''
+analyzer:
+  something:
+    - other
+
+linter:
+  - boo
+''';
+    newFile('/project/analysis_options.yaml', content: originalOptions);
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits(originalOptions, result.edits[0], '''
+analyzer:
+  something:
+    - other
+  enable-experiment:
+    - non-nullable
+
+linter:
+  - boo
+''');
+  }
+
+  test_dartfix_non_nullable_analysis_options_nnbd_added() async {
+    String originalOptions = '''
+analyzer:
+  enable-experiment:
+    - other
+linter:
+  - boo
+''';
+    newFile('/project/analysis_options.yaml', content: originalOptions);
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits(originalOptions, result.edits[0], '''
+analyzer:
+  enable-experiment:
+    - other
+    - non-nullable
+linter:
+  - boo
+''');
+  }
+
   test_dartfix_excludedSource() async {
     // Add analysis options to exclude the lib directory then reanalyze
     newFile('/project/analysis_options.yaml', content: '''
@@ -200,4 +273,77 @@
 const double myDouble = 42;
     ''');
   }
+
+  test_dartfix_spread_collections() 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 l = ['a']..addAll(['b']);
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['use-spread-collections']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expectEdits(result.edits, '''
+var l = ['a', ...['b']];
+''');
+  }
+
+  test_dartfix_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']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expectEdits(result.edits, '''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
+  test_dartfix_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 };
+}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 79cc139..70251a6 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -4,24 +4,24 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'assists_test.dart' as assists_test;
-import 'fixes_test.dart' as fixes_test;
-import 'format_test.dart' as format_test;
-import 'organize_directives_test.dart' as organize_directives_test;
-import 'postfix_completion_test.dart' as postfix_completion_test;
-import 'refactoring_test.dart' as refactoring_test;
-import 'sort_members_test.dart' as sort_members_test;
-import 'statement_completion_test.dart' as statement_completion_test;
+import 'assists_test.dart' as assists;
+import 'fixes_test.dart' as fixes;
+import 'format_test.dart' as format;
+import 'organize_directives_test.dart' as organize_directives;
+import 'postfix_completion_test.dart' as postfix_completion;
+import 'refactoring_test.dart' as refactoring;
+import 'sort_members_test.dart' as sort_members;
+import 'statement_completion_test.dart' as statement_completion;
 
 main() {
   defineReflectiveSuite(() {
-    assists_test.main();
-    fixes_test.main();
-    format_test.main();
-    organize_directives_test.main();
-    postfix_completion_test.main();
-    refactoring_test.main();
-    sort_members_test.main();
-    statement_completion_test.main();
+    assists.main();
+    fixes.main();
+    format.main();
+    organize_directives.main();
+    postfix_completion.main();
+    refactoring.main();
+    sort_members.main();
+    statement_completion.main();
   }, name: 'edit');
 }
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 cfd4d3a..fe67037 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -2026,6 +2026,13 @@
    *
    *   The elements to be made accessible in the specified file.
    *
+   * offset: int (optional)
+   *
+   *   The offset at which the specified elements need to be made accessible.
+   *   If provided, this is used to guard against adding imports for text that
+   *   would be inserted into a comment, string literal, or other location
+   *   where the imports would not be necessary.
+   *
    * Returns
    *
    * edit: SourceFileEdit (optional)
@@ -2038,8 +2045,10 @@
    *   that need to be applied.
    */
   Future<EditImportElementsResult> sendEditImportElements(
-      String file, List<ImportedElements> elements) async {
-    var params = new EditImportElementsParams(file, elements).toJson();
+      String file, List<ImportedElements> elements,
+      {int offset}) async {
+    var params =
+        new EditImportElementsParams(file, elements, offset: offset).toJson();
     var result = await server.send("edit.importElements", params);
     ResponseDecoder decoder = new ResponseDecoder(null);
     return new EditImportElementsResult.fromJson(decoder, 'result', result);
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 16f7d4b..7d348d6 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -712,6 +712,7 @@
     if (Platform.packageConfig != null) {
       arguments.add('--packages=${Platform.packageConfig}');
     }
+    arguments.add('--disable-service-auth-codes');
     //
     // Add the server executable.
     //
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 7cee89f..ec50cf1 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1618,13 +1618,17 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  */
 final Matcher isTokenDetails = new LazyMatcher(() => new MatchesJsonObject(
-    "TokenDetails", {"lexeme": isString, "type": isString},
-    optionalFields: {"validElementKinds": isListOf(isString)}));
+        "TokenDetails", {
+      "lexeme": isString
+    }, optionalFields: {
+      "type": isString,
+      "validElementKinds": isListOf(isString)
+    }));
 
 /**
  * TypeHierarchyItem
@@ -2616,11 +2620,13 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  */
 final Matcher isEditImportElementsParams = new LazyMatcher(() =>
     new MatchesJsonObject("edit.importElements params",
-        {"file": isFilePath, "elements": isListOf(isImportedElements)}));
+        {"file": isFilePath, "elements": isListOf(isImportedElements)},
+        optionalFields: {"offset": isInt}));
 
 /**
  * edit.importElements result
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 2da217e..03fa79b 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -52,7 +52,9 @@
     var uriStr = 'package:test/a.dart';
 
     newFile(path, content: r'''
-class A {}
+class A {
+  A.a();
+}
 ''');
 
     var set = await waitForSetWithUri(uriStr);
@@ -77,6 +79,27 @@
   ]
 }
 ''');
+    assertJsonText(_getSuggestion(set, 'A.a'), '''
+{
+  "label": "A.a",
+  "element": {
+    "kind": "CONSTRUCTOR",
+    "name": "a",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 14,
+      "length": 0,
+      "startLine": 2,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "parameters": "()"
+  },
+  "parameterNames": [],
+  "parameterTypes": [],
+  "requiredParameterCount": 0
+}
+''');
   }
 
   test_suggestion_enum() async {
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
index e9db0d5..c3b1915 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -48,6 +49,14 @@
             predicate((_Clause clause) => clause.consequence == consequence))));
   }
 
+  void assertNonNullIntent(NullabilityNode node, bool expected) {
+    if (expected) {
+      assertConstraint([], node.nonNullIntent);
+    } else {
+      assertNoConstraints(node.nonNullIntent);
+    }
+  }
+
   /// Gets the [ExpressionChecks] associated with the expression whose text
   /// representation is [text], or `null` if the expression has no
   /// [ExpressionChecks] associated with it.
@@ -78,7 +87,7 @@
 }
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
   }
 
   test_binaryExpression_add_left_check() async {
@@ -86,7 +95,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int i').nullable],
+    assertConstraint([decoratedTypeAnnotation('int i').node.nullable],
         checkExpression('i +').nullCheck);
   }
 
@@ -98,7 +107,7 @@
 Int f(Int i, Int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('Int i').nullable],
+    assertConstraint([decoratedTypeAnnotation('Int i').node.nullable],
         checkExpression('i +').nullCheck);
   }
 
@@ -111,8 +120,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('Int operator+').nullable],
-        _either(decoratedTypeAnnotation('Int f').nullable,
+        [decoratedTypeAnnotation('Int operator+').node.nullable],
+        _either(decoratedTypeAnnotation('Int f').node.nullable,
             checkExpression('(i + j)').nullCheck));
   }
 
@@ -121,7 +130,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int f').node.nullable);
   }
 
   test_binaryExpression_add_right_check() async {
@@ -129,7 +138,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int j').nullable],
+    assertConstraint([decoratedTypeAnnotation('int j').node.nullable],
         checkExpression('j;').nullCheck);
   }
 
@@ -142,8 +151,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('Int j').nullable],
-        _either(decoratedTypeAnnotation('Int other').nullable,
+        [decoratedTypeAnnotation('Int j').node.nullable],
+        _either(decoratedTypeAnnotation('Int other').node.nullable,
             checkExpression('j/*check*/').nullCheck));
   }
 
@@ -152,7 +161,7 @@
 bool f(int i, int j) => i == j;
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('bool f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('bool f').node.nullable);
   }
 
   test_boolLiteral() async {
@@ -161,7 +170,7 @@
   return true;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('bool').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('bool').node.nullable);
   }
 
   test_conditionalExpression_condition_check() async {
@@ -171,7 +180,7 @@
 }
 ''');
 
-    var nullable_b = decoratedTypeAnnotation('bool b').nullable;
+    var nullable_b = decoratedTypeAnnotation('bool b').node.nullable;
     var check_b = checkExpression('b ?').nullCheck;
     assertConstraint([nullable_b], check_b);
   }
@@ -183,11 +192,11 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     var nullable_i_or_nullable_j = _either(nullable_i, nullable_j);
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i], nullable_conditional);
     assertConstraint([nullable_j], nullable_conditional);
     assertConstraint([nullable_conditional], nullable_i_or_nullable_j);
@@ -202,8 +211,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(nullable_i));
   }
 
@@ -214,7 +223,7 @@
 }
 ''');
 
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(ConstraintVariable.always));
   }
 
@@ -225,8 +234,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(nullable_i));
   }
 
@@ -237,7 +246,7 @@
 }
 ''');
 
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(ConstraintVariable.always));
   }
 
@@ -247,8 +256,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('int/*2*/').nullable],
-        _either(decoratedTypeAnnotation('int/*1*/').nullable,
+        [decoratedTypeAnnotation('int/*2*/').node.nullable],
+        _either(decoratedTypeAnnotation('int/*1*/').node.nullable,
             checkExpression('i/*3*/').nullCheck));
   }
 
@@ -257,7 +266,7 @@
 void f({int i = 1}) {}
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_default_null() async {
@@ -265,8 +274,8 @@
 void f({int i = null}) {}
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_nullable() async {
@@ -277,7 +286,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeNullable));
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_required() async {
@@ -288,7 +298,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_required_assume_nullable() async {
@@ -301,7 +311,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeNullable));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_required_assume_required() async {
@@ -314,7 +324,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
@@ -322,7 +332,7 @@
 void f([int i = 1]) {}
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_default_null() async {
@@ -330,8 +340,8 @@
 void f([int i = null]) {}
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default() async {
@@ -339,7 +349,8 @@
 void f([int i]) {}
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default_assume_required() async {
@@ -352,7 +363,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_resets_unconditional_control_flow() async {
@@ -366,9 +378,9 @@
   assert(k != null);
 }
 ''');
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
-    assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent);
-    assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
+    assertNonNullIntent(decoratedTypeAnnotation('int j').node, false);
+    assertNonNullIntent(decoratedTypeAnnotation('int k').node, true);
   }
 
   test_functionInvocation_parameter_fromLocalParameter() async {
@@ -382,9 +394,11 @@
     var int_1 = decoratedTypeAnnotation('int/*1*/');
     var int_2 = decoratedTypeAnnotation('int/*2*/');
     var i_3 = checkExpression('i/*3*/');
-    assertConstraint([int_2.nullable], _either(int_1.nullable, i_3.nullCheck));
-    assertConstraint([int_2.nullable, int_1.nonNullIntent], i_3.nullCheck);
-    assertConstraint([int_1.nonNullIntent], int_2.nonNullIntent);
+    assertConstraint(
+        [int_2.node.nullable], _either(int_1.node.nullable, i_3.nullCheck));
+    assertConstraint(
+        [int_2.node.nullable, int_1.node.nonNullIntent], i_3.nullCheck);
+    assertConstraint([int_1.node.nonNullIntent], int_2.node.nonNullIntent);
   }
 
   test_functionInvocation_parameter_named() async {
@@ -394,8 +408,8 @@
   f(i: j/*check*/);
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     assertConstraint([nullable_j],
         _either(nullable_i, checkExpression('j/*check*/').nullCheck));
   }
@@ -408,7 +422,7 @@
 }
 ''');
     var optional_i = possiblyOptionalParameter('int i');
-    assertConstraint([], optional_i);
+    assertConstraint([], optional_i.nullable);
   }
 
   test_functionInvocation_parameter_named_missing_required() async {
@@ -424,7 +438,7 @@
     // The call at `f()` is presumed to be in error; no constraint is recorded.
     var optional_i = possiblyOptionalParameter('int i');
     expect(optional_i, isNull);
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
     assertNoConstraints(nullable_i);
   }
 
@@ -438,7 +452,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('null').nullCheck));
   }
 
@@ -451,8 +465,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('int/*1*/').nullable],
-        _either(decoratedTypeAnnotation('int/*2*/').nullable,
+        [decoratedTypeAnnotation('int/*1*/').node.nullable],
+        _either(decoratedTypeAnnotation('int/*2*/').node.nullable,
             checkExpression('(f())').nullCheck));
   }
 
@@ -463,7 +477,7 @@
 }
 ''');
 
-    assertConstraint([(decoratedTypeAnnotation('bool b').nullable)],
+    assertConstraint([(decoratedTypeAnnotation('bool b').node.nullable)],
         checkExpression('b) {}').nullCheck);
   }
 
@@ -477,7 +491,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, false);
   }
 
   test_if_conditional_control_flow_within() async {
@@ -492,7 +506,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, false);
   }
 
   test_if_guard_equals_null() async {
@@ -505,17 +519,17 @@
   }
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
-    var nullable_k = decoratedTypeAnnotation('int k').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
+    var nullable_k = decoratedTypeAnnotation('int k').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i, nullable_j],
         _either(nullable_return, checkExpression('j/*check*/').nullCheck));
     assertConstraint([nullable_k],
         _either(nullable_return, checkExpression('k/*check*/').nullCheck));
     var discard = statementDiscard('if (i == null)');
-    expect(discard.keepTrue, same(nullable_i));
-    expect(discard.keepFalse, same(ConstraintVariable.always));
+    expect(discard.trueGuard.nullable, same(nullable_i));
+    expect(discard.falseGuard, null);
     expect(discard.pureCondition, true);
   }
 
@@ -530,9 +544,9 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i],
         _either(nullable_return, checkExpression('i/*check*/').nullCheck));
     assertConstraint([nullable_j],
@@ -549,8 +563,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i],
         _either(nullable_return, checkExpression('i/*check*/').nullCheck));
   }
@@ -561,7 +575,7 @@
   return 0;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_methodDeclaration_resets_unconditional_control_flow() async {
@@ -577,9 +591,9 @@
   }
 }
 ''');
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
-    assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent);
-    assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
+    assertNonNullIntent(decoratedTypeAnnotation('int j').node, false);
+    assertNonNullIntent(decoratedTypeAnnotation('int k').node, true);
   }
 
   test_methodInvocation_parameter_contravariant() async {
@@ -592,10 +606,10 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
     var nullable_c_t =
-        decoratedTypeAnnotation('C<int>').typeArguments[0].nullable;
-    var nullable_t = decoratedTypeAnnotation('T t').nullable;
+        decoratedTypeAnnotation('C<int>').typeArguments[0].node.nullable;
+    var nullable_t = decoratedTypeAnnotation('T t').node.nullable;
     var nullable_c_t_or_nullable_t = _either(nullable_c_t, nullable_t);
     assertConstraint(
         [nullable_i],
@@ -612,11 +626,11 @@
 }
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int/*3*/').nullable],
-        decoratedTypeAnnotation('int/*1*/').nullable);
+    assertConstraint([decoratedTypeAnnotation('int/*3*/').node.nullable],
+        decoratedTypeAnnotation('int/*1*/').node.nullable);
     assertConstraint(
-        [decoratedTypeAnnotation('C<int/*3*/>/*4*/').nullable],
-        _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').nullable,
+        [decoratedTypeAnnotation('C<int/*3*/>/*4*/').node.nullable],
+        _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').node.nullable,
             checkExpression('c/*check*/').nullCheck));
   }
 
@@ -629,8 +643,8 @@
   c.f(i: j/*check*/);
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     assertConstraint([nullable_j],
         _either(nullable_i, checkExpression('j/*check*/').nullCheck));
   }
@@ -645,7 +659,7 @@
 }
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('C c').nullable],
+    assertConstraint([decoratedTypeAnnotation('C c').node.nullable],
         checkExpression('c.m').nullCheck);
   }
 
@@ -659,7 +673,7 @@
 }
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('C c').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('C c').node, true);
   }
 
   test_parenthesizedExpression() async {
@@ -671,7 +685,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('(null)').nullCheck));
   }
 
@@ -683,8 +697,8 @@
 }
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_return_null() async {
@@ -696,7 +710,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('null').nullCheck));
   }
 
@@ -707,7 +721,7 @@
   return 'x';
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('String').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('String').node.nullable);
   }
 
   test_thisExpression() async {
@@ -717,7 +731,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('C f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('C f').node.nullable);
   }
 
   test_throwExpression() async {
@@ -726,7 +740,7 @@
   return throw null;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_typeName() async {
@@ -735,7 +749,7 @@
   return int;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('Type').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('Type').node.nullable);
   }
 
   /// Creates a variable representing the disjunction of [a] and [b] solely for
@@ -777,7 +791,7 @@
     var decoratedType = decoratedTypeAnnotation('int?');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_interfaceType_typeParameter() async {
@@ -787,10 +801,10 @@
     var decoratedListType = decoratedTypeAnnotation('List<int>');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedListType));
-    expect(decoratedListType.nullable, isNotNull);
+    expect(decoratedListType.node.nullable, isNotNull);
     var decoratedIntType = decoratedTypeAnnotation('int');
     expect(decoratedListType.typeArguments[0], same(decoratedIntType));
-    expect(decoratedIntType.nullable, isNotNull);
+    expect(decoratedIntType.node.nullable, isNotNull);
   }
 
   test_topLevelFunction_parameterType_implicit_dynamic() async {
@@ -802,7 +816,7 @@
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_topLevelFunction_parameterType_named_no_default() async {
@@ -812,10 +826,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
-    expect(functionType.namedParameterOptionalVariables['s'],
-        same(decoratedType.nullable));
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, true);
   }
 
   test_topLevelFunction_parameterType_named_no_default_required() async {
@@ -827,9 +840,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
-    expect(functionType.namedParameterOptionalVariables['s'], isNull);
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
   test_topLevelFunction_parameterType_named_with_default() async {
@@ -839,9 +852,8 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(functionType.namedParameterOptionalVariables['s'],
-        same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
   test_topLevelFunction_parameterType_positionalOptional() async {
@@ -851,7 +863,7 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
   }
 
   test_topLevelFunction_parameterType_simple() async {
@@ -861,8 +873,8 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nonNullIntent, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nonNullIntent, isNotNull);
   }
 
   test_topLevelFunction_returnType_implicit_dynamic() async {
@@ -871,7 +883,7 @@
 ''');
     var decoratedType = decoratedFunctionType('f').returnType;
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_topLevelFunction_returnType_simple() async {
@@ -880,7 +892,7 @@
 ''');
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').returnType, same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
   }
 }
 
@@ -907,7 +919,7 @@
     return _variables.decoratedTypeAnnotation(findNode.typeAnnotation(text));
   }
 
-  ConstraintVariable possiblyOptionalParameter(String text) {
+  NullabilityNode possiblyOptionalParameter(String text) {
     return _variables
         .possiblyOptionalParameter(findNode.defaultParameter(text));
   }
@@ -988,7 +1000,7 @@
 
   final _expressionChecks = <Expression, ExpressionChecks>{};
 
-  final _possiblyOptional = <DefaultFormalParameter, ConstraintVariable>{};
+  final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
 
   /// Gets the [ExpressionChecks] associated with the given [expression].
   ExpressionChecks checkExpression(Expression expression) =>
@@ -1006,10 +1018,9 @@
   DecoratedType decoratedTypeAnnotation(TypeAnnotation typeAnnotation) =>
       _decoratedTypeAnnotations[typeAnnotation];
 
-  /// Gets the [ConstraintVariable] associated with the possibility that
+  /// Gets the [NullabilityNode] associated with the possibility that
   /// [parameter] may be optional.
-  ConstraintVariable possiblyOptionalParameter(
-          DefaultFormalParameter parameter) =>
+  NullabilityNode possiblyOptionalParameter(DefaultFormalParameter parameter) =>
       _possiblyOptional[parameter];
 
   @override
@@ -1038,10 +1049,10 @@
   }
 
   @override
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable) {
-    _possiblyOptional[parameter] = variable;
-    super.recordPossiblyOptional(source, parameter, variable);
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
+    _possiblyOptional[parameter] = node;
+    super.recordPossiblyOptional(source, parameter, node);
   }
 
   /// Unwraps any parentheses surrounding [expression].
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
index 1698262..d96f84d 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -368,6 +368,31 @@
                 NamedNoDefaultParameterHeuristic.assumeNullable));
   }
 
+  test_named_parameter_no_default_unused_option2_assume_nullable_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
   test_named_parameter_no_default_unused_option2_assume_required() async {
     var content = '''
 void f({String s}) {}
@@ -387,6 +412,31 @@
                 NamedNoDefaultParameterHeuristic.assumeRequired));
   }
 
+  test_named_parameter_no_default_unused_option2_assume_required_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
   test_named_parameter_no_default_unused_required_option2_assume_nullable() async {
     // The `@required` annotation overrides the assumption of nullability.
     // The call at `f()` is presumed to be in error.
@@ -455,6 +505,31 @@
                 NamedNoDefaultParameterHeuristic.assumeNullable));
   }
 
+  test_named_parameter_no_default_used_non_null_option2_assume_nullable_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
   test_named_parameter_no_default_used_non_null_option2_assume_required() async {
     var content = '''
 void f({String s}) {}
@@ -463,6 +538,7 @@
 }
 ''';
     var expected = '''
+import 'package:meta/meta.dart';
 void f({@required String s}) {}
 main() {
   f(s: 'x');
@@ -474,6 +550,32 @@
                 NamedNoDefaultParameterHeuristic.assumeRequired));
   }
 
+  test_named_parameter_no_default_used_non_null_option2_assume_required_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f(String s) {}
+void g({@required String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
   test_named_parameter_no_default_used_non_null_required_option2_assume_required() async {
     // Even if we are using the "assumeRequired" heuristic, we should not add a
     // duplicate `@required` annotation.
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
new file mode 100644
index 0000000..597c353
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -0,0 +1,190 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToIfElementTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToIfElementTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
+
+  void setUp() {
+    createAnalysisOptionsFile(
+        experiments: [EnableString.control_flow_collections]);
+    super.setUp();
+  }
+
+  test_mapFromIterable_complexKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) {
+    var result = e * 2;
+    return result;
+  }, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_complexValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) {
+    var result = e  + 3;
+    return result;
+  });
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var k = 3;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var k = 3;
+  return { for (var e in i) e * 2 : k };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var k in i) k * 2 : 0 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var e = 2;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var e = 2;
+  return { for (var e1 in i) e1 * e : e1 + e };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int v = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int v = 0;
+  return { for (var e in i) v++ : e * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int index = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int index = 0;
+  return { for (var v in i) index++ : v * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_missingKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingKeyAndValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_notMapFromIterable() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+class A {
+  A.fromIterable(i, {key, value});
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_sameParameterNames() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
index 8d8e3ef..5caae77 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
@@ -39,6 +39,19 @@
 ''');
   }
 
+  test_conditional_list_caret_at_start_of_expression() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return ['a', /*caret*/b ? 'c' : 'd', 'e'];
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
   test_conditional_list_withParentheses() async {
     await resolveTestUnit('''
 f(bool b) {
@@ -104,166 +117,4 @@
 }
 ''');
   }
-
-  test_mapFromIterable_complexKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) {
-    var result = e * 2;
-    return result;
-  }, value: (e) => e + 3);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_complexValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) {
-    var result = e  + 3;
-    return result;
-  });
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  var k = 3;
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  var k = 3;
-  return { for (var e in i) e * 2 : k };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var k in i) k * 2 : 0 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  var e = 2;
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  var e = 2;
-  return { for (var e1 in i) e1 * e : e1 + e };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var e in i) e * 2 : e + 3 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  int v = 0;
-  return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  int v = 0;
-  return { for (var e in i) v++ : e * 10 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  int index = 0;
-  return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  int index = 0;
-  return { for (var v in i) index++ : v * 10 };
-}
-''');
-  }
-
-  test_mapFromIterable_missingKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, value: (e) => e + 3);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_missingKeyAndValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_missingValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_notMapFromIterable() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
-}
-class A {
-  A.fromIterable(i, {key, value});
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_sameParameterNames() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var e in i) e * 2 : e + 3 };
-}
-''');
-  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
index 648502f..d026fb3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -41,6 +41,21 @@
 ''');
   }
 
+  test_addAll_expression_to_emptyList() async {
+    await resolveTestUnit('''
+f() {
+  var ints = [1, 2, 3];
+  print([]..addAl/*caret*/l(ints.map((i) => i.toString()))..addAll(['c']));
+}
+''');
+    await assertHasAssist('''
+f() {
+  var ints = [1, 2, 3];
+  print([...ints.map((i) => i.toString())]..addAll(['c']));
+}
+''');
+  }
+
   test_addAll_literal() async {
     await resolveTestUnit('''
 var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index 9bba973..bcf631e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -26,6 +26,7 @@
 import 'convert_to_double_quoted_string_test.dart'
     as convert_to_double_quoted_string;
 import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter;
+import 'convert_to_for_element_test.dart' as convert_to_for_element;
 import 'convert_to_if_element_test.dart' as convert_to_if_element;
 import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
 import 'convert_to_list_literal_test.dart' as convert_to_list_literal;
@@ -96,6 +97,7 @@
     convert_part_of_to_uri.main();
     convert_to_double_quoted_string.main();
     convert_to_field_parameter.main();
+    convert_to_for_element.main();
     convert_to_if_element.main();
     convert_to_int_literal.main();
     convert_to_list_literal.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
new file mode 100644
index 0000000..5a19c8b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -0,0 +1,122 @@
+// 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/fix/fix_core.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
+import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
+import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveSettingTest);
+  });
+}
+
+class NonDartFixTest with ResourceProviderMixin {
+  Future<void> assertHasFix(
+      String initialContent, String location, String expectedContent) async {
+    File optionsFile = resourceProvider.getFile('/analysis_options.yaml');
+    SourceFactory sourceFactory = new SourceFactory([]);
+    List<engine.AnalysisError> errors = analyzeAnalysisOptions(
+        optionsFile.createSource(), initialContent, sourceFactory);
+    expect(errors, hasLength(1));
+    engine.AnalysisError error = errors[0];
+    YamlMap options = _getOptions(sourceFactory, initialContent);
+    AnalysisOptionsFixGenerator generator =
+        new AnalysisOptionsFixGenerator(error, initialContent, options);
+    List<Fix> fixes = await generator.computeFixes();
+    expect(fixes, hasLength(1));
+    List<SourceFileEdit> fileEdits = fixes[0].change.edits;
+    expect(fileEdits, hasLength(1));
+
+    String actualContent =
+        SourceEdit.applySequence(initialContent, fileEdits[0].edits);
+    expect(actualContent, expectedContent);
+  }
+
+  YamlMap _getOptions(SourceFactory sourceFactory, String content) {
+    AnalysisOptionsProvider optionsProvider =
+        new AnalysisOptionsProvider(sourceFactory);
+    try {
+      return optionsProvider.getOptionsFromString(content);
+    } on OptionsFormatException {
+      return null;
+    }
+  }
+}
+
+@reflectiveTest
+class RemoveSettingTest extends NonDartFixTest {
+  test_enableSuperMixins() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+  language:
+    enableSuperMixins: true
+''',
+        'enable',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_first() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - not-an-experiment
+    - non-nullable
+''',
+        'not-',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_last() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+    - not-an-experiment
+''',
+        'not-',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_only() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - not-an-experiment
+''',
+        'not-',
+        '''
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
new file mode 100644
index 0000000..c202ee9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
@@ -0,0 +1,13 @@
+// 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'remove_setting_test.dart' as remove_setting;
+
+main() {
+  defineReflectiveSuite(() {
+    remove_setting.main();
+  });
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
index b24488f..2707a41 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
@@ -117,6 +117,23 @@
 ''');
   }
 
+  test_default_annotation() async {
+    await resolveTestUnit('''
+@A(boot: 2)
+f() => null;
+class A {
+  const A({int boat});
+}
+''');
+    await assertHasFix('''
+@A(boat: 2)
+f() => null;
+class A {
+  const A({int boat});
+}
+''');
+  }
+
   test_default_constructor() async {
     await resolveTestUnit('''
 f() => new A(boot: 2);
@@ -166,6 +183,40 @@
 ''');
   }
 
+  test_default_redirectingConstructor() async {
+    await resolveTestUnit('''
+class A {
+  A.one() : this.two(boot: 3);
+  A.two({int boat});
+}
+''');
+    await assertHasFix('''
+class A {
+  A.one() : this.two(boat: 3);
+  A.two({int boat});
+}
+''');
+  }
+
+  test_default_superConstructor() async {
+    await resolveTestUnit('''
+class A {
+  A.a({int boat});
+}
+class B extends A {
+  B.b() : super.a(boot: 3);
+}
+''');
+    await assertHasFix('''
+class A {
+  A.a({int boat});
+}
+class B extends A {
+  B.b() : super.a(boat: 3);
+}
+''');
+  }
+
   test_tooDistant_constructor() async {
     await resolveTestUnit('''
 f() => new A(bbbbb: 2);
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 e9b5fa2..beb7025 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
@@ -64,9 +64,13 @@
   Future<void> assertHasFix(String expected,
       {bool Function(AnalysisError) errorFilter,
       int length,
-      String target}) async {
+      String target,
+      int expectedNumberOfFixesForKind,
+      String matchFixMessage}) async {
     AnalysisError error = await _findErrorToFix(errorFilter, length: length);
-    Fix fix = await _assertHasFix(error);
+    Fix fix = await _assertHasFix(error,
+        expectedNumberOfFixesForKind: expectedNumberOfFixesForKind,
+        matchFixMessage: matchFixMessage);
     change = fix.change;
 
     // apply to "file"
@@ -148,12 +152,38 @@
     verifyNoTestUnitErrors = false;
   }
 
-  /// Computes fixes and verifies that there is a fix for the given [error] of
-  /// the appropriate kind.
-  Future<Fix> _assertHasFix(AnalysisError error) async {
+  /// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind.
+  /// Optionally, if a [matchFixMessage] is passed, then the kind as well as the fix message must
+  /// match to be returned.
+  Future<Fix> _assertHasFix(AnalysisError error,
+      {int expectedNumberOfFixesForKind, String matchFixMessage}) async {
     // Compute the fixes for this AnalysisError
     final List<Fix> fixes = await _computeFixes(error);
 
+    if (expectedNumberOfFixesForKind != null) {
+      int actualNumberOfFixesForKind = 0;
+      for (Fix fix in fixes) {
+        if (fix.kind == kind) {
+          actualNumberOfFixesForKind++;
+        }
+      }
+      if (actualNumberOfFixesForKind != expectedNumberOfFixesForKind) {
+        fail(
+            "Expected $expectedNumberOfFixesForKind fixes of kind $kind, but found $actualNumberOfFixesForKind:\n${fixes.join('\n')}");
+      }
+    }
+
+    // If a matchFixMessage was provided,
+    if (matchFixMessage != null) {
+      for (Fix fix in fixes) {
+        if (matchFixMessage == fix?.change?.message) {
+          return fix;
+        }
+      }
+      fail(
+          'Expected to find fix $kind with name $matchFixMessage in\n${fixes.join('\n')}');
+    }
+
     // Assert that none of the fixes are a fix-all fix.
     Fix foundFix = null;
     for (Fix fix in fixes) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index 08bf63e..f1d1710 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -65,7 +65,7 @@
   Test test = null;
   print(test);
 }
-''');
+''', expectedNumberOfFixesForKind: 1);
   }
 
   test_preferDirectOverExport_src() async {
@@ -83,7 +83,65 @@
   Test test = null;
   print(test);
 }
+''', expectedNumberOfFixesForKind: 1);
+  }
+
+  test_relativeDirective() async {
+    addSource('/home/test/lib/a.dart', '''
+import "b.dart";
 ''');
+    addSource('/home/test/lib/b.dart', '''
+class Foo {}
+''');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import 'b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library 'b.dart'");
+  }
+
+  test_relativeDirective_upOneDirectory() async {
+    addSource('/home/test/lib/a.dart', '''
+import "b.dart";
+''');
+    addSource('/home/test/lib/b.dart', '''
+class Foo {}
+''');
+    testFile = convertPath('/home/test/lib/dir/test.dart');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import '../b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library '../b.dart'");
+  }
+
+  test_relativeDirective_downOneDirectory() async {
+    addSource('/home/test/lib/dir/a.dart', '''
+import "b.dart";
+''');
+    addSource('/home/test/lib/dir/b.dart', '''
+class Foo {}
+''');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import 'dir/b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library 'dir/b.dart'");
   }
 
   test_withClass_annotation() async {
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
new file mode 100644
index 0000000..ef13aa9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithIsEmptyTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithIsEmptyTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REPLACE_WITH_IS_EMPTY;
+
+  @override
+  String get lintCode => LintNames.prefer_is_empty;
+
+  test_constantOnLeft_equal() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 == c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_greaterThan() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/1 > c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_greaterThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 >= c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_equal() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length == 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_lessThan() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length < 1) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_lessThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length <= 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/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
new file mode 100644
index 0000000..9b621d9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithIsNotEmptyTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithIsNotEmptyTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+
+  @override
+  String get lintCode => LintNames.prefer_is_empty;
+
+  test_constantOnLeft_lessThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/1 <= c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_notEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 != c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_greaterThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length >= 1) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_notEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length != 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index e9ea84e..de8cd2a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -23,6 +23,7 @@
 import 'add_static_test.dart' as add_static;
 import 'add_super_constructor_invocation_test.dart'
     as add_super_constructor_invocation;
+import 'analysis_options/test_all.dart' as analysis_options;
 import 'change_argument_name_test.dart' as change_argument_name;
 import 'change_to_nearest_precise_value_test.dart'
     as change_to_nearest_precise_value;
@@ -95,6 +96,8 @@
 import 'replace_with_conditional_assignment_test.dart'
     as replace_with_conditional_assignment;
 import 'replace_with_identifier_test.dart' as replace_with_identifier;
+import 'replace_with_is_empty_test.dart' as replace_with_is_empty;
+import 'replace_with_is_not_empty_test.dart' as replace_with_is_not_empty;
 import 'replace_with_null_aware_test.dart' as replace_with_null_aware;
 import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
 import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
@@ -122,6 +125,7 @@
     add_required.main();
     add_static.main();
     add_super_constructor_invocation.main();
+    analysis_options.main();
     change_argument_name.main();
     change_to.main();
     change_to_nearest_precise_value.main();
@@ -188,6 +192,8 @@
     replace_with_brackets.main();
     replace_with_conditional_assignment.main();
     replace_with_identifier.main();
+    replace_with_is_empty.main();
+    replace_with_is_not_empty.main();
     replace_with_null_aware.main();
     replace_with_tear_off.main();
     update_sdk_constraints.main();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 1ad467a..da73811 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -624,8 +624,12 @@
    *
    * @param file The file in which the specified elements are to be made accessible.
    * @param elements The elements to be made accessible in the specified file.
+   * @param offset The offset at which the specified elements need to be made accessible. If
+   *         provided, this is used to guard against adding imports for text that would be inserted
+   *         into a comment, string literal, or other location where the imports would not be
+   *         necessary.
    */
-  public void edit_importElements(String file, List<ImportedElements> elements, ImportElementsConsumer consumer);
+  public void edit_importElements(String file, List<ImportedElements> elements, int offset, ImportElementsConsumer consumer);
 
   /**
    * {@code edit.isPostfixCompletionApplicable}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
index 183ba52..071328a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
@@ -36,17 +36,20 @@
   public static final List<TokenDetails> EMPTY_LIST = Lists.newArrayList();
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   private final String lexeme;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
+   * reference position.
    */
   private final String type;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference position. (If no other
+   * purpose is found for this field then it should be renamed and converted to a boolean value.)
+   * Omitted if the token is not an identifier.
    */
   private final List<String> validElementKinds;
 
@@ -73,7 +76,7 @@
 
   public static TokenDetails fromJson(JsonObject jsonObject) {
     String lexeme = jsonObject.get("lexeme").getAsString();
-    String type = jsonObject.get("type").getAsString();
+    String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString();
     List<String> validElementKinds = jsonObject.get("validElementKinds") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("validElementKinds").getAsJsonArray());
     return new TokenDetails(lexeme, type, validElementKinds);
   }
@@ -91,21 +94,24 @@
   }
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   public String getLexeme() {
     return lexeme;
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
+   * reference position.
    */
   public String getType() {
     return type;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference position. (If no other
+   * purpose is found for this field then it should be renamed and converted to a boolean value.)
+   * Omitted if the token is not an identifier.
    */
   public List<String> getValidElementKinds() {
     return validElementKinds;
@@ -123,7 +129,9 @@
   public JsonObject toJson() {
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("lexeme", lexeme);
-    jsonObject.addProperty("type", type);
+    if (type != null) {
+      jsonObject.addProperty("type", type);
+    }
     if (validElementKinds != null) {
       JsonArray jsonArrayValidElementKinds = new JsonArray();
       for (String elt : validElementKinds) {
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index edbcba3..56f1243 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.25.0</version>
+  <version>1.26.0</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -2534,15 +2534,26 @@
           The elements to be made accessible in the specified file.
         </p>
       </field>
+      <field name="offset" optional="true">
+        <ref>int</ref>
+        <p>
+          The offset at which the specified elements need to be made accessible.
+          If provided, this is used to guard against adding imports for text
+          that would be inserted into a comment, string literal, or other
+          location where the imports would not be necessary.
+        </p>
+      </field>
     </params>
     <result>
       <field name="edit" optional="true">
         <ref>SourceFileEdit</ref>
         <p>
-          The edits to be applied in order to make the specified elements accessible. The file to be edited will be the
-          defining compilation unit of the library containing the file specified in the request, which can be different
-          than the file specified in the request if the specified file is a part file. This field will be omitted if
-          there are no edits that need to be applied.
+          The edits to be applied in order to make the specified elements
+          accessible. The file to be edited will be the defining compilation
+          unit of the library containing the file specified in the request,
+          which can be different than the file specified in the request if the
+          specified file is a part file. This field will be omitted if there are
+          no edits that need to be applied.
         </p>
       </field>
     </result>
@@ -3892,13 +3903,14 @@
       <field name="lexeme">
         <ref>String</ref>
         <p>
-          The raw token text.
+          The token's lexeme.
         </p>
       </field>
-      <field name="type">
+      <field name="type" optional="true">
         <ref>String</ref>
         <p>
-          The type of this token.
+          A unique id for the type of the identifier.
+          Omitted if the token is not an identifier in a reference position.
         </p>
       </field>
       <field name="validElementKinds" optional="true">
@@ -3906,7 +3918,10 @@
           <ref>String</ref>
         </list>
         <p>
-          The kinds of elements which could validly replace this token.
+          An indication of whether this token is in a declaration or reference
+          position. (If no other purpose is found for this field then it should
+          be renamed and converted to a boolean value.)
+          Omitted if the token is not an identifier.
         </p>
       </field>
     </object>
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 0125a30..35174b9 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.25.0';
+const String PROTOCOL_VERSION = '1.26.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -201,6 +201,7 @@
 const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file';
+const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE =
     'edit.isPostfixCompletionApplicable';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
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 b9d94ce..5d1b076 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -10312,6 +10313,8 @@
 
   List<ImportedElements> _elements;
 
+  int _offset;
+
   /**
    * The file in which the specified elements are to be made accessible.
    */
@@ -10338,9 +10341,29 @@
     this._elements = value;
   }
 
-  EditImportElementsParams(String file, List<ImportedElements> elements) {
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  void set offset(int value) {
+    this._offset = value;
+  }
+
+  EditImportElementsParams(String file, List<ImportedElements> elements,
+      {int offset}) {
     this.file = file;
     this.elements = elements;
+    this.offset = offset;
   }
 
   factory EditImportElementsParams.fromJson(
@@ -10365,7 +10388,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "elements");
       }
-      return new EditImportElementsParams(file, elements);
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      }
+      return new EditImportElementsParams(file, elements, offset: offset);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json);
     }
@@ -10382,6 +10409,9 @@
     result["file"] = file;
     result["elements"] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    if (offset != null) {
+      result["offset"] = offset;
+    }
     return result;
   }
 
@@ -10398,7 +10428,8 @@
     if (other is EditImportElementsParams) {
       return file == other.file &&
           listEqual(elements, other.elements,
-              (ImportedElements a, ImportedElements b) => a == b);
+              (ImportedElements a, ImportedElements b) => a == b) &&
+          offset == other.offset;
     }
     return false;
   }
@@ -10408,6 +10439,7 @@
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -21541,7 +21573,7 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  *
@@ -21555,12 +21587,12 @@
   List<String> _validElementKinds;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   String get lexeme => _lexeme;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   void set lexeme(String value) {
     assert(value != null);
@@ -21568,31 +21600,38 @@
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   String get type => _type;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   void set type(String value) {
-    assert(value != null);
     this._type = value;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   List<String> get validElementKinds => _validElementKinds;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   void set validElementKinds(List<String> value) {
     this._validElementKinds = value;
   }
 
-  TokenDetails(String lexeme, String type, {List<String> validElementKinds}) {
+  TokenDetails(String lexeme, {String type, List<String> validElementKinds}) {
     this.lexeme = lexeme;
     this.type = type;
     this.validElementKinds = validElementKinds;
@@ -21613,8 +21652,6 @@
       String type;
       if (json.containsKey("type")) {
         type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, "type");
       }
       List<String> validElementKinds;
       if (json.containsKey("validElementKinds")) {
@@ -21623,8 +21660,8 @@
             json["validElementKinds"],
             jsonDecoder.decodeString);
       }
-      return new TokenDetails(lexeme, type,
-          validElementKinds: validElementKinds);
+      return new TokenDetails(lexeme,
+          type: type, validElementKinds: validElementKinds);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json);
     }
@@ -21634,7 +21671,9 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["lexeme"] = lexeme;
-    result["type"] = type;
+    if (type != null) {
+      result["type"] = type;
+    }
     if (validElementKinds != null) {
       result["validElementKinds"] = validElementKinds;
     }
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 156688d..f79078a 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -523,6 +523,10 @@
   /// Return `true` if this element has an annotation of the form '@literal'.
   bool get hasLiteral;
 
+  /// Return `true` if this element has an annotation of the form
+  /// `@optionalTypeArgs`.
+  bool get hasOptionalTypeArgs;
+
   /// Return `true` if this element has an annotation of the form `@override`.
   bool get hasOverride;
 
@@ -747,6 +751,10 @@
   /// overriding methods to call super.
   bool get isMustCallSuper;
 
+  /// Return `true` if this annotation marks the associated type as
+  /// having "optional" type arguments.
+  bool get isOptionalTypeArgs;
+
   /// Return `true` if this annotation marks the associated method as being
   /// expected to override an inherited method.
   bool get isOverride;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index c5b2489..266e0f2 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/manifest/manifest_warning_code.dart';
 import 'package:front_end/src/base/errors.dart';
 import 'package:front_end/src/scanner/errors.dart';
 
@@ -230,6 +231,7 @@
   CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
   CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
   CompileTimeErrorCode.NOT_MAP_SPREAD,
+  CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
   CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
@@ -355,6 +357,9 @@
   HintCode.UNUSED_LABEL,
   HintCode.UNUSED_LOCAL_VARIABLE,
   HintCode.UNUSED_SHOWN_NAME,
+  ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE,
+  ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE,
+  ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE,
   ParserErrorCode.ABSTRACT_CLASS_MEMBER,
   ParserErrorCode.ABSTRACT_ENUM,
   ParserErrorCode.ABSTRACT_STATIC_METHOD,
@@ -528,6 +533,7 @@
   ParserErrorCode.TOP_LEVEL_OPERATOR,
   ParserErrorCode.TYPEDEF_IN_CLASS,
   ParserErrorCode.TYPE_ARGUMENTS_ON_TYPE_VARIABLE,
+  ParserErrorCode.TYPE_BEFORE_FACTORY,
   ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
   ParserErrorCode.UNEXPECTED_TOKEN,
   ParserErrorCode.VAR_AND_TYPE,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f9db9f8..b5fde2b 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -7993,7 +7993,12 @@
         if (i > 0) {
           sink.write(separator);
         }
-        nodes[i].accept(this);
+        var node = nodes[i];
+        if (node != null) {
+          node.accept(this);
+        } else {
+          sink.write('<null>');
+        }
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 789609e..112dce6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1160,6 +1160,10 @@
       return _dartObjectComputer.eagerXor(
           node, leftResult, rightResult, experimentStatus.constant_update_2018);
     } else if (operatorType == TokenType.EQ_EQ) {
+      if (experimentStatus.constant_update_2018) {
+        return _dartObjectComputer.lazyEqualEqual(
+            node, leftResult, rightResult);
+      }
       return _dartObjectComputer.equalEqual(node, leftResult, rightResult);
     } else if (operatorType == TokenType.GT) {
       return _dartObjectComputer.greaterThan(node, leftResult, rightResult);
@@ -2012,6 +2016,18 @@
     return null;
   }
 
+  DartObjectImpl lazyEqualEqual(Expression node, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (leftOperand != null && rightOperand != null) {
+      try {
+        return leftOperand.lazyEqualEqual(_typeProvider, rightOperand);
+      } on EvaluationException catch (exception) {
+        _errorReporter.reportErrorForNode(exception.errorCode, node);
+      }
+    }
+    return null;
+  }
+
   DartObjectImpl lazyOr(BinaryExpression node, DartObjectImpl leftOperand,
       DartObjectImpl rightOperandComputer()) {
     if (leftOperand != null) {
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index bb01428..1b93859 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -109,6 +109,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lazyOr(InstanceState rightOperandComputer()) {
     if (value == true) {
       return TRUE_STATE;
@@ -563,6 +568,31 @@
           _state.lazyAnd(() => rightOperandComputer()?._state));
 
   /**
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
+   *
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
+   */
+  DartObjectImpl lazyEqualEqual(
+      TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    if (isNull || rightOperand.isNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType,
+          isNull && rightOperand.isNull
+              ? BoolState.TRUE_STATE
+              : BoolState.FALSE_STATE);
+    }
+    if (isBoolNumStringOrNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType, _state.lazyEqualEqual(rightOperand._state));
+    }
+    throw new EvaluationException(
+        CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+  }
+
+  /**
    * Return the result of invoking the '||' operator on this object with the
    * [rightOperand]. The [typeProvider] is the type provider used to find known
    * types.
@@ -1077,6 +1107,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -1313,6 +1348,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   BoolState lazyOr(InstanceState rightOperandComputer()) {
     InstanceState rightOperand = rightOperandComputer();
     assertBool(rightOperand);
@@ -1452,6 +1492,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => _element == null ? "-unknown-" : _element.name;
 }
 
@@ -1544,6 +1589,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     List<String> fieldNames = _fieldMap.keys.toList();
@@ -1855,6 +1905,15 @@
   }
 
   /**
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand].
+   *
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
+   */
+  BoolState lazyEqualEqual(InstanceState rightOperand);
+
+  /**
    * Return the result of invoking the '||' operator on this object with the
    * [rightOperand].
    *
@@ -2348,6 +2407,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -2640,6 +2704,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('[');
@@ -2724,6 +2793,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('{');
@@ -2791,6 +2865,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState logicalNot() {
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2880,6 +2959,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     return BoolState.UNKNOWN_VALUE;
@@ -2982,6 +3066,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('{');
@@ -3078,6 +3167,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   IntState stringLength() {
     if (value == null) {
       return IntState.UNKNOWN_VALUE;
@@ -3145,6 +3239,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => value == null ? "-unknown-" : "#$value";
 }
 
@@ -3204,5 +3303,10 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => _type?.toString() ?? "-unknown-";
 }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 8cbeb21..743595d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -32,6 +32,7 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/comment.dart';
 
 /// Assert that the given [object] is null, which in the places where this
 /// function is called means that the element is not resynthesized.
@@ -61,7 +62,7 @@
   AbstractClassElementImpl(String name, int offset) : super(name, offset);
 
   AbstractClassElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
@@ -460,11 +461,9 @@
         super(name, offset);
 
   ClassElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
+      Reference reference, AstNode linkedNode)
       : _unlinkedClass = null,
-        super.forLinkedNode(enclosing, reference, linkedNode) {
-    enclosing.linkedContext.loadClassMemberReferences(reference);
-  }
+        super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
   ClassElementImpl.forNode(Identifier name)
@@ -484,11 +483,10 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
-    if (linkedNode != null) {
-      if (_accessors != null) return _accessors;
+    if (_accessors != null) return _accessors;
 
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
+    if (linkedNode != null) {
+      if (linkedNode is ClassOrMixinDeclaration) {
         _createPropertiesAndAccessors();
         assert(_accessors != null);
         return _accessors;
@@ -496,12 +494,14 @@
         return _accessors = const [];
       }
     }
+
     if (_accessors == null) {
       if (_unlinkedClass != null) {
         _resynthesizeFieldsAndPropertyAccessors();
       }
     }
-    return _accessors ?? const <PropertyAccessorElement>[];
+
+    return _accessors ??= const <PropertyAccessorElement>[];
   }
 
   @override
@@ -520,7 +520,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.codeRange?.length;
@@ -531,7 +531,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.codeRange?.offset;
@@ -552,16 +552,15 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@constructor');
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
-        _constructors = linkedNode.classOrMixinDeclaration_members
-            .where((node) => node.kind == LinkedNodeKind.constructorDeclaration)
-            .map((node) {
-          var name = context.getConstructorDeclarationName(node);
-          var reference = containerRef.getChild(name);
-          return ConstructorElementImpl.forLinkedNode(reference, node, this);
-        }).toList();
-      }
+      _constructors = context.getConstructors(linkedNode).map((node) {
+        var name = node.name?.name ?? '';
+        var reference = containerRef.getChild(name);
+        if (reference.element == null) {
+          reference.node2 = node;
+          ConstructorElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as ConstructorElement;
+      }).toList();
     }
 
     if (_unlinkedClass != null) {
@@ -619,9 +618,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.documentationComment?.text;
@@ -634,11 +633,10 @@
 
   @override
   List<FieldElement> get fields {
-    if (linkedNode != null) {
-      if (_fields != null) return _fields;
+    if (_fields != null) return _fields;
 
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
+    if (linkedNode != null) {
+      if (linkedNode is ClassOrMixinDeclaration) {
         _createPropertiesAndAccessors();
         assert(_fields != null);
         return _fields;
@@ -646,11 +644,13 @@
         _fields = const [];
       }
     }
+
     if (_fields == null) {
       if (_unlinkedClass != null) {
         _resynthesizeFieldsAndPropertyAccessors();
       }
     }
+
     return _fields ?? const <FieldElement>[];
   }
 
@@ -748,10 +748,13 @@
       var context = enclosingUnit.linkedContext;
       var implementsClause = context.getImplementsClause(linkedNode);
       if (implementsClause != null) {
-        return _interfaces = implementsClause.implementsClause_interfaces
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        return _interfaces = implementsClause.interfaces
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
+            .where(_isInterfaceTypeInterface)
             .toList();
+      } else {
+        return _interfaces = const [];
       }
     } else if (_unlinkedClass != null) {
       var unlinkedInterfaces = _unlinkedClass.interfaces;
@@ -792,11 +795,7 @@
   @override
   bool get isAbstract {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-        return linkedNode.classDeclaration_abstractKeyword != 0;
-      } else {
-        return linkedNode.classTypeAlias_abstractKeyword != 0;
-      }
+      return enclosingUnit.linkedContext.isAbstract(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.isAbstract;
@@ -807,7 +806,7 @@
   @override
   bool get isMixinApplication {
     if (linkedNode != null) {
-      return linkedNode.kind == LinkedNodeKind.classTypeAlias;
+      return linkedNode is ClassTypeAlias;
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.isMixinApplication;
@@ -830,6 +829,14 @@
   }
 
   @override
+  bool get isSimplyBounded {
+//    if (linkedNode != null) {
+//      return linkedNode.simplyBoundable_isSimplyBounded;
+//    }
+    return super.isSimplyBounded;
+  }
+
+  @override
   bool get isValidMixin {
     if (hasReferenceToSuper) {
       return false;
@@ -863,19 +870,18 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@method');
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
-        return _methods = linkedNode.classOrMixinDeclaration_members
-            .where((node) => node.kind == LinkedNodeKind.methodDeclaration)
-            .where((node) => node.methodDeclaration_propertyKeyword == 0)
-            .map((node) {
-          var name = context.getSimpleName(node.methodDeclaration_name);
-          var reference = containerRef.getChild(name);
-          return MethodElementImpl.forLinkedNode(reference, node, this);
-        }).toList();
-      } else {
-        return _methods = const <MethodElement>[];
-      }
+      return _methods = context
+          .getMethods(linkedNode)
+          .where((node) => node.propertyKeyword == null)
+          .map((node) {
+        var name = node.name.name;
+        var reference = containerRef.getChild(name);
+        if (reference.element == null) {
+          reference.node2 = node;
+          MethodElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as MethodElement;
+      }).toList();
     }
 
     if (_unlinkedClass != null) {
@@ -933,17 +939,15 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      LinkedNode withClause;
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-        withClause = linkedNode.classDeclaration_withClause;
-      } else {
-        withClause = linkedNode.classTypeAlias_withClause;
-      }
+      var withClause = context.getWithClause(linkedNode);
       if (withClause != null) {
-        return _mixins = withClause.withClause_mixinTypes
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        return _mixins = withClause.mixinTypes
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
+            .where(_isInterfaceTypeInterface)
             .toList();
+      } else {
+        return _mixins = const [];
       }
     } else if (_unlinkedClass != null) {
       var unlinkedMixins = _unlinkedClass.mixins;
@@ -1013,37 +1017,31 @@
 
   @override
   InterfaceType get supertype {
-    if (_supertype == null) {
-      if (linkedNode != null) {
-        LinkedNode superclass;
-        if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-          superclass = linkedNode
-              .classDeclaration_extendsClause?.extendsClause_superclass;
-        } else {
-          superclass = linkedNode.classTypeAlias_superclass;
-        }
-        if (superclass != null) {
-          var context = enclosingUnit.linkedContext;
-          _supertype = context.getInterfaceType(superclass.typeName_type);
-        } else if (!linkedNode.classDeclaration_isDartObject) {
-          _supertype = context.typeProvider.objectType;
-        }
-      } else if (_unlinkedClass != null) {
-        if (_unlinkedClass.supertype != null) {
-          DartType type = enclosingUnit.resynthesizerContext
-              .resolveTypeRef(this, _unlinkedClass.supertype);
-          if (_isInterfaceTypeClass(type)) {
-            _supertype = type;
-          } else {
-            _supertype = context.typeProvider.objectType;
-          }
-        } else if (_unlinkedClass.hasNoSupertype) {
-          return null;
+    if (_supertype != null) return _supertype;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var type = context.getSuperclass(linkedNode)?.type;
+      if (_isInterfaceTypeClass(type)) {
+        return _supertype = type;
+      }
+      return _supertype = this.context.typeProvider.objectType;
+    } else if (_unlinkedClass != null) {
+      if (_unlinkedClass.supertype != null) {
+        DartType type = enclosingUnit.resynthesizerContext
+            .resolveTypeRef(this, _unlinkedClass.supertype);
+        if (_isInterfaceTypeClass(type)) {
+          _supertype = type;
         } else {
           _supertype = context.typeProvider.objectType;
         }
+      } else if (_unlinkedClass.hasNoSupertype) {
+        return null;
+      } else {
+        _supertype = context.typeProvider.objectType;
       }
     }
+
     return _supertype;
   }
 
@@ -1069,17 +1067,21 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
+      var typeParameters = context.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      return _typeParameterElements = typeParameters.map((node) {
-        var name = context.getSimpleName(node.typeParameter_name);
+      return _typeParameterElements = typeParameters.typeParameters.map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as TypeParameterElementImpl;
       }).toList();
     }
+
     return super.typeParameters;
   }
 
@@ -1308,9 +1310,9 @@
     var accessorList = <PropertyAccessorElementImpl>[];
     var fieldList = <FieldElementImpl>[];
 
-    var fields = context.classFields(linkedNode);
+    var fields = context.getFields(linkedNode);
     for (var field in fields) {
-      var name = context.getVariableName(field);
+      var name = field.name.name;
       var fieldElement = FieldElementImpl.forLinkedNodeFactory(
         this,
         reference.getChild('@field').getChild(name),
@@ -1324,44 +1326,43 @@
       }
     }
 
-    for (var node in linkedNode.classOrMixinDeclaration_members) {
-      if (node.kind == LinkedNodeKind.methodDeclaration) {
-        var isGetter = context.isGetterMethod(node);
-        var isSetter = context.isSetterMethod(node);
-        if (!isGetter && !isSetter) continue;
+    var methods = context.getMethods(linkedNode);
+    for (var method in methods) {
+      var isGetter = method.isGetter;
+      var isSetter = method.isSetter;
+      if (!isGetter && !isSetter) continue;
 
-        var name = context.getMethodName(node);
-        var containerRef = isGetter
-            ? reference.getChild('@getter')
-            : reference.getChild('@setter');
+      var name = method.name.name;
+      var containerRef = isGetter
+          ? reference.getChild('@getter')
+          : reference.getChild('@setter');
 
-        var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-          this,
-          containerRef.getChild(name),
-          node,
-        );
-        accessorList.add(accessorElement);
+      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
+        this,
+        containerRef.getChild(name),
+        method,
+      );
+      accessorList.add(accessorElement);
 
-        var fieldRef = reference.getChild('@field').getChild(name);
-        FieldElementImpl field = fieldRef.element;
-        if (field == null) {
-          field = new FieldElementImpl(name, -1);
-          fieldRef.element = field;
-          field.enclosingElement = this;
-          field.isSynthetic = true;
-          field.isFinal = isGetter;
-          field.isStatic = accessorElement.isStatic;
-          fieldList.add(field);
-        } else {
-          field.isFinal = false;
-        }
+      var fieldRef = reference.getChild('@field').getChild(name);
+      FieldElementImpl field = fieldRef.element;
+      if (field == null) {
+        field = new FieldElementImpl(name, -1);
+        fieldRef.element = field;
+        field.enclosingElement = this;
+        field.isSynthetic = true;
+        field.isFinal = isGetter;
+        field.isStatic = accessorElement.isStatic;
+        fieldList.add(field);
+      } else {
+        field.isFinal = false;
+      }
 
-        accessorElement.variable = field;
-        if (isGetter) {
-          field.getter = accessorElement;
-        } else {
-          field.setter = accessorElement;
-        }
+      accessorElement.variable = field;
+      if (isGetter) {
+        field.getter = accessorElement;
+      } else {
+        field.setter = accessorElement;
       }
     }
 
@@ -1640,7 +1641,7 @@
         super(null, -1);
 
   CompilationUnitElementImpl.forLinkedNode(LibraryElementImpl enclosingLibrary,
-      this.linkedContext, Reference reference, LinkedNode linkedNode)
+      this.linkedContext, Reference reference, CompilationUnit linkedNode)
       : resynthesizerContext = null,
         _unlinkedUnit = null,
         _unlinkedPart = null,
@@ -1657,25 +1658,26 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
+    if (_accessors != null) return _accessors;
+
     if (linkedNode != null) {
-      if (_accessors != null) return _accessors;
       _createPropertiesAndAccessors(this);
       assert(_accessors != null);
       return _accessors;
     }
-    if (_accessors == null) {
-      if (_unlinkedUnit != null) {
-        _explicitTopLevelAccessors ??=
-            resynthesizerContext.buildTopLevelAccessors();
-        _explicitTopLevelVariables ??=
-            resynthesizerContext.buildTopLevelVariables();
-      }
-      if (_explicitTopLevelAccessors != null) {
-        _accessors = <PropertyAccessorElementImpl>[]
-          ..addAll(_explicitTopLevelAccessors.accessors)
-          ..addAll(_explicitTopLevelVariables.implicitAccessors);
-      }
+
+    if (_unlinkedUnit != null) {
+      _explicitTopLevelAccessors ??=
+          resynthesizerContext.buildTopLevelAccessors();
+      _explicitTopLevelVariables ??=
+          resynthesizerContext.buildTopLevelVariables();
     }
+    if (_explicitTopLevelAccessors != null) {
+      _accessors = <PropertyAccessorElementImpl>[]
+        ..addAll(_explicitTopLevelAccessors.accessors)
+        ..addAll(_explicitTopLevelVariables.implicitAccessors);
+    }
+
     return _accessors ?? const <PropertyAccessorElement>[];
   }
 
@@ -1715,25 +1717,28 @@
 
   @override
   List<ClassElement> get enums {
+    if (_enums != null) return _enums;
+
     if (linkedNode != null) {
-      if (_enums != null) return _enums;
-      var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@enum');
-      _enums = linkedNode.compilationUnit_declarations
-          .where((node) => node.kind == LinkedNodeKind.enumDeclaration)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      CompilationUnit linkedNode = this.linkedNode;
+      _enums = linkedNode.declarations.whereType<EnumDeclaration>().map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return EnumElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          EnumElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as EnumElementImpl;
       }).toList();
     }
+
     if (_unlinkedUnit != null) {
-      _enums ??= _unlinkedUnit.enums
+      return _enums = _unlinkedUnit.enums
           .map((e) => new EnumElementImpl.forSerialized(e, this))
           .toList(growable: false);
     }
-    return _enums ?? const <ClassElement>[];
+    return _enums ??= const <ClassElement>[];
   }
 
   /// Set the enums contained in this compilation unit to the given [enums].
@@ -1750,17 +1755,19 @@
     if (_functions != null) return _functions;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@function');
-      _functions = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.functionDeclaration &&
-              !context.isGetterFunction(node) &&
-              !context.isSetterFunction(node))
+      return _functions = linkedNode.declarations
+          .whereType<FunctionDeclaration>()
+          .where((node) => !node.isGetter && !node.isSetter)
           .map((node) {
-        var name = context.getUnitMemberName(node);
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        return FunctionElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          FunctionElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as FunctionElementImpl;
       }).toList();
     } else if (_unlinkedUnit != null) {
       _functions = _unlinkedUnit.executables
@@ -1785,16 +1792,24 @@
     if (_typeAliases != null) return _typeAliases;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@typeAlias');
-      _typeAliases = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.functionTypeAlias ||
-              node.kind == LinkedNodeKind.genericTypeAlias)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      return _typeAliases = linkedNode.declarations.where((node) {
+        return node is FunctionTypeAlias || node is GenericTypeAlias;
+      }).map((node) {
+        String name;
+        if (node is FunctionTypeAlias) {
+          name = node.name.name;
+        } else {
+          name = (node as GenericTypeAlias).name.name;
+        }
+
         var reference = containerRef.getChild(name);
-        return GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as GenericTypeAliasElement;
       }).toList();
     }
 
@@ -1843,15 +1858,17 @@
     if (_mixins != null) return _mixins;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
-      return _mixins = linkedNode.compilationUnit_declarations
-          .where((node) => node.kind == LinkedNodeKind.mixinDeclaration)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      var declarations = linkedNode.declarations;
+      return _mixins = declarations.whereType<MixinDeclaration>().map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return MixinElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          MixinElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as MixinElementImpl;
       }).toList();
     }
 
@@ -1937,18 +1954,26 @@
     if (_types != null) return _types;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
-      return _types = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.classDeclaration ||
-              node.kind == LinkedNodeKind.classTypeAlias)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      _types = <ClassElement>[];
+      for (var node in linkedNode.declarations) {
+        String name;
+        if (node is ClassDeclaration) {
+          name = node.name.name;
+        } else if (node is ClassTypeAlias) {
+          name = node.name.name;
+        } else {
+          continue;
+        }
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return ClassElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+        if (reference.element == null) {
+          reference.node2 = node;
+          ClassElementImpl.forLinkedNode(this, reference, node);
+        }
+        _types.add(reference.element);
+      }
+      return _types;
     }
 
     if (_unlinkedUnit != null) {
@@ -2131,9 +2156,12 @@
       var variableList = <TopLevelVariableElementImpl>[];
       variableMap[unit] = variableList;
 
-      var variables = context.topLevelVariables(unit.linkedNode);
+      var unitNode = unit.linkedContext.unit_withDeclarations;
+      var unitDeclarations = unitNode.declarations;
+
+      var variables = context.topLevelVariables(unitNode);
       for (var variable in variables) {
-        var name = context.getVariableName(variable);
+        var name = variable.name.name;
         var reference = unit.reference.getChild('@variable').getChild(name);
         var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
           unit,
@@ -2148,13 +2176,13 @@
         }
       }
 
-      for (var node in unit.linkedNode.compilationUnit_declarations) {
-        if (node.kind == LinkedNodeKind.functionDeclaration) {
-          var isGetter = context.isGetterFunction(node);
-          var isSetter = context.isSetterFunction(node);
+      for (var node in unitDeclarations) {
+        if (node is FunctionDeclaration) {
+          var isGetter = node.isGetter;
+          var isSetter = node.isSetter;
           if (!isGetter && !isSetter) continue;
 
-          var name = context.getUnitMemberName(node);
+          var name = node.name.name;
           var containerRef = isGetter
               ? unit.reference.getChild('@getter')
               : unit.reference.getChild('@setter');
@@ -2210,7 +2238,7 @@
   ConstFieldElementImpl(String name, int offset) : super(name, offset);
 
   ConstFieldElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created field element to have the given [name].
@@ -2232,7 +2260,7 @@
       : super(enumElement);
 
   ConstFieldElementImpl_EnumValue.forLinkedNode(EnumElementImpl enumElement,
-      Reference reference, LinkedNode linkedNode, this._index)
+      Reference reference, AstNode linkedNode, this._index)
       : _unlinkedEnumValue = null,
         super.forLinkedNode(enumElement, reference, linkedNode);
 
@@ -2242,9 +2270,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedEnumValue != null) {
       return _unlinkedEnumValue.documentationComment?.text;
@@ -2289,9 +2317,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.enumConstantDeclaration_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
     int offset = super.nameOffset;
     if (offset == -1) {
@@ -2350,7 +2376,7 @@
   }
 
   ConstFieldElementImpl_ofEnum.forLinkedNode(
-      this._enum, Reference reference, LinkedNode linkedNode)
+      this._enum, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(_enum, reference, linkedNode);
 
   @override
@@ -2429,8 +2455,8 @@
   /// and [offset].
   ConstructorElementImpl(String name, int offset) : super(name, offset);
 
-  ConstructorElementImpl.forLinkedNode(Reference reference,
-      LinkedNode linkedNode, ClassElementImpl enclosingClass)
+  ConstructorElementImpl.forLinkedNode(ClassElementImpl enclosingClass,
+      Reference reference, ConstructorDeclaration linkedNode)
       : super.forLinkedNode(enclosingClass, reference, linkedNode);
 
   /// Initialize a newly created constructor element to have the given [name].
@@ -2445,13 +2471,13 @@
   /// there are no initializers, or `null` if there was an error in the source.
   List<ConstructorInitializer> get constantInitializers {
     if (_constantInitializers == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        return _constantInitializers ??=
-            linkedNode.constructorDeclaration_initializers.map((node) {
-          return context.readNode(node) as ConstructorInitializer;
-        }).toList();
-      }
+//      if (linkedNode != null) {
+//        var context = enclosingUnit.linkedContext;
+//        return _constantInitializers ??=
+//            linkedNode.constructorDeclaration_initializers.map((node) {
+//          return context.readNode(node) as ConstructorInitializer;
+//        }).toList();
+//      }
 
       if (serializedExecutable != null) {
         _constantInitializers = serializedExecutable.constantInitializers
@@ -2493,7 +2519,8 @@
   @override
   bool get isConst {
     if (linkedNode != null) {
-      return linkedNode.constructorDeclaration_constKeyword != 0;
+      ConstructorDeclaration linkedNode = this.linkedNode;
+      return linkedNode.constKeyword != null;
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isConst;
@@ -2542,7 +2569,8 @@
   @override
   bool get isFactory {
     if (linkedNode != null) {
-      return linkedNode.constructorDeclaration_factoryKeyword != 0;
+      ConstructorDeclaration linkedNode = this.linkedNode;
+      return linkedNode.factoryKeyword != null;
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isFactory;
@@ -2599,24 +2627,24 @@
   @override
   ConstructorElement get redirectedConstructor {
     if (_redirectedConstructor == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        if (isFactory) {
-          var node = linkedNode.constructorDeclaration_redirectedConstructor;
-          if (node != null) {
-            ConstructorName ast = context.readNode(node);
-            return ast.staticElement;
-          }
-        } else {
-          for (var node in linkedNode.constructorDeclaration_initializers) {
-            if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) {
-              RedirectingConstructorInvocation ast = context.readNode(node);
-              return ast.staticElement;
-            }
-          }
-        }
-        return null;
-      }
+//      if (linkedNode != null) {
+//        var context = enclosingUnit.linkedContext;
+//        if (isFactory) {
+//          var node = linkedNode.constructorDeclaration_redirectedConstructor;
+//          if (node != null) {
+//            ConstructorName ast = context.readNode(node);
+//            return ast.staticElement;
+//          }
+//        } else {
+//          for (var node in linkedNode.constructorDeclaration_initializers) {
+//            if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) {
+//              RedirectingConstructorInvocation ast = context.readNode(node);
+//              return ast.staticElement;
+//            }
+//          }
+//        }
+//        return null;
+//      }
 
       if (serializedExecutable != null) {
         if (serializedExecutable.isRedirectedConstructor) {
@@ -2759,7 +2787,7 @@
       : super(name, offset);
 
   ConstTopLevelVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created top-level variable element to have the given
@@ -2850,7 +2878,7 @@
       : super(name, nameOffset);
 
   DefaultFieldFormalParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -2872,7 +2900,7 @@
       : super(name, nameOffset);
 
   DefaultParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -2938,6 +2966,10 @@
   /// literal.
   static String _LITERAL_VARIABLE_NAME = "literal";
 
+  /// The name of the top-level variable used to mark a type as having
+  /// "optional" type arguments.
+  static String _OPTIONAL_TYPE_ARGS_VARIABLE_NAME = "optionalTypeArgs";
+
   /// The name of the top-level variable used to mark a function as running
   /// a single test.
   static String _IS_TEST_VARIABLE_NAME = "isTest";
@@ -3087,6 +3119,12 @@
       element.library?.name == _META_LIB_NAME;
 
   @override
+  bool get isOptionalTypeArgs =>
+      element is PropertyAccessorElement &&
+      element.name == _OPTIONAL_TYPE_ARGS_VARIABLE_NAME &&
+      element.library?.name == _META_LIB_NAME;
+
+  @override
   bool get isOverride =>
       element is PropertyAccessorElement &&
       element.name == _OVERRIDE_VARIABLE_NAME &&
@@ -3168,7 +3206,7 @@
   ElementImpl _enclosingElement;
 
   Reference reference;
-  final LinkedNode linkedNode;
+  final AstNode linkedNode;
 
   /// The name of this element.
   String _name;
@@ -3358,6 +3396,18 @@
   }
 
   @override
+  bool get hasOptionalTypeArgs {
+    var metadata = this.metadata;
+    for (var i = 0; i < metadata.length; i++) {
+      var annotation = metadata[i];
+      if (annotation.isOptionalTypeArgs) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
   bool get hasOverride {
     var metadata = this.metadata;
     for (var i = 0; i < metadata.length; i++) {
@@ -3492,6 +3542,10 @@
   @override
   Source get librarySource => library?.source;
 
+  LinkedUnitContext get linkedContext {
+    return _enclosingElement.linkedContext;
+  }
+
   @override
   ElementLocation get location {
     if (_cachedLocation == null) {
@@ -3506,7 +3560,7 @@
   List<ElementAnnotation> get metadata {
     if (linkedNode != null) {
       if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
+      var metadata = linkedContext.getMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
     return _metadata ?? const <ElementAnnotation>[];
@@ -3720,7 +3774,7 @@
 
   /// Return annotations for the given [nodeList] in the [unit].
   List<ElementAnnotation> _buildAnnotations2(
-      CompilationUnitElementImpl unit, List<LinkedNode> nodeList) {
+      CompilationUnitElementImpl unit, List<Annotation> nodeList) {
     var length = nodeList.length;
     if (length == 0) {
       return const <ElementAnnotation>[];
@@ -3728,7 +3782,7 @@
 
     var annotations = new List<ElementAnnotation>(length);
     for (int i = 0; i < length; i++) {
-      var ast = unit.linkedContext.readNode(nodeList[i]);
+      var ast = nodeList[i];
       annotations[i] = ElementAnnotationImpl(enclosingUnit)
         ..annotationAst = ast;
     }
@@ -3922,7 +3976,7 @@
         super(name, offset);
 
   EnumElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
+      Reference reference, EnumDeclaration linkedNode)
       : _unlinkedEnum = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -3966,7 +4020,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.codeRange?.length;
@@ -3977,7 +4031,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.codeRange?.offset;
@@ -3997,9 +4051,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.documentationComment?.text;
@@ -4209,13 +4263,12 @@
     }
 
     // Build fields for all enum constants.
-    var constants = linkedNode.enumDeclaration_constants;
+    var containerRef = this.reference.getChild('@constant');
+    var constants = linkedContext.getEnumConstants(linkedNode);
     for (var i = 0; i < constants.length; ++i) {
       var constant = constants[i];
-      var name = enclosingUnit.linkedContext.getSimpleName(
-        constant.enumConstantDeclaration_name,
-      );
-      var reference = this.reference.getChild('@constant').getChild(name);
+      var name = constant.name.name;
+      var reference = containerRef.getChild(name);
       var field = new ConstFieldElementImpl_EnumValue.forLinkedNode(
           this, reference, constant, i);
       fields.add(field);
@@ -4256,7 +4309,7 @@
 
   /// Initialize using the given linked node.
   ExecutableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : serializedExecutable = null,
         super.forLinkedNode(enclosing, reference, linkedNode) {
     reference.element = this;
@@ -4281,7 +4334,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.codeRange?.length;
@@ -4292,7 +4345,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.codeRange?.offset;
@@ -4319,9 +4372,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.documentationComment?.text;
@@ -4358,6 +4411,9 @@
 
   @override
   bool get isAbstract {
+    if (linkedNode != null) {
+      return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode);
+    }
     if (serializedExecutable != null) {
       return serializedExecutable.isAbstract;
     }
@@ -4426,9 +4482,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.namedCompilationUnitMember_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
 
     int offset = super.nameOffset;
@@ -4440,24 +4494,26 @@
 
   @override
   List<ParameterElement> get parameters {
-    if (_parameters == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        var containerRef = reference.getChild('@parameter');
-        var formalParameters = context.getFormalParameters(linkedNode);
-        _parameters = ParameterElementImpl.forLinkedNodeList(
-          this,
-          context,
-          containerRef,
-          formalParameters,
-        );
-      }
-      if (serializedExecutable != null) {
-        _parameters = ParameterElementImpl.resynthesizeList(
-            serializedExecutable.parameters, this);
-      }
+    if (_parameters != null) return _parameters;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var containerRef = reference.getChild('@parameter');
+      var formalParameters = context.getFormalParameters(linkedNode);
+      _parameters = ParameterElementImpl.forLinkedNodeList(
+        this,
+        context,
+        containerRef,
+        formalParameters,
+      );
     }
-    return _parameters ?? const <ParameterElement>[];
+
+    if (serializedExecutable != null) {
+      _parameters = ParameterElementImpl.resynthesizeList(
+          serializedExecutable.parameters, this);
+    }
+
+    return _parameters ??= const <ParameterElement>[];
   }
 
   /// Set the parameters defined by this executable element to the given
@@ -4473,8 +4529,10 @@
   @override
   DartType get returnType {
     if (linkedNode != null) {
-      return _returnType ??=
-          enclosingUnit.linkedContext.getReturnType(linkedNode);
+      if (_returnType != null) return _returnType;
+      return _returnType = enclosingUnit.linkedContext.getReturnType(
+        linkedNode,
+      );
     }
     if (serializedExecutable != null &&
         _declaredReturnType == null &&
@@ -4624,7 +4682,7 @@
         super(null, offset);
 
   ExportElementImpl.forLinkedNode(
-      LibraryElementImpl enclosing, LinkedNode linkedNode)
+      LibraryElementImpl enclosing, ExportDirective linkedNode)
       : _unlinkedExportPublic = null,
         _unlinkedExportNonPublic = null,
         super.forLinkedNode(enclosing, null, linkedNode);
@@ -4639,9 +4697,10 @@
     if (_combinators != null) return _combinators;
 
     if (linkedNode != null) {
+      ExportDirective node = linkedNode;
       return _combinators = ImportElementImpl._buildCombinators2(
         enclosingUnit.linkedContext,
-        linkedNode,
+        node.combinators,
       );
     }
 
@@ -4670,11 +4729,7 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      var relativeUriStr = context.getStringContent(
-        linkedNode.uriBasedDirective_uri,
-      );
-      var relativeUri = Uri.parse(relativeUriStr);
-      var uri = resolveRelativeUri(librarySource.uri, relativeUri);
+      var uri = context.directiveUri(librarySource.uri, linkedNode);
       var elementFactory = context.bundleContext.elementFactory;
       return _exportedLibrary = elementFactory.libraryOfUri('$uri');
     }
@@ -4700,11 +4755,6 @@
 
   @override
   List<ElementAnnotation> get metadata {
-    if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
-      return _metadata = _buildAnnotations2(enclosingUnit, metadata);
-    }
     if (_metadata == null) {
       if (_unlinkedExportNonPublic != null) {
         return _metadata = _buildAnnotations(library.definingCompilationUnit,
@@ -4789,7 +4839,7 @@
   FieldElementImpl(String name, int offset) : super(name, offset);
 
   FieldElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
@@ -4809,7 +4859,7 @@
   }
 
   factory FieldElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
+      ElementImpl enclosing, Reference reference, AstNode linkedNode) {
     if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) {
       return ConstFieldElementImpl.forLinkedNode(
         enclosing,
@@ -4850,14 +4900,13 @@
   @override
   bool get isCovariant {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.variableDeclaration) {
-        return linkedNode.variableDeclaration_declaration.isCovariant;
-      }
-      return false;
+      return linkedContext.isCovariantField(linkedNode);
     }
+
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.isCovariant;
     }
+
     return hasModifier(Modifier.COVARIANT);
   }
 
@@ -4922,7 +4971,7 @@
       : super(name, nameOffset);
 
   FieldFormalParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -5001,8 +5050,8 @@
   /// [offset].
   FunctionElementImpl(String name, int offset) : super(name, offset);
 
-  FunctionElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+  FunctionElementImpl.forLinkedNode(ElementImpl enclosing, Reference reference,
+      FunctionDeclaration linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created function element to have the given [name].
@@ -5030,6 +5079,14 @@
   }
 
   @override
+  String get displayName {
+    if (linkedNode != null) {
+      return reference.name;
+    }
+    return super.displayName;
+  }
+
+  @override
   TypeParameterizedElementMixin get enclosingTypeParameterContext {
     return (enclosingElement as ElementImpl).typeParameterContext;
   }
@@ -5056,20 +5113,18 @@
   ElementKind get kind => ElementKind.FUNCTION;
 
   @override
-  DartType get returnType {
+  String get name {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getType(
-        linkedNode.functionDeclaration_returnType2,
-      );
+      return reference.name;
     }
-    return super.returnType;
+    return super.name;
   }
 
   @override
   void set returnType(DartType returnType) {
-    if (linkedNode != null) {
-      enclosingUnit.linkedContext.setReturnType(linkedNode, returnType);
-    }
+//    if (linkedNode != null) {
+//      enclosingUnit.linkedContext.setReturnType(linkedNode, returnType);
+//    }
     super.returnType = returnType;
   }
 
@@ -5242,7 +5297,7 @@
   FunctionType _type;
 
   GenericFunctionTypeElementImpl.forLinkedNode(
-      ElementImpl enclosingElement, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosingElement, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosingElement, reference, linkedNode);
 
   /// Initialize a newly created function element to have no name and the given
@@ -5335,7 +5390,7 @@
   @override
   List<TypeParameterElement> get typeParameters {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.functionTypeAlias) {
+      if (linkedNode is FunctionTypeAlias) {
         return const <TypeParameterElement>[];
       }
     }
@@ -5425,7 +5480,7 @@
   GenericTypeAliasElementImpl.forLinkedNode(
       CompilationUnitElementImpl enclosingUnit,
       Reference reference,
-      LinkedNode linkedNode)
+      AstNode linkedNode)
       : _unlinkedTypedef = null,
         super.forLinkedNode(enclosingUnit, reference, linkedNode);
 
@@ -5442,7 +5497,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.codeRange?.length;
@@ -5453,7 +5508,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.codeRange?.offset;
@@ -5467,9 +5522,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.documentationComment?.text;
@@ -5493,11 +5548,12 @@
     if (_function != null) return _function;
 
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.genericTypeAlias) {
-        _function = GenericFunctionTypeElementImpl.forLinkedNode(
+      if (linkedNode is GenericTypeAlias) {
+        var context = enclosingUnit.linkedContext;
+        return _function = GenericFunctionTypeElementImpl.forLinkedNode(
           this,
           reference.getChild('@function'),
-          linkedNode.genericTypeAlias_functionType,
+          context.getGeneticTypeAliasFunction(linkedNode),
         );
       } else {
         return _function = GenericFunctionTypeElementImpl.forLinkedNode(
@@ -5506,7 +5562,6 @@
           linkedNode,
         );
       }
-      return _function;
     }
 
     if (_unlinkedTypedef != null) {
@@ -5546,6 +5601,14 @@
   }
 
   @override
+  bool get isSimplyBounded {
+//    if (linkedNode != null) {
+//      return linkedNode.simplyBoundable_isSimplyBounded;
+//    }
+    return super.isSimplyBounded;
+  }
+
+  @override
   ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
 
   @override
@@ -5706,7 +5769,7 @@
   final UnlinkedCombinator _unlinkedCombinator;
 
   final LinkedUnitContext linkedContext;
-  final LinkedNode linkedNode;
+  final HideCombinator linkedNode;
 
   /// The names that are not to be made visible in the importing library even if
   /// they are defined in the imported library.
@@ -5730,9 +5793,7 @@
     if (_hiddenNames != null) return _hiddenNames;
 
     if (linkedNode != null) {
-      return _hiddenNames = linkedNode.hideCombinator_hiddenNames
-          .map((node) => linkedContext.getSimpleName(node))
-          .toList();
+      return _hiddenNames = linkedNode.hiddenNames.map((i) => i.name).toList();
     }
 
     if (_unlinkedCombinator != null) {
@@ -5800,7 +5861,7 @@
         super(null, offset);
 
   ImportElementImpl.forLinkedNode(
-      LibraryElementImpl enclosing, LinkedNode linkedNode)
+      LibraryElementImpl enclosing, ImportDirective linkedNode)
       : _unlinkedImport = null,
         _linkedDependency = null,
         super.forLinkedNode(enclosing, null, linkedNode);
@@ -5815,9 +5876,10 @@
     if (_combinators != null) return _combinators;
 
     if (linkedNode != null) {
-      return _combinators = _buildCombinators2(
+      ImportDirective node = linkedNode;
+      return _combinators = ImportElementImpl._buildCombinators2(
         enclosingUnit.linkedContext,
-        linkedNode,
+        node.combinators,
       );
     }
 
@@ -5854,14 +5916,11 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      var relativeUriStr = context.getStringContent(
-        linkedNode.uriBasedDirective_uri,
-      );
-      var relativeUri = Uri.parse(relativeUriStr);
-      var uri = resolveRelativeUri(librarySource.uri, relativeUri);
+      var uri = context.directiveUri(librarySource.uri, linkedNode);
       var elementFactory = context.bundleContext.elementFactory;
       return _importedLibrary = elementFactory.libraryOfUri('$uri');
     }
+
     if (_linkedDependency != null) {
       if (_importedLibrary == null) {
         LibraryElementImpl library = enclosingElement as LibraryElementImpl;
@@ -5873,6 +5932,7 @@
         }
       }
     }
+
     return _importedLibrary;
   }
 
@@ -5884,7 +5944,8 @@
   @override
   bool get isDeferred {
     if (linkedNode != null) {
-      return linkedNode.importDirective_deferredKeyword != 0;
+      ImportDirective linkedNode = this.linkedNode;
+      return linkedNode.deferredKeyword != null;
     }
     if (_unlinkedImport != null) {
       return _unlinkedImport.isDeferred;
@@ -5905,11 +5966,6 @@
 
   @override
   List<ElementAnnotation> get metadata {
-    if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
-      return _metadata = _buildAnnotations2(enclosingUnit, metadata);
-    }
     if (_metadata == null) {
       if (_unlinkedImport != null) {
         return _metadata = _buildAnnotations(
@@ -5943,25 +5999,27 @@
   }
 
   PrefixElement get prefix {
-    if (_prefix == null) {
-      if (linkedNode != null) {
-        var prefix = linkedNode.importDirective_prefix;
-        if (prefix != null) {
-          var context = enclosingUnit.linkedContext;
-          var name = context.getSimpleName(prefix);
-          LibraryElementImpl library = enclosingElement as LibraryElementImpl;
-          _prefix = new PrefixElementImpl.forLinkedNode(
-            library,
-            library.reference.getChild('@prefix').getChild(name),
-            prefix,
-          );
-        }
-      }
-      if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) {
-        LibraryElementImpl library = enclosingElement as LibraryElementImpl;
-        _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
+    if (_prefix != null) return _prefix;
+
+    if (linkedNode != null) {
+      ImportDirective linkedNode = this.linkedNode;
+      var prefix = linkedNode.prefix;
+      if (prefix != null) {
+        var name = prefix.name;
+        var library = enclosingElement as LibraryElementImpl;
+        _prefix = new PrefixElementImpl.forLinkedNode(
+          library,
+          library.reference.getChild('@prefix').getChild(name),
+          prefix,
+        );
       }
     }
+
+    if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) {
+      LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+      _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
+    }
+
     return _prefix;
   }
 
@@ -6069,16 +6127,15 @@
   }
 
   static List<NamespaceCombinator> _buildCombinators2(
-      LinkedUnitContext context, LinkedNode linkedNode) {
-    return linkedNode.namespaceDirective_combinators.map((node) {
-      var kind = node.kind;
-      if (kind == LinkedNodeKind.hideCombinator) {
+      LinkedUnitContext context, List<Combinator> combinators) {
+    return combinators.map((node) {
+      if (node is HideCombinator) {
         return HideElementCombinatorImpl.forLinkedNode(context, node);
       }
-      if (kind == LinkedNodeKind.showCombinator) {
+      if (node is ShowCombinator) {
         return ShowElementCombinatorImpl.forLinkedNode(context, node);
       }
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }).toList();
   }
 }
@@ -6212,7 +6269,7 @@
       this.nameLength,
       this.linkedContext,
       Reference reference,
-      LinkedNode linkedNode)
+      CompilationUnit linkedNode)
       : resynthesizerContext = null,
         unlinkedDefiningUnit = null,
         super.forLinkedNode(null, reference, linkedNode) {
@@ -6311,14 +6368,17 @@
 
   @override
   Namespace get exportNamespace {
+    if (_exportNamespace != null) return _exportNamespace;
+
     if (linkedNode != null) {
-      if (_exportNamespace != null) return _exportNamespace;
       var elements = linkedContext.bundleContext.elementFactory;
       return _exportNamespace = elements.buildExportNamespace(source.uri);
     }
+
     if (resynthesizerContext != null) {
       _exportNamespace ??= resynthesizerContext.buildExportNamespace();
     }
+
     return _exportNamespace;
   }
 
@@ -6328,41 +6388,42 @@
 
   @override
   List<ExportElement> get exports {
-    if (_exports == null) {
-      if (linkedNode != null) {
-        return _exports = linkedNode.compilationUnit_directives
-            .where((node) => node.kind == LinkedNodeKind.exportDirective)
-            .map((node) {
-          return ExportElementImpl.forLinkedNode(this, node);
-        }).toList();
-      }
-      if (unlinkedDefiningUnit != null) {
-        List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
-            unlinkedDefiningUnit.exports;
-        List<UnlinkedExportPublic> unlinkedPublicExports =
-            unlinkedDefiningUnit.publicNamespace.exports;
-        assert(unlinkedDefiningUnit.exports.length ==
-            unlinkedPublicExports.length);
-        int length = unlinkedNonPublicExports.length;
-        if (length != 0) {
-          List<ExportElement> exports = new List<ExportElement>();
-          for (int i = 0; i < length; i++) {
-            UnlinkedExportPublic serializedExportPublic =
-                unlinkedPublicExports[i];
-            UnlinkedExportNonPublic serializedExportNonPublic =
-                unlinkedNonPublicExports[i];
-            ExportElementImpl exportElement =
-                new ExportElementImpl.forSerialized(
-                    serializedExportPublic, serializedExportNonPublic, library);
-            exports.add(exportElement);
-          }
-          _exports = exports;
-        } else {
-          _exports = const <ExportElement>[];
+    if (_exports != null) return _exports;
+
+    if (linkedNode != null) {
+      var unit = linkedContext.unit_withDirectives;
+      return _exports = unit.directives
+          .whereType<ExportDirective>()
+          .map((node) => ExportElementImpl.forLinkedNode(this, node))
+          .toList();
+    }
+
+    if (unlinkedDefiningUnit != null) {
+      List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
+          unlinkedDefiningUnit.exports;
+      List<UnlinkedExportPublic> unlinkedPublicExports =
+          unlinkedDefiningUnit.publicNamespace.exports;
+      assert(
+          unlinkedDefiningUnit.exports.length == unlinkedPublicExports.length);
+      int length = unlinkedNonPublicExports.length;
+      if (length != 0) {
+        List<ExportElement> exports = new List<ExportElement>();
+        for (int i = 0; i < length; i++) {
+          UnlinkedExportPublic serializedExportPublic =
+              unlinkedPublicExports[i];
+          UnlinkedExportNonPublic serializedExportNonPublic =
+              unlinkedNonPublicExports[i];
+          ExportElementImpl exportElement = new ExportElementImpl.forSerialized(
+              serializedExportPublic, serializedExportNonPublic, library);
+          exports.add(exportElement);
         }
+        _exports = exports;
+      } else {
+        _exports = const <ExportElement>[];
       }
     }
-    return _exports ?? const <ExportElement>[];
+
+    return _exports ??= const <ExportElement>[];
   }
 
   /// Set the specifications of all of the exports defined in this library to
@@ -6424,20 +6485,30 @@
 
   @override
   List<ImportElement> get imports {
-    if (_imports == null) {
-      if (linkedNode != null) {
-        return _imports = linkedNode.compilationUnit_directives
-            .where((node) => node.kind == LinkedNodeKind.importDirective)
-            .map((node) {
-          return ImportElementImpl.forLinkedNode(this, node);
-        }).toList();
+    if (_imports != null) return _imports;
+
+    if (linkedNode != null) {
+      var unit = linkedContext.unit_withDirectives;
+      _imports = unit.directives
+          .whereType<ImportDirective>()
+          .map((node) => ImportElementImpl.forLinkedNode(this, node))
+          .toList();
+      var hasCore = _imports.any((import) => import.importedLibrary.isDartCore);
+      if (!hasCore) {
+        var elements = linkedContext.bundleContext.elementFactory;
+        _imports.add(ImportElementImpl(-1)
+          ..importedLibrary = elements.libraryOfUri('dart:core')
+          ..isSynthetic = true);
       }
-      if (unlinkedDefiningUnit != null) {
-        _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports,
-            resynthesizerContext.linkedLibrary.importDependencies);
-      }
+      return _imports;
     }
-    return _imports ?? const <ImportElement>[];
+
+    if (unlinkedDefiningUnit != null) {
+      _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports,
+          resynthesizerContext.linkedLibrary.importDependencies);
+    }
+
+    return _imports ??= const <ImportElement>[];
   }
 
   /// Set the specifications of all of the imports defined in this library to
@@ -6599,21 +6670,19 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    if (_metadata != null) return _metadata;
+
     if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      CompilationUnitElementImpl enclosingUnit = _definingCompilationUnit;
-      var context = enclosingUnit.linkedContext;
-      var metadata = context.getLibraryMetadataOrEmpty(linkedNode);
+      var metadata = linkedContext.getLibraryMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
-    if (_metadata == null) {
-      if (unlinkedDefiningUnit != null) {
-        _metadata = _buildAnnotations(
-            _definingCompilationUnit as CompilationUnitElementImpl,
-            unlinkedDefiningUnit.libraryAnnotations);
-        return _metadata;
-      }
+
+    if (unlinkedDefiningUnit != null) {
+      return _metadata = _buildAnnotations(
+          _definingCompilationUnit as CompilationUnitElementImpl,
+          unlinkedDefiningUnit.libraryAnnotations);
     }
+
     return super.metadata;
   }
 
@@ -6990,8 +7059,8 @@
   /// given [offset].
   MethodElementImpl(String name, int offset) : super(name, offset);
 
-  MethodElementImpl.forLinkedNode(Reference reference, LinkedNode linkedNode,
-      ClassElementImpl enclosingClass)
+  MethodElementImpl.forLinkedNode(ClassElementImpl enclosingClass,
+      Reference reference, MethodDeclaration linkedNode)
       : super.forLinkedNode(enclosingClass, reference, linkedNode);
 
   /// Initialize a newly created method element to have the given [name].
@@ -7025,14 +7094,6 @@
       super.enclosingElement as ClassElementImpl;
 
   @override
-  bool get isAbstract {
-    if (linkedNode != null) {
-      return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode);
-    }
-    return super.isAbstract;
-  }
-
-  @override
   bool get isOperator {
     String name = displayName;
     if (name.isEmpty) {
@@ -7048,7 +7109,7 @@
   @override
   bool get isStatic {
     if (linkedNode != null) {
-      return linkedNode.methodDeclaration_modifierKeyword != 0;
+      return enclosingUnit.linkedContext.isStatic(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isStatic;
@@ -7076,11 +7137,11 @@
 
   @override
   DartType get returnType {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getType(
-        linkedNode.methodDeclaration_returnType2,
-      );
-    }
+//    if (linkedNode != null) {
+//      return enclosingUnit.linkedContext.getType(
+//        linkedNode.methodDeclaration_returnType2,
+//      );
+//    }
     return super.returnType;
   }
 
@@ -7151,10 +7212,8 @@
   MixinElementImpl(String name, int offset) : super(name, offset);
 
   MixinElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
-      : super.forLinkedNode(enclosing, reference, linkedNode) {
-    enclosing.linkedContext.loadClassMemberReferences(reference);
-  }
+      Reference reference, MixinDeclaration linkedNode)
+      : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
   MixinElementImpl.forNode(Identifier name) : super.forNode(name);
@@ -7179,12 +7238,11 @@
 
     if (linkedNode != null) {
       List<InterfaceType> constraints;
-      var onClause = linkedNode.mixinDeclaration_onClause;
+      var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode);
       if (onClause != null) {
-        var context = enclosingUnit.linkedContext;
-        constraints = onClause.onClause_superclassConstraints
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        constraints = onClause.superclassConstraints
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
             .toList();
       }
       if (constraints == null || constraints.isEmpty) {
@@ -7443,6 +7501,9 @@
   bool get hasLiteral => false;
 
   @override
+  bool get hasOptionalTypeArgs => false;
+
+  @override
   bool get hasOverride => false;
 
   @override
@@ -7651,7 +7712,7 @@
         super(name, offset);
 
   NonParameterVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : _unlinkedVariable = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -7668,7 +7729,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.codeRange?.length;
@@ -7679,7 +7740,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.codeRange?.offset;
@@ -7690,9 +7751,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.variableDeclaration_declaration.comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.documentationComment?.text;
@@ -7778,9 +7839,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleName(
-        linkedNode.variableDeclaration_name,
-      );
+      return reference.name;
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.name;
@@ -7791,10 +7850,9 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.variableDeclaration_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
+
     int offset = super.nameOffset;
     if (offset == 0) {
       if (_unlinkedVariable != null) {
@@ -7864,28 +7922,23 @@
         super(name, nameOffset);
 
   ParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, FormalParameter linkedNode)
       : unlinkedParam = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
   factory ParameterElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
-    var kind = linkedNode.kind;
-    if (kind == LinkedNodeKind.fieldFormalParameter) {
+      ElementImpl enclosing, Reference reference, FormalParameter node) {
+    if (node is FieldFormalParameter) {
       return FieldFormalParameterElementImpl.forLinkedNode(
         enclosing,
         reference,
-        linkedNode,
+        node,
       );
-    } else if (kind == LinkedNodeKind.functionTypedFormalParameter ||
-        kind == LinkedNodeKind.simpleFormalParameter) {
-      return ParameterElementImpl.forLinkedNode(
-        enclosing,
-        reference,
-        linkedNode,
-      );
+    } else if (node is FunctionTypedFormalParameter ||
+        node is SimpleFormalParameter) {
+      return ParameterElementImpl.forLinkedNode(enclosing, reference, node);
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
@@ -7938,7 +7991,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (unlinkedParam != null) {
       return unlinkedParam.codeRange?.length;
@@ -7949,7 +8002,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (unlinkedParam != null) {
       return unlinkedParam.codeRange?.offset;
@@ -8046,13 +8099,13 @@
 
   @override
   bool get isCovariant {
-    if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-        var parameter = linkedNode.defaultFormalParameter_parameter;
-        return parameter.normalFormalParameter_isCovariant;
-      }
-      return linkedNode.normalFormalParameter_isCovariant;
-    }
+//    if (linkedNode != null) {
+//      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
+//        var parameter = linkedNode.defaultFormalParameter_parameter;
+//        return parameter.normalFormalParameter_isCovariant;
+//      }
+//      return linkedNode.normalFormalParameter_isCovariant;
+//    }
     if (isExplicitlyCovariant || inheritsCovariant) {
       return true;
     }
@@ -8077,7 +8130,8 @@
   @override
   bool get isFinal {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.isFinal(linkedNode);
+      FormalParameter linkedNode = this.linkedNode;
+      return linkedNode.isFinal;
     }
     if (unlinkedParam != null) {
       return unlinkedParam.isFinal;
@@ -8126,9 +8180,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.normalFormalParameter_identifier,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
 
     int offset = super.nameOffset;
@@ -8151,14 +8203,9 @@
     if (_parameterKind != null) return _parameterKind;
 
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-        if (linkedNode.defaultFormalParameter_isNamed) {
-          return _parameterKind = ParameterKind.NAMED;
-        } else {
-          return _parameterKind = ParameterKind.POSITIONAL;
-        }
-      }
-      return _parameterKind = ParameterKind.REQUIRED;
+      FormalParameter linkedNode = this.linkedNode;
+      // ignore: deprecated_member_use_from_same_package
+      return linkedNode.kind;
     }
     if (unlinkedParam != null) {
       switch (unlinkedParam.kind) {
@@ -8191,7 +8238,7 @@
     if (linkedNode != null) {
       if (_type != null) return _type;
       var context = enclosingUnit.linkedContext;
-      return _type = context.getFormalParameterType(linkedNode);
+      return _type = context.getType(linkedNode);
     }
     _resynthesizeTypeAndParameters();
     return super.type;
@@ -8305,18 +8352,18 @@
       ElementImpl enclosing,
       LinkedUnitContext context,
       Reference containerRef,
-      List<LinkedNode> formalParameters) {
+      List<FormalParameter> formalParameters) {
     if (formalParameters == null) {
       return const [];
     }
 
     return formalParameters.map((node) {
-      if (node.kind == LinkedNodeKind.defaultFormalParameter) {
-        var parameterNode = node.defaultFormalParameter_parameter;
-        var name = context.getFormalParameterName(parameterNode);
+      if (node is DefaultFormalParameter) {
+        NormalFormalParameter parameterNode = node.parameter;
+        var name = parameterNode.identifier.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        if (parameterNode.kind == LinkedNodeKind.fieldFormalParameter) {
+        reference.node2 = node;
+        if (parameterNode is FieldFormalParameter) {
           return DefaultFieldFormalParameterElementImpl.forLinkedNode(
             enclosing,
             reference,
@@ -8330,14 +8377,17 @@
           );
         }
       } else {
-        var name = context.getFormalParameterName(node);
+        var name = node.identifier.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return ParameterElementImpl.forLinkedNodeFactory(
-          enclosing,
-          reference,
-          node,
-        );
+        if (reference.element == null) {
+          reference.node2 = node;
+          ParameterElementImpl.forLinkedNodeFactory(
+            enclosing,
+            reference,
+            node,
+          );
+        }
+        return reference.element as ParameterElement;
       }
     }).toList();
   }
@@ -8465,7 +8515,7 @@
         super(name, nameOffset);
 
   PrefixElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, SimpleIdentifier linkedNode)
       : _unlinkedImport = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -8510,8 +8560,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      LibraryElementImpl library = enclosingElement;
-      return library.linkedContext.getSimpleOffset(linkedNode);
+      return (linkedNode as SimpleIdentifier).offset;
     }
     int offset = super.nameOffset;
     if (offset == 0 && _unlinkedImport != null) {
@@ -8541,7 +8590,7 @@
   PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
 
   PropertyAccessorElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created property accessor element to have the given
@@ -8614,14 +8663,6 @@
   }
 
   @override
-  bool get isAbstract {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.isAbstract(linkedNode);
-    }
-    return super.isAbstract;
-  }
-
-  @override
   bool get isGetter {
     if (linkedNode != null) {
       return enclosingUnit.linkedContext.isGetter(linkedNode);
@@ -8813,7 +8854,7 @@
   PropertyInducingElementImpl(String name, int offset) : super(name, offset);
 
   PropertyInducingElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created element to have the given [name].
@@ -8838,9 +8879,7 @@
   DartType get type {
     if (linkedNode != null) {
       if (_type != null) return _type;
-      return _type = enclosingUnit.linkedContext.getType(
-        linkedNode.variableDeclaration_type2,
-      );
+      return _type = enclosingUnit.linkedContext.getType(linkedNode);
     }
     if (isSynthetic && _type == null) {
       if (getter != null) {
@@ -8914,7 +8953,7 @@
   final UnlinkedCombinator _unlinkedCombinator;
 
   final LinkedUnitContext linkedContext;
-  final LinkedNode linkedNode;
+  final ShowCombinator linkedNode;
 
   /// The names that are to be made visible in the importing library if they are
   /// defined in the imported library.
@@ -8956,7 +8995,7 @@
   @override
   int get offset {
     if (linkedNode != null) {
-      return linkedContext.getTokenOffset(linkedNode.combinator_keyword);
+      return linkedNode.keyword.offset;
     }
     if (_unlinkedCombinator != null) {
       return _unlinkedCombinator.offset;
@@ -8974,9 +9013,7 @@
     if (_shownNames != null) return _shownNames;
 
     if (linkedNode != null) {
-      return _shownNames = linkedNode.showCombinator_shownNames
-          .map((node) => linkedContext.getSimpleName(node))
-          .toList();
+      return _shownNames = linkedNode.shownNames.map((i) => i.name).toList();
     }
 
     if (_unlinkedCombinator != null) {
@@ -9037,7 +9074,7 @@
   TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
 
   TopLevelVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
@@ -9057,7 +9094,7 @@
   }
 
   factory TopLevelVariableElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
+      ElementImpl enclosing, Reference reference, AstNode linkedNode) {
     if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) {
       return ConstTopLevelVariableElementImpl.forLinkedNode(
         enclosing,
@@ -9121,7 +9158,7 @@
   TypeParameterElementImpl.forLinkedNode(
       TypeParameterizedElementMixin enclosing,
       Reference reference,
-      LinkedNode linkedNode)
+      TypeParameter linkedNode)
       : _unlinkedTypeParam = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -9148,13 +9185,8 @@
     if (_bound != null) return _bound;
 
     if (linkedNode != null) {
-      var bound = linkedNode.typeParameter_bound;
-      if (bound != null) {
-        var context = enclosingUnit.linkedContext;
-        return _bound = context.getTypeAnnotationType(bound);
-      } else {
-        return null;
-      }
+      var context = enclosingUnit.linkedContext;
+      return _bound = context.getTypeParameterBound(linkedNode)?.type;
     }
 
     if (_unlinkedTypeParam != null) {
@@ -9177,7 +9209,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedTypeParam != null) {
       return _unlinkedTypeParam.codeRange?.length;
@@ -9188,7 +9220,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedTypeParam != null) {
       return _unlinkedTypeParam.codeRange?.offset;
@@ -9290,15 +9322,18 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
+      var typeParameters = context.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      return _typeParameterElements = typeParameters.map((node) {
-        var name = context.getSimpleName(node.typeParameter_name);
+      return _typeParameterElements = typeParameters.typeParameters.map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as TypeParameterElementImpl;
       }).toList();
     }
 
@@ -9411,7 +9446,7 @@
   UriReferencedElementImpl(String name, int offset) : super(name, offset);
 
   UriReferencedElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize using the given serialized information.
@@ -9475,7 +9510,7 @@
   VariableElementImpl(String name, int offset) : super(name, offset);
 
   VariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created variable element to have the given [name].
@@ -9498,9 +9533,9 @@
   DartObject get constantValue => evaluationResult?.value;
 
   void set declaredType(DartType type) {
-    if (linkedNode != null) {
-      enclosingUnit.linkedContext.setVariableType(linkedNode, type);
-    }
+//    if (linkedNode != null) {
+//      enclosingUnit.linkedContext.setVariableType(linkedNode, type);
+//    }
     _declaredType = _checkElementOfType(type);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 67f47f7..7384095d 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -395,6 +395,9 @@
   bool get hasLiteral => actualElement.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => actualElement.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => actualElement.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 845d59d..7472796 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -425,6 +425,9 @@
   bool get hasLiteral => _baseElement.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => _baseElement.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => _baseElement.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
new file mode 100644
index 0000000..b3fd95f
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -0,0 +1,292 @@
+// 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/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_visitor.dart';
+
+/// Returns a type where all occurrences of the given type parameters have been
+/// replaced with the corresponding types.
+///
+/// This will copy only the sub-terms of [type] that contain substituted
+/// variables; all other [DartType] objects will be reused.
+///
+/// In particular, if no type parameters were substituted, this is guaranteed
+/// to return the [type] instance (not a copy), so the caller may use
+/// [identical] to efficiently check if a distinct type was created.
+DartType substitute(
+  DartType type,
+  Map<TypeParameterElement, DartType> substitution,
+) {
+  if (substitution.isEmpty) {
+    return type;
+  }
+  return Substitution.fromMap(substitution).substituteType(type);
+}
+
+abstract class Substitution {
+  static const Substitution empty = _NullSubstitution.instance;
+
+  const Substitution();
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound);
+
+  DartType substituteType(DartType type, {bool contravariant: false}) {
+    return new _TopSubstitutor(this, contravariant).visit(type);
+  }
+
+  /// Substitutes the type parameters on the class of [type] with the
+  /// type arguments provided in [type].
+  static Substitution fromInterfaceType(InterfaceType type) {
+    if (type.typeArguments.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return fromPairs(type.element.typeParameters, type.typeArguments);
+  }
+
+  /// Substitutes each parameter to the type it maps to in [map].
+  static Substitution fromMap(Map<TypeParameterElement, DartType> map) {
+    if (map.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return new _MapSubstitution(map, map);
+  }
+
+  /// Substitutes the Nth parameter in [parameters] with the Nth type in
+  /// [types].
+  static Substitution fromPairs(
+    List<TypeParameterElement> parameters,
+    List<DartType> types,
+  ) {
+    assert(parameters.length == types.length);
+    if (parameters.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return fromMap(
+      new Map<TypeParameterElement, DartType>.fromIterables(
+        parameters,
+        types,
+      ),
+    );
+  }
+
+  /// Substitutes all occurrences of the given type parameters with the
+  /// corresponding upper or lower bound, depending on the variance of the
+  /// context where it occurs.
+  ///
+  /// For example the type `(T) => T` with the bounds `bottom <: T <: num`
+  /// becomes `(bottom) => num` (in this example, `num` is the upper bound,
+  /// and `bottom` is the lower bound).
+  ///
+  /// This is a way to obtain an upper bound for a type while eliminating all
+  /// references to certain type variables.
+  static Substitution fromUpperAndLowerBounds(
+    Map<TypeParameterElement, DartType> upper,
+    Map<TypeParameterElement, DartType> lower,
+  ) {
+    if (upper.isEmpty && lower.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return new _MapSubstitution(upper, lower);
+  }
+}
+
+class _FreshTypeParametersSubstitutor extends _TypeSubstitutor {
+  final Map<TypeParameterElement, DartType> substitution = {};
+
+  _FreshTypeParametersSubstitutor(_TypeSubstitutor outer) : super(outer);
+
+  TypeParameterElement freshTypeParameter(TypeParameterElement element) {
+    var freshElement = new TypeParameterElementImpl(element.name, -1);
+    var freshType = new TypeParameterTypeImpl(freshElement);
+    freshElement.type = freshType;
+    substitution[element] = freshType;
+    if (element.bound != null) {
+      freshElement.bound = visit(element.bound);
+    }
+    return freshElement;
+  }
+
+  DartType lookup(TypeParameterElement parameter, bool upperBound) {
+    return substitution[parameter];
+  }
+}
+
+class _MapSubstitution extends Substitution {
+  final Map<TypeParameterElement, DartType> upper;
+  final Map<TypeParameterElement, DartType> lower;
+
+  _MapSubstitution(this.upper, this.lower);
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
+    return upperBound ? upper[parameter] : lower[parameter];
+  }
+}
+
+class _NullSubstitution extends Substitution {
+  static const _NullSubstitution instance = const _NullSubstitution();
+
+  const _NullSubstitution();
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
+    return new TypeParameterTypeImpl(parameter);
+  }
+
+  @override
+  DartType substituteType(DartType type, {bool contravariant: false}) => type;
+}
+
+class _TopSubstitutor extends _TypeSubstitutor {
+  final Substitution substitution;
+
+  _TopSubstitutor(this.substitution, bool contravariant) : super(null) {
+    if (contravariant) {
+      invertVariance();
+    }
+  }
+
+  @override
+  TypeParameterElement freshTypeParameter(TypeParameterElement element) {
+    throw 'Create a fresh environment first';
+  }
+
+  @override
+  DartType lookup(TypeParameterElement parameter, bool upperBound) {
+    return substitution.getSubstitute(parameter, upperBound);
+  }
+}
+
+abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
+  final _TypeSubstitutor outer;
+  bool covariantContext = true;
+
+  /// The number of times a variable from this environment has been used in
+  /// a substitution.
+  ///
+  /// There is a strict requirement that we must return the same instance for
+  /// types that were not altered by the substitution.  This counter lets us
+  /// check quickly if anything happened in a substitution.
+  int useCounter = 0;
+
+  _TypeSubstitutor(this.outer) {
+    covariantContext = outer == null ? true : outer.covariantContext;
+  }
+
+  void bumpCountersUntil(_TypeSubstitutor target) {
+    var substitutor = this;
+    while (substitutor != target) {
+      substitutor.useCounter++;
+      substitutor = substitutor.outer;
+    }
+    target.useCounter++;
+  }
+
+  TypeParameterElement freshTypeParameter(TypeParameterElement element);
+
+  List<TypeParameterElement> freshTypeParameters(
+      List<TypeParameterElement> parameters) {
+    if (parameters.isEmpty) {
+      return const <TypeParameterElement>[];
+    }
+    return parameters.map(freshTypeParameter).toList();
+  }
+
+  DartType getSubstitute(TypeParameterElement parameter) {
+    var environment = this;
+    while (environment != null) {
+      var replacement = environment.lookup(parameter, covariantContext);
+      if (replacement != null) {
+        bumpCountersUntil(environment);
+        return replacement;
+      }
+      environment = environment.outer;
+    }
+    return null;
+  }
+
+  void invertVariance() {
+    covariantContext = !covariantContext;
+  }
+
+  DartType lookup(TypeParameterElement parameter, bool upperBound);
+
+  _FreshTypeParametersSubstitutor newInnerEnvironment() {
+    return new _FreshTypeParametersSubstitutor(this);
+  }
+
+  DartType visit(DartType type) {
+    return DartTypeVisitor.visit(type, this);
+  }
+
+  @override
+  DartType visitBottomType(BottomTypeImpl type) => type;
+
+  @override
+  DartType visitDynamicType(DynamicTypeImpl type) => type;
+
+  @override
+  DartType visitFunctionType(FunctionType type) {
+    // This is a bit tricky because we have to generate fresh type parameters
+    // in order to change the bounds.  At the same time, if the function type
+    // was unaltered, we have to return the [type] object (not a copy!).
+    // Substituting a type for a fresh type variable should not be confused
+    // with a "real" substitution.
+    //
+    // Create an inner environment to generate fresh type parameters.  The use
+    // counter on the inner environment tells if the fresh type parameters have
+    // any uses, but does not tell if the resulting function type is distinct.
+    // Our own use counter will get incremented if something from our
+    // environment has been used inside the function.
+    var inner = type.typeFormals.isEmpty ? this : newInnerEnvironment();
+    int before = this.useCounter;
+
+    // Invert the variance when translating parameters.
+    inner.invertVariance();
+
+    var typeFormals = inner.freshTypeParameters(type.typeFormals);
+
+    var parameters = type.parameters.map((parameter) {
+      var type = inner.visit(parameter.type);
+      return ParameterElementImpl.synthetic(
+        parameter.name,
+        type,
+        // ignore: deprecated_member_use_from_same_package
+        parameter.parameterKind,
+      );
+    }).toList();
+
+    inner.invertVariance();
+
+    var returnType = inner.visit(type.returnType);
+
+    if (this.useCounter == before) return type;
+
+    return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
+  }
+
+  @override
+  DartType visitInterfaceType(InterfaceType type) {
+    if (type.typeArguments.isEmpty) {
+      return type;
+    }
+
+    int before = useCounter;
+    var typeArguments = type.typeArguments.map(visit).toList();
+    if (useCounter == before) {
+      return type;
+    }
+
+    return new InterfaceTypeImpl.explicit(type.element, typeArguments);
+  }
+
+  @override
+  DartType visitTypeParameterType(TypeParameterType type) {
+    return getSubstitute(type.element) ?? type;
+  }
+
+  @override
+  DartType visitVoidType(VoidType type) => type;
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
new file mode 100644
index 0000000..6b0ffbe
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
@@ -0,0 +1,46 @@
+// 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/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+
+class DartTypeVisitor<R> {
+  const DartTypeVisitor();
+
+  R defaultDartType(DartType type) => null;
+
+  R visitBottomType(BottomTypeImpl type) => defaultDartType(type);
+
+  R visitDynamicType(DynamicTypeImpl type) => defaultDartType(type);
+
+  R visitFunctionType(FunctionType type) => defaultDartType(type);
+
+  R visitInterfaceType(InterfaceType type) => defaultDartType(type);
+
+  R visitTypeParameterType(TypeParameterType type) => defaultDartType(type);
+
+  R visitVoidType(VoidType type) => defaultDartType(type);
+
+  static R visit<R>(DartType type, DartTypeVisitor<R> visitor) {
+    if (type is BottomTypeImpl) {
+      return visitor.visitBottomType(type);
+    }
+    if (type is DynamicTypeImpl) {
+      return visitor.visitDynamicType(type);
+    }
+    if (type is FunctionType) {
+      return visitor.visitFunctionType(type);
+    }
+    if (type is InterfaceType) {
+      return visitor.visitInterfaceType(type);
+    }
+    if (type is TypeParameterType) {
+      return visitor.visitTypeParameterType(type);
+    }
+    if (type is VoidType) {
+      return visitor.visitVoidType(type);
+    }
+    throw UnimplementedError('(${type.runtimeType}) $type');
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 984a7b1..5aebd1d 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -71,6 +71,9 @@
   bool get hasLoadLibraryFunction => wrappedUnit.hasLoadLibraryFunction;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedUnit.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedUnit.hasOverride;
 
   @override
@@ -261,6 +264,9 @@
   bool get hasLiteral => wrappedImport.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedImport.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedImport.hasOverride;
 
   @override
@@ -466,6 +472,9 @@
   bool get hasLoadLibraryFunction => wrappedLib.hasLoadLibraryFunction;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedLib.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedLib.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 67fbccc..6e31a4b 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -693,6 +693,8 @@
   static const ParserErrorCode TYPE_ARGUMENTS_ON_TYPE_VARIABLE =
       _TYPE_ARGUMENTS_ON_TYPE_VARIABLE;
 
+  static const ParserErrorCode TYPE_BEFORE_FACTORY = _TYPE_BEFORE_FACTORY;
+
   static const ParserErrorCode TYPEDEF_IN_CLASS = _TYPEDEF_IN_CLASS;
 
   /**
@@ -716,7 +718,7 @@
 
   static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER =
       const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
-          "The default value of a positional parameter should be preceeded by '='.",
+          "The default value of a positional parameter should be preceded by '='.",
           correction: "Try replacing the ':' with '='.");
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 598d093..b12e351 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -104,6 +104,7 @@
   _EXPECTED_ELSE_OR_COMMA,
   _INVALID_SUPER_IN_INITIALIZER,
   _INVALID_THIS_IN_INITIALIZER,
+  _TYPE_BEFORE_FACTORY,
 ];
 
 const ParserErrorCode _ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
@@ -216,7 +217,7 @@
 
 const ParserErrorCode _DUPLICATED_MODIFIER = const ParserErrorCode(
     'DUPLICATED_MODIFIER', r"The modifier '#lexeme' was already specified.",
-    correction: "Try removing all but one occurance of the modifier.");
+    correction: "Try removing all but one occurence of the modifier.");
 
 const ParserErrorCode _DUPLICATE_DEFERRED = const ParserErrorCode(
     'DUPLICATE_DEFERRED',
@@ -256,7 +257,7 @@
 
 const ParserErrorCode _EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
     const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
-        r"Export directives must preceed part directives.",
+        r"Export directives must precede part directives.",
         correction:
             "Try moving the export directives before the part directives.");
 
@@ -360,7 +361,7 @@
 
 const ParserErrorCode _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
     const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
-        r"Import directives must preceed part directives.",
+        r"Import directives must precede part directives.",
         correction:
             "Try moving the import directives before the part directives.");
 
@@ -438,7 +439,7 @@
 
 const ParserErrorCode _MISSING_KEYWORD_OPERATOR = const ParserErrorCode(
     'MISSING_KEYWORD_OPERATOR',
-    r"Operator declarations must be preceeded by the keyword 'operator'.",
+    r"Operator declarations must be preceded by the keyword 'operator'.",
     correction: "Try adding the keyword 'operator'.");
 
 const ParserErrorCode _MISSING_PREFIX_IN_DEFERRED_IMPORT =
@@ -550,6 +551,10 @@
     r"Can't use type arguments with type variable '#name'.",
     correction: "Try removing the type arguments.");
 
+const ParserErrorCode _TYPE_BEFORE_FACTORY = const ParserErrorCode(
+    'TYPE_BEFORE_FACTORY', r"Factory constructors cannot have a return type.",
+    correction: "Try removing the type appearing before 'factory'.");
+
 const ParserErrorCode _VAR_AND_TYPE = const ParserErrorCode('VAR_AND_TYPE',
     r"Variables can't be declared using both 'var' and a type name.",
     correction: "Try removing 'var.'");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 41a977e..570fc8f 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -331,7 +331,7 @@
           "Class '{0}' can't define field '{1}' and have method '{2}.{1}' "
           "with the same name.",
           correction: "Try converting the getter to a method, or "
-              "renaming the field to a name that doesn't conflit.");
+              "renaming the field to a name that doesn't conflict.");
 
   /**
    * 10.10 Superinterfaces: It is a compile-time error if a class `C` has two
@@ -366,7 +366,7 @@
           "Class '{0}' can't define method '{1}' and have field '{2}.{1}' "
           "with the same name.",
           correction: "Try converting the method to a getter, or "
-              "renaming the method to a name that doesn't conflit.");
+              "renaming the method to a name that doesn't conflict.");
 
   /**
    * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
@@ -384,7 +384,7 @@
           "Class '{0}' can't define static member '{1}' and have instance "
           "member '{2}.{1}' with the same name.",
           correction:
-              "Try renaming the member to a name that doesn't conflit.");
+              "Try renaming the member to a name that doesn't conflict.");
 
   /**
    * 7. Classes: It is a compile time error if a generic class declares a type
@@ -761,7 +761,7 @@
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR',
           "The class '{0}' doesn't have a constant constructor '{1}'.",
-          correction: "Try calling a different contructor.");
+          correction: "Try calling a different constructor.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
@@ -773,7 +773,7 @@
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
           "The class '{0}' doesn't have a default constant constructor.",
-          correction: "Try calling a different contructor.");
+          correction: "Try calling a different constructor.");
 
   /**
    * 15.3.1 Typedef: It is a compile-time error if any default values are
@@ -1173,7 +1173,7 @@
   static const CompileTimeErrorCode IMPLEMENTS_REPEATED =
       const CompileTimeErrorCode(
           'IMPLEMENTS_REPEATED', "'{0}' can only be implemented once.",
-          correction: "Try removing all but one occurance of the class name.");
+          correction: "Try removing all but one occurrence of the class name.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the superclass of a
@@ -1186,7 +1186,7 @@
   static const CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS =
       const CompileTimeErrorCode('IMPLEMENTS_SUPER_CLASS',
           "'{0}' can't be used in both 'extends' and 'implements' clauses.",
-          correction: "Try removing one of the occurances.");
+          correction: "Try removing one of the occurrences.");
 
   /**
    * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the
@@ -2184,6 +2184,10 @@
       'NOT_MAP_SPREAD',
       "Spread elements in map literals must implement 'Map'.");
 
+  static const CompileTimeErrorCode NOT_NULL_AWARE_NULL_SPREAD =
+      const CompileTimeErrorCode('NOT_NULL_AWARE_NULL_SPREAD',
+          "The Null typed expression can't be used with a non-null-aware spread.");
+
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
    * superinitializer appears and let <i>S</i> be the superclass of <i>C</i>.
@@ -2217,7 +2221,7 @@
   static const CompileTimeErrorCode ON_REPEATED = const CompileTimeErrorCode(
       'ON_REPEATED',
       "'{0}' can only be used in super-class constraints only once.",
-      correction: "Try removing all but one occurance of the class name.");
+      correction: "Try removing all but one occurrence of the class name.");
 
   /**
    * 7.1.1 Operators: It is a compile-time error to declare an optional
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index 29b65b9..89dcdce 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -82,11 +83,13 @@
             CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP, element);
       }
     } else if (element is SpreadElement) {
+      var isNullAware = element.spreadOperator.type ==
+          TokenType.PERIOD_PERIOD_PERIOD_QUESTION;
       Expression expression = element.expression;
       if (forList || forSet) {
-        _verifySpreadForListOrSet(expression);
+        _verifySpreadForListOrSet(isNullAware, expression);
       } else if (forMap) {
-        _verifySpreadForMap(expression);
+        _verifySpreadForMap(isNullAware, expression);
       }
     }
   }
@@ -123,12 +126,19 @@
 
   /// Verify that the type of the elements of the given [expression] can be
   /// assigned to the [elementType] of the enclosing collection.
-  void _verifySpreadForListOrSet(Expression expression) {
+  void _verifySpreadForListOrSet(bool isNullAware, Expression expression) {
     var expressionType = expression.staticType;
     if (expressionType.isDynamic) return;
 
-    // TODO(scheglov) Check for non-null-aware spread?
-    if (expressionType.isDartCoreNull) return;
+    if (expressionType.isDartCoreNull) {
+      if (!isNullAware) {
+        errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     InterfaceType iterableType;
     var iterableObjectType = typeProvider.iterableObjectType;
@@ -161,12 +171,19 @@
 
   /// Verify that the [expression] is a subtype of `Map<Object, Object>`, and
   /// its key and values are assignable to [mapKeyType] and [mapValueType].
-  void _verifySpreadForMap(Expression expression) {
+  void _verifySpreadForMap(bool isNullAware, Expression expression) {
     var expressionType = expression.staticType;
     if (expressionType.isDynamic) return;
 
-    // TODO(scheglov) Check for non-null-aware spread?
-    if (expressionType.isDartCoreNull) return;
+    if (expressionType.isDartCoreNull) {
+      if (!isNullAware) {
+        errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     InterfaceType mapType;
     var mapObjectObjectType = typeProvider.mapObjectObjectType;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index b4a0bda..ea8336f 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
@@ -128,9 +129,15 @@
         new ConstantEvaluationEngine(_typeProvider, new DeclaredVariables(),
             typeSystem: _typeSystem),
         errorReporter));
+    List<AnalysisError> errors = errorListener.errors;
+    if (errors.isNotEmpty) {
+      return EvaluationResult.forErrors(errors);
+    }
     if (result != null) {
       return EvaluationResult.forValue(result);
     }
-    return EvaluationResult.forErrors(errorListener.errors);
+    // We should not get here. Either there should be a valid value or there
+    // should be an error explaining why a value could not be generated.
+    return EvaluationResult.forErrors(errors);
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index cdffbef..0c23f5c 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -733,6 +733,11 @@
   static const String PUBSPEC_YAML_FILE = 'pubspec.yaml';
 
   /**
+   * The file name used for Android manifest files.
+   */
+  static const String ANDROID_MANIFEST_FILE = 'AndroidManifest.xml';
+
+  /**
    * The unique instance of this class.
    */
   static final AnalysisEngine instance = new AnalysisEngine._();
@@ -1023,6 +1028,12 @@
   @deprecated
   int get cacheSize;
 
+  /*
+   * A flag indicating whether to run checks on AndroidManifest.xml file to
+   * see if it is complaint with Chrome OS.
+   */
+  bool get chromeOsManifestChecks;
+
   /**
    * Return `true` if analysis is to generate dart2js related hint results.
    */
@@ -1391,6 +1402,9 @@
    */
   bool strictRawTypes = false;
 
+  @override
+  bool chromeOsManifestChecks = false;
+
   /**
    * Initialize a newly created set of analysis options to have their default
    * values.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c372f0d..236bfe4 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4739,17 +4739,8 @@
           return;
         }
       }
-      if (element.metadata.isNotEmpty) {
-        for (var annotation in element.metadata) {
-          var e = annotation.element;
-          // TODO(jmesserly): similar "package:meta" annotations are added to
-          // the element as boolean getters, that may be worth considering.
-          if (e?.name == 'optionalTypeArgs' &&
-              e.librarySource.uri.toString() == 'package:meta/meta.dart') {
-            // Type is marked with `@optionalTypeArgs`: not an error.
-            return;
-          }
-        }
+      if (element.hasOptionalTypeArgs) {
+        return;
       }
       _errorReporter.reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [type]);
     }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index a6fdb03..fa863d1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5164,7 +5164,7 @@
 
   FunctionType _inferArgumentTypesForGeneric(AstNode inferenceNode,
       DartType uninstantiatedType, TypeArgumentList typeArguments,
-      {AstNode errorNode}) {
+      {AstNode errorNode, bool isConst: false}) {
     errorNode ??= inferenceNode;
     TypeSystem ts = typeSystem;
     if (typeArguments == null &&
@@ -5177,6 +5177,7 @@
           const <DartType>[],
           InferenceContext.getContext(inferenceNode),
           downwards: true,
+          isConst: isConst,
           errorReporter: errorReporter,
           errorNode: errorNode);
     }
@@ -5218,7 +5219,7 @@
 
       inferred = _inferArgumentTypesForGeneric(
           node, constructorType, constructor.type.typeArguments,
-          errorNode: node.constructorName);
+          isConst: node.isConst, errorNode: node.constructorName);
 
       if (inferred != null) {
         ArgumentList arguments = node.argumentList;
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index f3b066e..682b4f3 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -175,6 +175,7 @@
     InterfaceType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
         _typeProvider.listType, parameters, elementTypes, contextType,
         downwards: downwards,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -190,6 +191,7 @@
     ParameterizedType inferred = ts.inferGenericFunctionOrType(
         _typeProvider.mapType, [], [], contextType,
         downwards: true,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -204,6 +206,7 @@
     DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
         _typeProvider.setType, [], [], contextType,
         downwards: true,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -1546,7 +1549,8 @@
       DartType fnType,
       TypeArgumentList typeArguments,
       ArgumentList argumentList,
-      AstNode errorNode) {
+      AstNode errorNode,
+      {bool isConst: false}) {
     TypeSystem ts = _typeSystem;
     if (typeArguments == null &&
         fnType is FunctionType &&
@@ -1568,7 +1572,9 @@
       }
       return ts.inferGenericFunctionOrType(
           fnType, params, argTypes, InferenceContext.getContext(node),
-          errorReporter: _resolver.errorReporter, errorNode: errorNode);
+          isConst: isConst,
+          errorReporter: _resolver.errorReporter,
+          errorNode: errorNode);
     }
     return null;
   }
@@ -1606,7 +1612,8 @@
 
     ArgumentList arguments = node.argumentList;
     FunctionType inferred = _inferGenericInvoke(node, constructorType,
-        constructor.type.typeArguments, arguments, node.constructorName);
+        constructor.type.typeArguments, arguments, node.constructorName,
+        isConst: node.isConst);
 
     if (inferred != null && inferred != originalElement.type) {
       // Fix up the parameter elements based on inferred method.
@@ -1888,7 +1895,9 @@
       ..addAll(valueTypes);
     return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
         _typeProvider.mapType, typeParameters, elementTypes, contextType,
-        errorReporter: _resolver.errorReporter, errorNode: node);
+        isConst: node.isConst,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
   }
 
   DartType _toSetType(SetOrMapLiteral node, DartType contextType,
@@ -1908,7 +1917,9 @@
         growable: true);
     return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
         _typeProvider.setType, parameters, elementTypes, contextType,
-        errorReporter: _resolver.errorReporter, errorNode: node);
+        isConst: node.isConst,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 969cac5..ec1a06f 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -225,7 +225,8 @@
       DartType returnContextType,
       {ErrorReporter errorReporter,
       AstNode errorNode,
-      bool downwards: false}) {
+      bool downwards: false,
+      bool isConst: false}) {
     // TODO(jmesserly): expose typeFormals on ParameterizedType.
     List<TypeParameterElement> typeFormals = typeFormalsAsElements(genericType);
     if (typeFormals.isEmpty) {
@@ -242,6 +243,9 @@
         genericType is FunctionType ? genericType.returnType : genericType;
 
     if (returnContextType != null) {
+      if (isConst) {
+        returnContextType = _eliminateTypeVariables(returnContextType);
+      }
       inferrer.constrainReturnType(declaredReturnType, returnContextType);
     }
 
@@ -652,6 +656,30 @@
   }
 
   /**
+   * Eliminates type variables from the context [type], replacing them with
+   * `Null` or `Object` as appropriate.
+   *
+   * For example in `List<T> list = const []`, the context type for inferring
+   * the list should be changed from `List<T>` to `List<Null>` so the constant
+   * doesn't depend on the type variables `T` (because it can't be canonicalized
+   * at compile time, as `T` is unknown).
+   *
+   * Conceptually this is similar to the "least closure", except instead of
+   * eliminating `?` ([UnknownInferredType]) it eliminates all type variables
+   * ([TypeParameterType]).
+   *
+   * The equivalent CFE code can be found in the `TypeVariableEliminator` class.
+   */
+  DartType _eliminateTypeVariables(DartType type) {
+    return _substituteType(type, true, (type, lowerBound) {
+      if (type is TypeParameterType) {
+        return lowerBound ? typeProvider.nullType : typeProvider.objectType;
+      }
+      return type;
+    });
+  }
+
+  /**
    * Compute the greatest lower bound of function types [f] and [g].
    *
    * The spec rules for GLB on function types, informally, are pretty simple:
@@ -891,19 +919,43 @@
     return false;
   }
 
+  /**
+   * Returns the greatest or least closure of [type], which replaces `?`
+   * ([UnknownInferredType]) with `dynamic` or `Null` as appropriate.
+   *
+   * If [lowerBound] is true, this will return the "least closure", otherwise
+   * it returns the "greatest closure".
+   */
   DartType _substituteForUnknownType(DartType type, {bool lowerBound: false}) {
-    if (identical(type, UnknownInferredType.instance)) {
-      if (lowerBound) {
-        // TODO(jmesserly): this should be the bottom type, once it can be
-        // reified.
-        return typeProvider.nullType;
+    return _substituteType(type, lowerBound, (type, lowerBound) {
+      if (identical(type, UnknownInferredType.instance)) {
+        return lowerBound ? typeProvider.nullType : typeProvider.dynamicType;
       }
-      return typeProvider.dynamicType;
+      return type;
+    });
+  }
+
+  /**
+   * Apply the [visitType] substitution to [type], using the result value if
+   * different, otherwise recursively apply the substitution.
+   *
+   * This method is used for substituting `?` ([UnknownInferredType]) with its
+   * greatest/least closure, and for eliminating type parameters for inference
+   * of `const` objects.
+   *
+   * See also [_eliminateTypeVariables] and [_substituteForUnknownType].
+   */
+  DartType _substituteType(DartType type, bool lowerBound,
+      DartType Function(DartType, bool) visitType) {
+    // Apply the substitution to this type, and return the result if different.
+    var newType = visitType(type, lowerBound);
+    if (!identical(newType, type)) {
+      return newType;
     }
     if (type is InterfaceTypeImpl) {
       // Generic types are covariant, so keep the constraint direction.
-      var newTypeArgs = _transformList(type.typeArguments,
-          (t) => _substituteForUnknownType(t, lowerBound: lowerBound));
+      var newTypeArgs = _transformList(
+          type.typeArguments, (t) => _substituteType(t, lowerBound, visitType));
       if (identical(type.typeArguments, newTypeArgs)) return type;
       return new InterfaceTypeImpl(
           type.element, type.prunedTypedefs, type.nullability)
@@ -914,8 +966,7 @@
       var returnType = type.returnType;
       var newParameters = _transformList(parameters, (ParameterElement p) {
         // Parameters are contravariant, so flip the constraint direction.
-        var newType =
-            _substituteForUnknownType(p.type, lowerBound: !lowerBound);
+        var newType = _substituteType(p.type, !lowerBound, visitType);
         return new ParameterElementImpl.synthetic(
             p.name,
             newType,
@@ -923,8 +974,7 @@
             p.parameterKind);
       });
       // Return type is covariant.
-      var newReturnType =
-          _substituteForUnknownType(returnType, lowerBound: lowerBound);
+      var newReturnType = _substituteType(returnType, lowerBound, visitType);
       if (identical(parameters, newParameters) &&
           identical(returnType, newReturnType)) {
         return type;
@@ -1179,8 +1229,8 @@
             ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
           typeParam,
           ' Inferred candidate type $inferred has type parameters'
-              ' ${(inferred as FunctionType).typeFormals}, but a function with'
-              ' type parameters cannot be used as a type argument.'
+          ' ${(inferred as FunctionType).typeFormals}, but a function with'
+          ' type parameters cannot be used as a type argument.'
         ]);
 
         // Heuristic: Using a generic function type as a bound makes subtyping
@@ -1211,8 +1261,8 @@
             ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
           typeParam,
           "\nRecursive bound cannot be instantiated: '$typeParamBound'."
-              "\nConsider passing explicit type argument(s) "
-              "to the generic.\n\n'"
+          "\nConsider passing explicit type argument(s) "
+          "to the generic.\n\n'"
         ]);
       }
     }
diff --git a/pkg/analyzer/lib/src/manifest/manifest_validator.dart b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
new file mode 100644
index 0000000..f18f9bd
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
@@ -0,0 +1,112 @@
+// 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/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart' show parseFragment;
+import 'package:source_span/source_span.dart';
+
+import 'manifest_values.dart';
+import 'manifest_warning_code.dart';
+
+class ManifestValidator {
+  /**
+   * The source representing the file being validated.
+   */
+  final Source source;
+
+  /**
+   * Initialize a newly create validator to validate the content of the given
+   * [source].
+   */
+  ManifestValidator(this.source);
+
+  /*
+   * Validate the [contents] of the Android Manifest file.
+   */
+  List<AnalysisError> validate(String contents, bool checkManifest) {
+    RecordingErrorListener recorder = new RecordingErrorListener();
+    ErrorReporter reporter = new ErrorReporter(recorder, source);
+
+    if (checkManifest) {
+      var document =
+          parseFragment(contents, container: MANIFEST_TAG, generateSpans: true);
+      var manifest = document.children.firstWhere(
+          (element) => element.localName == MANIFEST_TAG,
+          orElse: () => null);
+      var features = manifest?.getElementsByTagName(USES_FEATURE_TAG) ?? [];
+      var permissions =
+          manifest?.getElementsByTagName(USES_PERMISSION_TAG) ?? [];
+
+      _validateFeatures(features, reporter);
+      _validatePermissions(permissions, features, reporter);
+    }
+    return recorder.errors;
+  }
+
+  /*
+   * Validate the `uses-feature` tags.
+   */
+  _validateFeatures(List<Element> features, ErrorReporter reporter) {
+    var unsupported = features
+        .where((element) => UNSUPPORTED_HARDWARE_FEATURES
+            .contains(element.attributes[ANDROID_NAME]))
+        .toList();
+    unsupported.forEach((element) {
+      if (!element.attributes.containsKey(ANDROID_REQUIRED)) {
+        _reportErrorForNode(reporter, element, ANDROID_NAME,
+            ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE);
+      } else if (element.attributes[ANDROID_REQUIRED] == true) {
+        _reportErrorForNode(reporter, element, ANDROID_NAME,
+            ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE);
+      }
+    });
+  }
+
+  /*
+   * Validate the `uses-permission` tags.
+   */
+  _validatePermissions(List<Element> permissions, List<Element> features,
+      ErrorReporter reporter) {
+    permissions.forEach((permission) {
+      if (permission.attributes[ANDROID_NAME] == ANDROID_PERMISSION_CAMERA) {
+        if (!_hasFeatureCamera(features) ||
+            !_hasFeatureCameraAutoFocus(features)) {
+          _reportErrorForNode(reporter, permission, ANDROID_NAME,
+              ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE);
+        }
+      } else {
+        var featureName =
+            getImpliedUnsupportedHardware(permission.attributes[ANDROID_NAME]);
+        if (featureName != null) {
+          _reportErrorForNode(
+              reporter,
+              permission,
+              ANDROID_NAME,
+              ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE,
+              [featureName]);
+        }
+      }
+    });
+  }
+
+  bool _hasFeatureCamera(List<Element> features) =>
+      features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA);
+
+  bool _hasFeatureCameraAutoFocus(List<Element> features) =>
+      features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA_AUTOFOCUS);
+
+  /**
+   * Report an error for the given node.
+   */
+  void _reportErrorForNode(
+      ErrorReporter reporter, Node node, dynamic key, ErrorCode errorCode,
+      [List<Object> arguments]) {
+    FileSpan span = node.attributeValueSpans[key];
+    reporter.reportErrorForOffset(
+        errorCode, span.start.offset, span.length, arguments);
+  }
+}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_values.dart b/pkg/analyzer/lib/src/manifest/manifest_values.dart
new file mode 100644
index 0000000..ea1b59d
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_values.dart
@@ -0,0 +1,101 @@
+// 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.
+
+/*
+*  The arritbute values to check for compatibiltiy with Chrome OS.
+*
+ */
+
+const String MANIFEST_TAG = 'manifest';
+
+const String USES_PERMISSION_TAG = 'uses-permission';
+
+const String USES_FEATURE_TAG = 'uses-feature';
+
+const String ANDROID_NAME = 'android:name';
+
+const String ANDROID_REQUIRED = 'android:required';
+
+const String HARDWARE_FEATURE_CAMERA = 'android.hardware.camera';
+
+const String HARDWARE_FEATURE_CAMERA_AUTOFOCUS =
+    'android.hardware.camera.autofocus';
+
+const String HARDWARE_FEATURE_TELEPHONY = 'android.hardware.telephony';
+
+const String ANDROID_PERMISSION_CAMERA = 'android.permission.CAMERA';
+
+const UNSUPPORTED_HARDWARE_FEATURES = <String>[
+  HARDWARE_FEATURE_CAMERA,
+  HARDWARE_FEATURE_CAMERA_AUTOFOCUS,
+  'android.hardware.camera.capability.manual_post_processing',
+  'android.hardware.camera.capability.manual_sensor',
+  'android.hardware.camera.capability.raw',
+  'android.hardware.camera.flash',
+  'android.hardware.camera.level.full',
+  'android.hardware.consumerir',
+  'android.hardware.location.gps',
+  'android.hardware.nfc',
+  'android.hardware.nfc.hce',
+  'android.hardware.sensor.barometer',
+  HARDWARE_FEATURE_TELEPHONY,
+  'android.hardware.telephony.cdma',
+  'android.hardware.telephony.gsm',
+  'android.hardware.touchscreen',
+  'android.hardware.type.automotive',
+  'android.hardware.type.television',
+  'android.hardware.usb.accessory',
+  'android.hardware.usb.host',
+  // Partially-supported, only on some Chrome OS devices.
+  'android.hardware.sensor.accelerometer',
+  'android.hardware.sensor.compass',
+  'android.hardware.sensor.gyroscope',
+  'android.hardware.sensor.light',
+  'android.hardware.sensor.proximity',
+  'android.hardware.sensor.stepcounter',
+  'android.hardware.sensor.stepdetector',
+  // Software features that are not supported
+  'android.software.app_widgets',
+  'android.software.device_admin',
+  'android.software.home_screen',
+  'android.software.input_methods',
+  'android.software.leanback',
+  'android.software.live_wallpaper',
+  'android.software.live_tv',
+  'android.software.managed_users',
+  'android.software.midi',
+  'android.software.sip',
+  'android.software.sip.voip',
+];
+
+String getImpliedUnsupportedHardware(String permission) {
+  switch (permission) {
+    case ANDROID_PERMISSION_CAMERA:
+      return HARDWARE_FEATURE_CAMERA;
+    case 'android.permission.CALL_PHONE':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.CALL_PRIVILEGED':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.MODIFY_PHONE_STATE':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.PROCESS_OUTGOING_CALLS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.READ_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_MMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_WAP_PUSH':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.SEND_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.WRITE_APN_SETTINGS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.WRITE_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    default:
+      return null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
new file mode 100644
index 0000000..0e0928c
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -0,0 +1,60 @@
+// 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/error/error.dart';
+
+/**
+ * The error codes used for warnings in analysis options files. The convention
+ * for this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what is
+ * wrong and, when appropriate, how the problem can be corrected.
+ */
+class ManifestWarningCode extends ErrorCode {
+  /**
+   * A code indicating that a specified hardware feature is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode UNSUPPORTED_CHROME_OS_HARDWARE =
+      const ManifestWarningCode('UNSUPPORTED_CHROME_OS_HARDWARE',
+          "This hardware feature is not supported on Chrome OS.",
+          correction:
+              "Try adding `android:required=\"false\"` for this hardware " +
+                  "feature.");
+
+  /**
+   * A code indicating that a specified permission is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE =
+      const ManifestWarningCode(
+          'PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE',
+          "Permission exists without corresponding hardware tag `<uses-feature " +
+              "android:name=\"{0}\"  android:required=\"false\">`.",
+          correction:
+              "Try adding the uses-feature with required=\"false\" attribute value.");
+
+  /**
+   * A code indicating that the camera permissions is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode CAMERA_PERMISSIONS_INCOMPATIBLE =
+      const ManifestWarningCode(
+          'CAMERA_PERMISSIONS_INCOMPATIBLE',
+          "Permission exists without corresponding hardware `<uses-feature " +
+              "android:name=\"android.hardware.camera\"  android:required=\"false\">` " +
+              "`<uses-feature " +
+              "android:name=\"android.hardware.camera.autofocus\"  android:required=\"false\">`.",
+          correction:
+              "Try adding the uses-feature with required=\"false\" attribute value.");
+
+  /**
+   * Initialize a newly created warning code to have the given [name], [message]
+   * and [correction].
+   */
+  const ManifestWarningCode(String name, String message, {String correction})
+      : super.temporary(name, message, correction: correction);
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
+
+  @override
+  ErrorType get type => ErrorType.STATIC_WARNING;
+}
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 539b719..8337641 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -32,6 +32,7 @@
 
 /// A top-level public declaration.
 class Declaration {
+  final List<Declaration> children;
   final String defaultArgumentListString;
   final List<int> defaultArgumentListTextRanges;
   final String docComplete;
@@ -45,18 +46,11 @@
   final String locationPath;
   final int locationStartColumn;
   final int locationStartLine;
-
-  /// The name of the declaration.
-  /// For enum constants, the name of the constant.
   final String name;
-
-  /// Usually `null`.
-  /// For enum constants, the name of the enum.
-  final String name2;
-
   final String parameters;
   final List<String> parameterNames;
   final List<String> parameterTypes;
+  final Declaration parent;
   final int requiredParameterCount;
   final String returnType;
   final String typeParameters;
@@ -64,6 +58,7 @@
   List<String> _relevanceTags;
 
   Declaration({
+    @required this.children,
     @required this.defaultArgumentListString,
     @required this.defaultArgumentListTextRanges,
     @required this.docComplete,
@@ -78,10 +73,10 @@
     @required this.locationStartColumn,
     @required this.locationStartLine,
     @required this.name,
-    @required this.name2,
     @required this.parameters,
     @required this.parameterNames,
     @required this.parameterTypes,
+    @required this.parent,
     @required List<String> relevanceTags,
     @required this.requiredParameterCount,
     @required this.returnType,
@@ -92,11 +87,7 @@
 
   @override
   String toString() {
-    if (name2 == null) {
-      return '($kind, $name)';
-    } else {
-      return '($kind, $name, $name2)';
-    }
+    return '($kind, $name)';
   }
 }
 
@@ -735,8 +726,8 @@
         var name = declaration.name;
         return <String>['$uriStr::$name'];
       case DeclarationKind.ENUM_CONSTANT:
-        var name2 = declaration.name2;
-        return <String>['$uriStr::$name2'];
+        var enumName = declaration.parent.name;
+        return <String>['$uriStr::$enumName'];
       default:
         return null;
     }
@@ -767,15 +758,14 @@
 
 class _DeclarationStorage {
   static const fieldDocMask = 1 << 0;
-  static const fieldName2Mask = 1 << 1;
-  static const fieldParametersMask = 1 << 2;
-  static const fieldReturnTypeMask = 1 << 3;
-  static const fieldTypeParametersMask = 1 << 4;
+  static const fieldParametersMask = 1 << 1;
+  static const fieldReturnTypeMask = 1 << 2;
+  static const fieldTypeParametersMask = 1 << 3;
 
-  static Declaration fromIdl(String path, idl.AvailableDeclaration d) {
+  static Declaration fromIdl(
+      String path, Declaration parent, idl.AvailableDeclaration d) {
     var fieldMask = d.fieldMask;
     var hasDoc = fieldMask & fieldDocMask != 0;
-    var hasName2 = fieldMask & fieldName2Mask != 0;
     var hasParameters = fieldMask & fieldParametersMask != 0;
     var hasReturnType = fieldMask & fieldReturnTypeMask != 0;
     var hasTypeParameters = fieldMask & fieldTypeParametersMask != 0;
@@ -787,7 +777,9 @@
       relevanceTags = null;
     }
 
-    return Declaration(
+    var children = <Declaration>[];
+    var declaration = Declaration(
+      children: children,
       defaultArgumentListString: d.defaultArgumentListString.isNotEmpty
           ? d.defaultArgumentListString
           : null,
@@ -806,15 +798,22 @@
       locationStartColumn: d.locationStartColumn,
       locationStartLine: d.locationStartLine,
       name: d.name,
-      name2: hasName2 ? d.name2 : null,
       parameters: hasParameters ? d.parameters : null,
       parameterNames: hasParameters ? d.parameterNames : null,
       parameterTypes: hasParameters ? d.parameterTypes.toList() : null,
+      parent: parent,
       relevanceTags: relevanceTags,
       requiredParameterCount: hasParameters ? d.requiredParameterCount : null,
       returnType: hasReturnType ? d.returnType : null,
       typeParameters: hasTypeParameters ? d.typeParameters : null,
     );
+
+    for (var childIdl in d.children) {
+      var child = fromIdl(path, declaration, childIdl);
+      children.add(child);
+    }
+
+    return declaration;
   }
 
   static DeclarationKind kindFromIdl(idl.AvailableDeclarationKind kind) {
@@ -880,9 +879,6 @@
     if (d.docComplete != null) {
       fieldMask |= fieldDocMask;
     }
-    if (d.name2 != null) {
-      fieldMask |= fieldName2Mask;
-    }
     if (d.parameters != null) {
       fieldMask |= fieldParametersMask;
     }
@@ -895,6 +891,7 @@
 
     var idlKind = kindToIdl(d.kind);
     return idl.AvailableDeclarationBuilder(
+      children: d.children.map(toIdl).toList(),
       defaultArgumentListString: d.defaultArgumentListString,
       defaultArgumentListTextRanges: d.defaultArgumentListTextRanges,
       docComplete: d.docComplete,
@@ -909,7 +906,6 @@
       locationStartColumn: d.locationStartColumn,
       locationStartLine: d.locationStartLine,
       name: d.name,
-      name2: d.name2,
       parameters: d.parameters,
       parameterNames: d.parameterNames,
       parameterTypes: d.parameterTypes,
@@ -938,7 +934,7 @@
 
   Iterable<Declaration> filter(List<Declaration> declarations) {
     return declarations.where((d) {
-      var name = d.name2 ?? d.name;
+      var name = d.name;
       for (var combinator in combinators) {
         if (combinator.shows.isNotEmpty) {
           if (!combinator.shows.contains(name)) return false;
@@ -961,7 +957,7 @@
 
 class _File {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 9;
+  static const int DATA_VERSION = 11;
 
   /// The next value for [id].
   static int _nextId = 0;
@@ -1083,7 +1079,7 @@
       for (var part in parts) {
         libraryDeclarations.addAll(part.file.fileDeclarations);
       }
-      _computeRelevanceTagsForLibraryDeclarations();
+      _computeRelevanceTags(libraryDeclarations);
     }
   }
 
@@ -1093,6 +1089,8 @@
     fileDeclarations = [];
     libraryDeclarations = null;
     exportedDeclarations = null;
+    templateNames = [];
+    templateValues = [];
 
     for (var astDirective in unit.directives) {
       if (astDirective is ExportDirective) {
@@ -1143,7 +1141,7 @@
       }
     }
 
-    void addDeclaration({
+    Declaration addDeclaration({
       String defaultArgumentListString,
       List<int> defaultArgumentListTextRanges,
       bool isAbstract = false,
@@ -1152,23 +1150,23 @@
       bool isFinal = false,
       @required DeclarationKind kind,
       @required Identifier name,
-      Identifier name2,
       String parameters,
       List<String> parameterNames,
       List<String> parameterTypes,
+      Declaration parent,
       List<String> relevanceTags,
       int requiredParameterCount,
       String returnType,
       String typeParameters,
     }) {
-      if (Identifier.isPrivateName(name.name) ||
-          name2 != null && Identifier.isPrivateName(name2.name)) {
-        return;
+      if (Identifier.isPrivateName(name.name)) {
+        return null;
       }
 
       var locationOffset = name.offset;
       var lineLocation = lineInfo.getLocation(locationOffset);
-      fileDeclarations.add(Declaration(
+      var declaration = Declaration(
+        children: <Declaration>[],
         defaultArgumentListString: defaultArgumentListString,
         defaultArgumentListTextRanges: defaultArgumentListTextRanges,
         docComplete: docComplete,
@@ -1181,17 +1179,24 @@
         locationOffset: locationOffset,
         locationPath: path,
         name: name.name,
-        name2: name2?.name,
         locationStartColumn: lineLocation.columnNumber,
         locationStartLine: lineLocation.lineNumber,
         parameters: parameters,
         parameterNames: parameterNames,
         parameterTypes: parameterTypes,
+        parent: parent,
         relevanceTags: relevanceTags,
         requiredParameterCount: requiredParameterCount,
         returnType: returnType,
         typeParameters: typeParameters,
-      ));
+      );
+
+      if (parent != null) {
+        parent.children.add(declaration);
+      } else {
+        fileDeclarations.add(declaration);
+      }
+      return declaration;
     }
 
     for (var node in unit.declarations) {
@@ -1199,12 +1204,15 @@
       var isDeprecated = _hasDeprecatedAnnotation(node);
 
       if (node is ClassDeclaration) {
-        addDeclaration(
+        var classDeclaration = addDeclaration(
           isAbstract: node.isAbstract,
           isDeprecated: isDeprecated,
           kind: DeclarationKind.CLASS,
           name: node.name,
         );
+        if (classDeclaration == null) continue;
+
+        var hasConstructor = false;
         for (var classMember in node.members) {
           if (classMember is ConstructorDeclaration) {
             setDartDoc(classMember);
@@ -1228,15 +1236,44 @@
               isDeprecated: isDeprecated,
               kind: DeclarationKind.CONSTRUCTOR,
               name: constructorName,
-              name2: node.name,
               parameters: parameters.toSource(),
               parameterNames: _getFormalParameterNames(parameters),
               parameterTypes: _getFormalParameterTypes(parameters),
+              parent: classDeclaration,
               requiredParameterCount:
                   _getFormalParameterRequiredCount(parameters),
             );
+            hasConstructor = true;
           }
         }
+
+        if (!hasConstructor) {
+          classDeclaration.children.add(Declaration(
+            children: [],
+            defaultArgumentListString: null,
+            defaultArgumentListTextRanges: null,
+            docComplete: null,
+            docSummary: null,
+            isAbstract: false,
+            isConst: false,
+            isDeprecated: false,
+            isFinal: false,
+            kind: DeclarationKind.CONSTRUCTOR,
+            locationOffset: -1,
+            locationPath: path,
+            name: '',
+            locationStartColumn: 0,
+            locationStartLine: 0,
+            parameters: '()',
+            parameterNames: [],
+            parameterTypes: [],
+            parent: classDeclaration,
+            relevanceTags: null,
+            requiredParameterCount: 0,
+            returnType: null,
+            typeParameters: null,
+          ));
+        }
       } else if (node is ClassTypeAlias) {
         addDeclaration(
           isDeprecated: isDeprecated,
@@ -1244,11 +1281,13 @@
           name: node.name,
         );
       } else if (node is EnumDeclaration) {
-        addDeclaration(
+        var enumDeclaration = addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.ENUM,
           name: node.name,
         );
+        if (enumDeclaration == null) continue;
+
         for (var constant in node.constants) {
           setDartDoc(constant);
           var isDeprecated = _hasDeprecatedAnnotation(constant);
@@ -1256,7 +1295,7 @@
             isDeprecated: isDeprecated,
             kind: DeclarationKind.ENUM_CONSTANT,
             name: constant.name,
-            name2: node.name,
+            parent: enumDeclaration,
           );
         }
       } else if (node is FunctionDeclaration) {
@@ -1299,6 +1338,8 @@
         }
       } else if (node is GenericTypeAlias) {
         var functionType = node.functionType;
+        if (functionType == null) continue;
+
         var parameters = functionType.parameters;
         addDeclaration(
           isDeprecated: isDeprecated,
@@ -1335,10 +1376,11 @@
     }
   }
 
-  void _computeRelevanceTagsForLibraryDeclarations() {
-    for (var declaration in libraryDeclarations) {
+  void _computeRelevanceTags(List<Declaration> declarations) {
+    for (var declaration in declarations) {
       declaration._relevanceTags ??=
           RelevanceTags._forDeclaration(uriStr, declaration);
+      _computeRelevanceTags(declaration.children);
     }
   }
 
@@ -1429,11 +1471,11 @@
     }).toList();
 
     fileDeclarations = idlFile.declarations.map((e) {
-      return _DeclarationStorage.fromIdl(path, e);
+      return _DeclarationStorage.fromIdl(path, null, e);
     }).toList();
 
-    templateNames = idlFile.directiveInfo.templateNames;
-    templateValues = idlFile.directiveInfo.templateValues;
+    templateNames = idlFile.directiveInfo.templateNames.toList();
+    templateValues = idlFile.directiveInfo.templateValues.toList();
   }
 
   static _DefaultArguments _computeDefaultArguments(
@@ -1649,7 +1691,7 @@
   static Set<Declaration> _newDeclarationSet() {
     return HashSet<Declaration>(
       hashCode: (e) => e.name.hashCode,
-      equals: (a, b) => a.name == b.name && a.name2 == b.name2,
+      equals: (a, b) => a.name == b.name,
     );
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 004943b..fd78d94 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -322,7 +322,7 @@
   String get exception => _exception ??= '';
 
   /// The exception string.
-  void set exception(String value) {
+  set exception(String value) {
     this._exception = value;
   }
 
@@ -331,7 +331,7 @@
       _files ??= <AnalysisDriverExceptionFileBuilder>[];
 
   /// The state of files when the exception happened.
-  void set files(List<AnalysisDriverExceptionFileBuilder> value) {
+  set files(List<AnalysisDriverExceptionFileBuilder> value) {
     this._files = value;
   }
 
@@ -339,7 +339,7 @@
   String get path => _path ??= '';
 
   /// The path of the file being analyzed when the exception happened.
-  void set path(String value) {
+  set path(String value) {
     this._path = value;
   }
 
@@ -347,7 +347,7 @@
   String get stackTrace => _stackTrace ??= '';
 
   /// The exception stack trace string.
-  void set stackTrace(String value) {
+  set stackTrace(String value) {
     this._stackTrace = value;
   }
 
@@ -361,16 +361,12 @@
         _path = path,
         _stackTrace = stackTrace;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _files?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._path ?? '');
     signature.addString(this._exception ?? '');
@@ -517,7 +513,7 @@
   String get content => _content ??= '';
 
   /// The content of the file.
-  void set content(String value) {
+  set content(String value) {
     this._content = value;
   }
 
@@ -525,7 +521,7 @@
   String get path => _path ??= '';
 
   /// The path of the file.
-  void set path(String value) {
+  set path(String value) {
     this._path = value;
   }
 
@@ -533,14 +529,10 @@
       : _content = content,
         _path = path;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._path ?? '');
     signature.addString(this._content ?? '');
@@ -631,7 +623,7 @@
       _errors ??= <AnalysisDriverUnitErrorBuilder>[];
 
   /// The full list of analysis errors, both syntactic and semantic.
-  void set errors(List<AnalysisDriverUnitErrorBuilder> value) {
+  set errors(List<AnalysisDriverUnitErrorBuilder> value) {
     this._errors = value;
   }
 
@@ -639,7 +631,7 @@
   AnalysisDriverUnitIndexBuilder get index => _index;
 
   /// The index of the unit.
-  void set index(AnalysisDriverUnitIndexBuilder value) {
+  set index(AnalysisDriverUnitIndexBuilder value) {
     this._index = value;
   }
 
@@ -649,17 +641,13 @@
       : _errors = errors,
         _index = index;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _errors?.forEach((b) => b.flushInformative());
     _index?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._errors == null) {
       signature.addInt(0);
@@ -775,7 +763,7 @@
   /// The names of defined instance members.
   /// They are indexes into [AnalysisDriverUnitError.strings] list.
   /// The list is sorted in ascending order.
-  void set members(List<int> value) {
+  set members(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._members = value;
   }
@@ -785,7 +773,7 @@
 
   /// The name of the class.
   /// It is an index into [AnalysisDriverUnitError.strings] list.
-  void set name(int value) {
+  set name(int value) {
     assert(value == null || value >= 0);
     this._name = value;
   }
@@ -794,14 +782,10 @@
       : _members = members,
         _name = name;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._name ?? 0);
     if (this._members == null) {
@@ -897,7 +881,7 @@
   String get correction => _correction ??= '';
 
   /// The optional correction hint for the error.
-  void set correction(String value) {
+  set correction(String value) {
     this._correction = value;
   }
 
@@ -905,7 +889,7 @@
   int get length => _length ??= 0;
 
   /// The length of the error in the file.
-  void set length(int value) {
+  set length(int value) {
     assert(value == null || value >= 0);
     this._length = value;
   }
@@ -914,7 +898,7 @@
   String get message => _message ??= '';
 
   /// The message of the error.
-  void set message(String value) {
+  set message(String value) {
     this._message = value;
   }
 
@@ -922,7 +906,7 @@
   int get offset => _offset ??= 0;
 
   /// The offset from the beginning of the file.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -931,7 +915,7 @@
   String get uniqueName => _uniqueName ??= '';
 
   /// The unique name of the error code.
-  void set uniqueName(String value) {
+  set uniqueName(String value) {
     this._uniqueName = value;
   }
 
@@ -947,14 +931,10 @@
         _offset = offset,
         _uniqueName = uniqueName;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._offset ?? 0);
     signature.addInt(this._length ?? 0);
@@ -1106,7 +1086,7 @@
 
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the kind of the synthetic element.
-  void set elementKinds(List<idl.IndexSyntheticElementKind> value) {
+  set elementKinds(List<idl.IndexSyntheticElementKind> value) {
     this._elementKinds = value;
   }
 
@@ -1119,7 +1099,7 @@
   /// is a top-level element.  The list is sorted in ascending order, so that
   /// the client can quickly check whether an element is referenced in this
   /// index.
-  void set elementNameClassMemberIds(List<int> value) {
+  set elementNameClassMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameClassMemberIds = value;
   }
@@ -1131,7 +1111,7 @@
   /// the identifier of the named parameter name, or `null` if the element is
   /// not a named parameter.  The list is sorted in ascending order, so that the
   /// client can quickly check whether an element is referenced in this index.
-  void set elementNameParameterIds(List<int> value) {
+  set elementNameParameterIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameParameterIds = value;
   }
@@ -1144,7 +1124,7 @@
   /// the identifier of the top-level element name, or `null` if the element is
   /// the unit.  The list is sorted in ascending order, so that the client can
   /// quickly check whether an element is referenced in this index.
-  void set elementNameUnitMemberIds(List<int> value) {
+  set elementNameUnitMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameUnitMemberIds = value;
   }
@@ -1155,7 +1135,7 @@
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the index into [unitLibraryUris] and [unitUnitUris] for the library
   /// specific unit where the element is declared.
-  void set elementUnits(List<int> value) {
+  set elementUnits(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementUnits = value;
   }
@@ -1164,7 +1144,7 @@
   int get nullStringId => _nullStringId ??= 0;
 
   /// Identifier of the null string in [strings].
-  void set nullStringId(int value) {
+  set nullStringId(int value) {
     assert(value == null || value >= 0);
     this._nullStringId = value;
   }
@@ -1175,7 +1155,7 @@
   /// List of unique element strings used in this index.  The list is sorted in
   /// ascending order, so that the client can quickly check the presence of a
   /// string in this index.
-  void set strings(List<String> value) {
+  set strings(List<String> value) {
     this._strings = value;
   }
 
@@ -1184,7 +1164,7 @@
       _subtypes ??= <AnalysisDriverSubtypeBuilder>[];
 
   /// The list of classes declared in the unit.
-  void set subtypes(List<AnalysisDriverSubtypeBuilder> value) {
+  set subtypes(List<AnalysisDriverSubtypeBuilder> value) {
     this._subtypes = value;
   }
 
@@ -1195,7 +1175,7 @@
   /// in [subtypes].  They are indexes into [strings] list. The list is sorted
   /// in ascending order.  There might be more than one element with the same
   /// value if there is more than one subtype of this supertype.
-  void set supertypes(List<int> value) {
+  set supertypes(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._supertypes = value;
   }
@@ -1206,7 +1186,7 @@
   /// Each item of this list corresponds to the library URI of a unique library
   /// specific unit referenced in the index.  It is an index into [strings]
   /// list.
-  void set unitLibraryUris(List<int> value) {
+  set unitLibraryUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitLibraryUris = value;
   }
@@ -1217,7 +1197,7 @@
   /// Each item of this list corresponds to the unit URI of a unique library
   /// specific unit referenced in the index.  It is an index into [strings]
   /// list.
-  void set unitUnitUris(List<int> value) {
+  set unitUnitUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitUnitUris = value;
   }
@@ -1228,7 +1208,7 @@
 
   /// Each item of this list is the `true` if the corresponding element usage
   /// is qualified with some prefix.
-  void set usedElementIsQualifiedFlags(List<bool> value) {
+  set usedElementIsQualifiedFlags(List<bool> value) {
     this._usedElementIsQualifiedFlags = value;
   }
 
@@ -1237,7 +1217,7 @@
       _usedElementKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the element usage.
-  void set usedElementKinds(List<idl.IndexRelationKind> value) {
+  set usedElementKinds(List<idl.IndexRelationKind> value) {
     this._usedElementKinds = value;
   }
 
@@ -1245,7 +1225,7 @@
   List<int> get usedElementLengths => _usedElementLengths ??= <int>[];
 
   /// Each item of this list is the length of the element usage.
-  void set usedElementLengths(List<int> value) {
+  set usedElementLengths(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementLengths = value;
   }
@@ -1255,7 +1235,7 @@
 
   /// Each item of this list is the offset of the element usage relative to the
   /// beginning of the file.
-  void set usedElementOffsets(List<int> value) {
+  set usedElementOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementOffsets = value;
   }
@@ -1267,7 +1247,7 @@
   /// [elementNameUnitMemberIds], [elementNameClassMemberIds] and
   /// [elementNameParameterIds].  The list is sorted in ascending order, so
   /// that the client can quickly find element references in this index.
-  void set usedElements(List<int> value) {
+  set usedElements(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElements = value;
   }
@@ -1278,7 +1258,7 @@
 
   /// Each item of this list is the `true` if the corresponding name usage
   /// is qualified with some prefix.
-  void set usedNameIsQualifiedFlags(List<bool> value) {
+  set usedNameIsQualifiedFlags(List<bool> value) {
     this._usedNameIsQualifiedFlags = value;
   }
 
@@ -1287,7 +1267,7 @@
       _usedNameKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the name usage.
-  void set usedNameKinds(List<idl.IndexRelationKind> value) {
+  set usedNameKinds(List<idl.IndexRelationKind> value) {
     this._usedNameKinds = value;
   }
 
@@ -1296,7 +1276,7 @@
 
   /// Each item of this list is the offset of the name usage relative to the
   /// beginning of the file.
-  void set usedNameOffsets(List<int> value) {
+  set usedNameOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNameOffsets = value;
   }
@@ -1307,7 +1287,7 @@
   /// Each item of this list is the index into [strings] for a used name.  The
   /// list is sorted in ascending order, so that the client can quickly find
   /// whether a name is used in this index.
-  void set usedNames(List<int> value) {
+  set usedNames(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNames = value;
   }
@@ -1354,16 +1334,12 @@
         _usedNameOffsets = usedNameOffsets,
         _usedNames = usedNames;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _subtypes?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._strings == null) {
       signature.addInt(0);
@@ -1960,7 +1936,7 @@
       _definedClassMemberNames ??= <String>[];
 
   /// List of class member names defined by the unit.
-  void set definedClassMemberNames(List<String> value) {
+  set definedClassMemberNames(List<String> value) {
     this._definedClassMemberNames = value;
   }
 
@@ -1968,7 +1944,7 @@
   List<String> get definedTopLevelNames => _definedTopLevelNames ??= <String>[];
 
   /// List of top-level names defined by the unit.
-  void set definedTopLevelNames(List<String> value) {
+  set definedTopLevelNames(List<String> value) {
     this._definedTopLevelNames = value;
   }
 
@@ -1976,7 +1952,7 @@
   List<String> get referencedNames => _referencedNames ??= <String>[];
 
   /// List of external names referenced by the unit.
-  void set referencedNames(List<String> value) {
+  set referencedNames(List<String> value) {
     this._referencedNames = value;
   }
 
@@ -1985,7 +1961,7 @@
 
   /// List of names which are used in `extends`, `with` or `implements` clauses
   /// in the file. Import prefixes and type arguments are not included.
-  void set subtypedNames(List<String> value) {
+  set subtypedNames(List<String> value) {
     this._subtypedNames = value;
   }
 
@@ -1993,7 +1969,7 @@
   UnlinkedUnitBuilder get unit => _unit;
 
   /// Unlinked information for the unit.
-  void set unit(UnlinkedUnitBuilder value) {
+  set unit(UnlinkedUnitBuilder value) {
     this._unit = value;
   }
 
@@ -2009,16 +1985,12 @@
         _subtypedNames = subtypedNames,
         _unit = unit;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _unit?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._referencedNames == null) {
       signature.addInt(0);
@@ -2208,6 +2180,7 @@
 class AvailableDeclarationBuilder extends Object
     with _AvailableDeclarationMixin
     implements idl.AvailableDeclaration {
+  List<AvailableDeclarationBuilder> _children;
   String _defaultArgumentListString;
   List<int> _defaultArgumentListTextRanges;
   String _docComplete;
@@ -2222,7 +2195,6 @@
   int _locationStartColumn;
   int _locationStartLine;
   String _name;
-  String _name2;
   List<String> _parameterNames;
   String _parameters;
   List<String> _parameterTypes;
@@ -2232,9 +2204,17 @@
   String _typeParameters;
 
   @override
+  List<AvailableDeclarationBuilder> get children =>
+      _children ??= <AvailableDeclarationBuilder>[];
+
+  set children(List<AvailableDeclarationBuilder> value) {
+    this._children = value;
+  }
+
+  @override
   String get defaultArgumentListString => _defaultArgumentListString ??= '';
 
-  void set defaultArgumentListString(String value) {
+  set defaultArgumentListString(String value) {
     this._defaultArgumentListString = value;
   }
 
@@ -2242,7 +2222,7 @@
   List<int> get defaultArgumentListTextRanges =>
       _defaultArgumentListTextRanges ??= <int>[];
 
-  void set defaultArgumentListTextRanges(List<int> value) {
+  set defaultArgumentListTextRanges(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._defaultArgumentListTextRanges = value;
   }
@@ -2250,21 +2230,21 @@
   @override
   String get docComplete => _docComplete ??= '';
 
-  void set docComplete(String value) {
+  set docComplete(String value) {
     this._docComplete = value;
   }
 
   @override
   String get docSummary => _docSummary ??= '';
 
-  void set docSummary(String value) {
+  set docSummary(String value) {
     this._docSummary = value;
   }
 
   @override
   int get fieldMask => _fieldMask ??= 0;
 
-  void set fieldMask(int value) {
+  set fieldMask(int value) {
     assert(value == null || value >= 0);
     this._fieldMask = value;
   }
@@ -2272,28 +2252,28 @@
   @override
   bool get isAbstract => _isAbstract ??= false;
 
-  void set isAbstract(bool value) {
+  set isAbstract(bool value) {
     this._isAbstract = value;
   }
 
   @override
   bool get isConst => _isConst ??= false;
 
-  void set isConst(bool value) {
+  set isConst(bool value) {
     this._isConst = value;
   }
 
   @override
   bool get isDeprecated => _isDeprecated ??= false;
 
-  void set isDeprecated(bool value) {
+  set isDeprecated(bool value) {
     this._isDeprecated = value;
   }
 
   @override
   bool get isFinal => _isFinal ??= false;
 
-  void set isFinal(bool value) {
+  set isFinal(bool value) {
     this._isFinal = value;
   }
 
@@ -2302,14 +2282,14 @@
       _kind ??= idl.AvailableDeclarationKind.CLASS;
 
   /// The kind of the declaration.
-  void set kind(idl.AvailableDeclarationKind value) {
+  set kind(idl.AvailableDeclarationKind value) {
     this._kind = value;
   }
 
   @override
   int get locationOffset => _locationOffset ??= 0;
 
-  void set locationOffset(int value) {
+  set locationOffset(int value) {
     assert(value == null || value >= 0);
     this._locationOffset = value;
   }
@@ -2317,7 +2297,7 @@
   @override
   int get locationStartColumn => _locationStartColumn ??= 0;
 
-  void set locationStartColumn(int value) {
+  set locationStartColumn(int value) {
     assert(value == null || value >= 0);
     this._locationStartColumn = value;
   }
@@ -2325,7 +2305,7 @@
   @override
   int get locationStartLine => _locationStartLine ??= 0;
 
-  void set locationStartLine(int value) {
+  set locationStartLine(int value) {
     assert(value == null || value >= 0);
     this._locationStartLine = value;
   }
@@ -2335,37 +2315,28 @@
 
   /// The first part of the declaration name, usually the only one, for example
   /// the name of a class like `MyClass`, or a function like `myFunction`.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
   @override
-  String get name2 => _name2 ??= '';
-
-  /// The second, optional, part of the declaration name.  For example enum
-  /// constants all have the same [name], but their own [name2].
-  void set name2(String value) {
-    this._name2 = value;
-  }
-
-  @override
   List<String> get parameterNames => _parameterNames ??= <String>[];
 
-  void set parameterNames(List<String> value) {
+  set parameterNames(List<String> value) {
     this._parameterNames = value;
   }
 
   @override
   String get parameters => _parameters ??= '';
 
-  void set parameters(String value) {
+  set parameters(String value) {
     this._parameters = value;
   }
 
   @override
   List<String> get parameterTypes => _parameterTypes ??= <String>[];
 
-  void set parameterTypes(List<String> value) {
+  set parameterTypes(List<String> value) {
     this._parameterTypes = value;
   }
 
@@ -2376,14 +2347,14 @@
   /// example, function do not currently), and not every declaration has to
   /// store one (for classes it can be computed when we know the library that
   /// includes this file).
-  void set relevanceTags(List<String> value) {
+  set relevanceTags(List<String> value) {
     this._relevanceTags = value;
   }
 
   @override
   int get requiredParameterCount => _requiredParameterCount ??= 0;
 
-  void set requiredParameterCount(int value) {
+  set requiredParameterCount(int value) {
     assert(value == null || value >= 0);
     this._requiredParameterCount = value;
   }
@@ -2391,19 +2362,20 @@
   @override
   String get returnType => _returnType ??= '';
 
-  void set returnType(String value) {
+  set returnType(String value) {
     this._returnType = value;
   }
 
   @override
   String get typeParameters => _typeParameters ??= '';
 
-  void set typeParameters(String value) {
+  set typeParameters(String value) {
     this._typeParameters = value;
   }
 
   AvailableDeclarationBuilder(
-      {String defaultArgumentListString,
+      {List<AvailableDeclarationBuilder> children,
+      String defaultArgumentListString,
       List<int> defaultArgumentListTextRanges,
       String docComplete,
       String docSummary,
@@ -2417,7 +2389,6 @@
       int locationStartColumn,
       int locationStartLine,
       String name,
-      String name2,
       List<String> parameterNames,
       String parameters,
       List<String> parameterTypes,
@@ -2425,7 +2396,8 @@
       int requiredParameterCount,
       String returnType,
       String typeParameters})
-      : _defaultArgumentListString = defaultArgumentListString,
+      : _children = children,
+        _defaultArgumentListString = defaultArgumentListString,
         _defaultArgumentListTextRanges = defaultArgumentListTextRanges,
         _docComplete = docComplete,
         _docSummary = docSummary,
@@ -2439,7 +2411,6 @@
         _locationStartColumn = locationStartColumn,
         _locationStartLine = locationStartLine,
         _name = name,
-        _name2 = name2,
         _parameterNames = parameterNames,
         _parameters = parameters,
         _parameterTypes = parameterTypes,
@@ -2448,15 +2419,21 @@
         _returnType = returnType,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
-  void flushInformative() {}
+  /// Flush [informative] data recursively.
+  void flushInformative() {
+    _children?.forEach((b) => b.flushInformative());
+  }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._children == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._children.length);
+      for (var x in this._children) {
+        x?.collectApiSignature(signature);
+      }
+    }
     signature.addString(this._defaultArgumentListString ?? '');
     if (this._defaultArgumentListTextRanges == null) {
       signature.addInt(0);
@@ -2478,7 +2455,6 @@
     signature.addInt(this._locationStartColumn ?? 0);
     signature.addInt(this._locationStartLine ?? 0);
     signature.addString(this._name ?? '');
-    signature.addString(this._name2 ?? '');
     if (this._parameterNames == null) {
       signature.addInt(0);
     } else {
@@ -2510,18 +2486,22 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_children;
     fb.Offset offset_defaultArgumentListString;
     fb.Offset offset_defaultArgumentListTextRanges;
     fb.Offset offset_docComplete;
     fb.Offset offset_docSummary;
     fb.Offset offset_name;
-    fb.Offset offset_name2;
     fb.Offset offset_parameterNames;
     fb.Offset offset_parameters;
     fb.Offset offset_parameterTypes;
     fb.Offset offset_relevanceTags;
     fb.Offset offset_returnType;
     fb.Offset offset_typeParameters;
+    if (!(_children == null || _children.isEmpty)) {
+      offset_children = fbBuilder
+          .writeList(_children.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (_defaultArgumentListString != null) {
       offset_defaultArgumentListString =
           fbBuilder.writeString(_defaultArgumentListString);
@@ -2540,9 +2520,6 @@
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
-    if (_name2 != null) {
-      offset_name2 = fbBuilder.writeString(_name2);
-    }
     if (!(_parameterNames == null || _parameterNames.isEmpty)) {
       offset_parameterNames = fbBuilder.writeList(
           _parameterNames.map((b) => fbBuilder.writeString(b)).toList());
@@ -2565,50 +2542,50 @@
       offset_typeParameters = fbBuilder.writeString(_typeParameters);
     }
     fbBuilder.startTable();
+    if (offset_children != null) {
+      fbBuilder.addOffset(0, offset_children);
+    }
     if (offset_defaultArgumentListString != null) {
-      fbBuilder.addOffset(0, offset_defaultArgumentListString);
+      fbBuilder.addOffset(1, offset_defaultArgumentListString);
     }
     if (offset_defaultArgumentListTextRanges != null) {
-      fbBuilder.addOffset(1, offset_defaultArgumentListTextRanges);
+      fbBuilder.addOffset(2, offset_defaultArgumentListTextRanges);
     }
     if (offset_docComplete != null) {
-      fbBuilder.addOffset(2, offset_docComplete);
+      fbBuilder.addOffset(3, offset_docComplete);
     }
     if (offset_docSummary != null) {
-      fbBuilder.addOffset(3, offset_docSummary);
+      fbBuilder.addOffset(4, offset_docSummary);
     }
     if (_fieldMask != null && _fieldMask != 0) {
-      fbBuilder.addUint32(4, _fieldMask);
+      fbBuilder.addUint32(5, _fieldMask);
     }
     if (_isAbstract == true) {
-      fbBuilder.addBool(5, true);
-    }
-    if (_isConst == true) {
       fbBuilder.addBool(6, true);
     }
-    if (_isDeprecated == true) {
+    if (_isConst == true) {
       fbBuilder.addBool(7, true);
     }
-    if (_isFinal == true) {
+    if (_isDeprecated == true) {
       fbBuilder.addBool(8, true);
     }
+    if (_isFinal == true) {
+      fbBuilder.addBool(9, true);
+    }
     if (_kind != null && _kind != idl.AvailableDeclarationKind.CLASS) {
-      fbBuilder.addUint8(9, _kind.index);
+      fbBuilder.addUint8(10, _kind.index);
     }
     if (_locationOffset != null && _locationOffset != 0) {
-      fbBuilder.addUint32(10, _locationOffset);
+      fbBuilder.addUint32(11, _locationOffset);
     }
     if (_locationStartColumn != null && _locationStartColumn != 0) {
-      fbBuilder.addUint32(11, _locationStartColumn);
+      fbBuilder.addUint32(12, _locationStartColumn);
     }
     if (_locationStartLine != null && _locationStartLine != 0) {
-      fbBuilder.addUint32(12, _locationStartLine);
+      fbBuilder.addUint32(13, _locationStartLine);
     }
     if (offset_name != null) {
-      fbBuilder.addOffset(13, offset_name);
-    }
-    if (offset_name2 != null) {
-      fbBuilder.addOffset(14, offset_name2);
+      fbBuilder.addOffset(14, offset_name);
     }
     if (offset_parameterNames != null) {
       fbBuilder.addOffset(15, offset_parameterNames);
@@ -2652,6 +2629,7 @@
 
   _AvailableDeclarationImpl(this._bc, this._bcOffset);
 
+  List<idl.AvailableDeclaration> _children;
   String _defaultArgumentListString;
   List<int> _defaultArgumentListTextRanges;
   String _docComplete;
@@ -2666,7 +2644,6 @@
   int _locationStartColumn;
   int _locationStartLine;
   String _name;
-  String _name2;
   List<String> _parameterNames;
   String _parameters;
   List<String> _parameterTypes;
@@ -2676,102 +2653,104 @@
   String _typeParameters;
 
   @override
+  List<idl.AvailableDeclaration> get children {
+    _children ??= const fb.ListReader<idl.AvailableDeclaration>(
+            const _AvailableDeclarationReader())
+        .vTableGet(_bc, _bcOffset, 0, const <idl.AvailableDeclaration>[]);
+    return _children;
+  }
+
+  @override
   String get defaultArgumentListString {
     _defaultArgumentListString ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _defaultArgumentListString;
   }
 
   @override
   List<int> get defaultArgumentListTextRanges {
     _defaultArgumentListTextRanges ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
+        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
     return _defaultArgumentListTextRanges;
   }
 
   @override
   String get docComplete {
-    _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, '');
+    _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
     return _docComplete;
   }
 
   @override
   String get docSummary {
-    _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
+    _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
     return _docSummary;
   }
 
   @override
   int get fieldMask {
-    _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
+    _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
     return _fieldMask;
   }
 
   @override
   bool get isAbstract {
-    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
     return _isAbstract;
   }
 
   @override
   bool get isConst {
-    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
+    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
     return _isConst;
   }
 
   @override
   bool get isDeprecated {
-    _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
+    _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
     return _isDeprecated;
   }
 
   @override
   bool get isFinal {
-    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
+    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 9, false);
     return _isFinal;
   }
 
   @override
   idl.AvailableDeclarationKind get kind {
     _kind ??= const _AvailableDeclarationKindReader()
-        .vTableGet(_bc, _bcOffset, 9, idl.AvailableDeclarationKind.CLASS);
+        .vTableGet(_bc, _bcOffset, 10, idl.AvailableDeclarationKind.CLASS);
     return _kind;
   }
 
   @override
   int get locationOffset {
     _locationOffset ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
     return _locationOffset;
   }
 
   @override
   int get locationStartColumn {
     _locationStartColumn ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
     return _locationStartColumn;
   }
 
   @override
   int get locationStartLine {
     _locationStartLine ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 13, 0);
     return _locationStartLine;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 13, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, '');
     return _name;
   }
 
   @override
-  String get name2 {
-    _name2 ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, '');
-    return _name2;
-  }
-
-  @override
   List<String> get parameterNames {
     _parameterNames ??= const fb.ListReader<String>(const fb.StringReader())
         .vTableGet(_bc, _bcOffset, 15, const <String>[]);
@@ -2823,6 +2802,8 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (children.isNotEmpty)
+      _result["children"] = children.map((_value) => _value.toJson()).toList();
     if (defaultArgumentListString != '')
       _result["defaultArgumentListString"] = defaultArgumentListString;
     if (defaultArgumentListTextRanges.isNotEmpty)
@@ -2842,7 +2823,6 @@
     if (locationStartLine != 0)
       _result["locationStartLine"] = locationStartLine;
     if (name != '') _result["name"] = name;
-    if (name2 != '') _result["name2"] = name2;
     if (parameterNames.isNotEmpty) _result["parameterNames"] = parameterNames;
     if (parameters != '') _result["parameters"] = parameters;
     if (parameterTypes.isNotEmpty) _result["parameterTypes"] = parameterTypes;
@@ -2856,6 +2836,7 @@
 
   @override
   Map<String, Object> toMap() => {
+        "children": children,
         "defaultArgumentListString": defaultArgumentListString,
         "defaultArgumentListTextRanges": defaultArgumentListTextRanges,
         "docComplete": docComplete,
@@ -2870,7 +2851,6 @@
         "locationStartColumn": locationStartColumn,
         "locationStartLine": locationStartLine,
         "name": name,
-        "name2": name2,
         "parameterNames": parameterNames,
         "parameters": parameters,
         "parameterTypes": parameterTypes,
@@ -2887,36 +2867,36 @@
 class AvailableFileBuilder extends Object
     with _AvailableFileMixin
     implements idl.AvailableFile {
-  DirectiveInfoBuilder _directiveInfo;
   List<AvailableDeclarationBuilder> _declarations;
+  DirectiveInfoBuilder _directiveInfo;
   List<AvailableFileExportBuilder> _exports;
   bool _isLibrary;
   bool _isLibraryDeprecated;
   List<String> _parts;
 
   @override
-  DirectiveInfoBuilder get directiveInfo => _directiveInfo;
-
-  /// The Dartdoc directives in the file.
-  void set directiveInfo(DirectiveInfoBuilder value) {
-    this._directiveInfo = value;
-  }
-
-  @override
   List<AvailableDeclarationBuilder> get declarations =>
       _declarations ??= <AvailableDeclarationBuilder>[];
 
   /// Declarations of the file.
-  void set declarations(List<AvailableDeclarationBuilder> value) {
+  set declarations(List<AvailableDeclarationBuilder> value) {
     this._declarations = value;
   }
 
   @override
+  DirectiveInfoBuilder get directiveInfo => _directiveInfo;
+
+  /// The Dartdoc directives in the file.
+  set directiveInfo(DirectiveInfoBuilder value) {
+    this._directiveInfo = value;
+  }
+
+  @override
   List<AvailableFileExportBuilder> get exports =>
       _exports ??= <AvailableFileExportBuilder>[];
 
   /// Exports directives of the file.
-  void set exports(List<AvailableFileExportBuilder> value) {
+  set exports(List<AvailableFileExportBuilder> value) {
     this._exports = value;
   }
 
@@ -2924,7 +2904,7 @@
   bool get isLibrary => _isLibrary ??= false;
 
   /// Is `true` if this file is a library.
-  void set isLibrary(bool value) {
+  set isLibrary(bool value) {
     this._isLibrary = value;
   }
 
@@ -2932,7 +2912,7 @@
   bool get isLibraryDeprecated => _isLibraryDeprecated ??= false;
 
   /// Is `true` if this file is a library, and it is deprecated.
-  void set isLibraryDeprecated(bool value) {
+  set isLibraryDeprecated(bool value) {
     this._isLibraryDeprecated = value;
   }
 
@@ -2940,36 +2920,32 @@
   List<String> get parts => _parts ??= <String>[];
 
   /// URIs of `part` directives.
-  void set parts(List<String> value) {
+  set parts(List<String> value) {
     this._parts = value;
   }
 
   AvailableFileBuilder(
-      {DirectiveInfoBuilder directiveInfo,
-      List<AvailableDeclarationBuilder> declarations,
+      {List<AvailableDeclarationBuilder> declarations,
+      DirectiveInfoBuilder directiveInfo,
       List<AvailableFileExportBuilder> exports,
       bool isLibrary,
       bool isLibraryDeprecated,
       List<String> parts})
-      : _directiveInfo = directiveInfo,
-        _declarations = declarations,
+      : _declarations = declarations,
+        _directiveInfo = directiveInfo,
         _exports = exports,
         _isLibrary = isLibrary,
         _isLibraryDeprecated = isLibraryDeprecated,
         _parts = parts;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
-    _directiveInfo?.flushInformative();
     _declarations?.forEach((b) => b.flushInformative());
+    _directiveInfo?.flushInformative();
     _exports?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._declarations == null) {
       signature.addInt(0);
@@ -3007,17 +2983,17 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_directiveInfo;
     fb.Offset offset_declarations;
+    fb.Offset offset_directiveInfo;
     fb.Offset offset_exports;
     fb.Offset offset_parts;
-    if (_directiveInfo != null) {
-      offset_directiveInfo = _directiveInfo.finish(fbBuilder);
-    }
     if (!(_declarations == null || _declarations.isEmpty)) {
       offset_declarations = fbBuilder
           .writeList(_declarations.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (_directiveInfo != null) {
+      offset_directiveInfo = _directiveInfo.finish(fbBuilder);
+    }
     if (!(_exports == null || _exports.isEmpty)) {
       offset_exports = fbBuilder
           .writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
@@ -3027,12 +3003,12 @@
           .writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
-    if (offset_directiveInfo != null) {
-      fbBuilder.addOffset(5, offset_directiveInfo);
-    }
     if (offset_declarations != null) {
       fbBuilder.addOffset(0, offset_declarations);
     }
+    if (offset_directiveInfo != null) {
+      fbBuilder.addOffset(5, offset_directiveInfo);
+    }
     if (offset_exports != null) {
       fbBuilder.addOffset(1, offset_exports);
     }
@@ -3070,21 +3046,14 @@
 
   _AvailableFileImpl(this._bc, this._bcOffset);
 
-  idl.DirectiveInfo _directiveInfo;
   List<idl.AvailableDeclaration> _declarations;
+  idl.DirectiveInfo _directiveInfo;
   List<idl.AvailableFileExport> _exports;
   bool _isLibrary;
   bool _isLibraryDeprecated;
   List<String> _parts;
 
   @override
-  idl.DirectiveInfo get directiveInfo {
-    _directiveInfo ??=
-        const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null);
-    return _directiveInfo;
-  }
-
-  @override
   List<idl.AvailableDeclaration> get declarations {
     _declarations ??= const fb.ListReader<idl.AvailableDeclaration>(
             const _AvailableDeclarationReader())
@@ -3093,6 +3062,13 @@
   }
 
   @override
+  idl.DirectiveInfo get directiveInfo {
+    _directiveInfo ??=
+        const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null);
+    return _directiveInfo;
+  }
+
+  @override
   List<idl.AvailableFileExport> get exports {
     _exports ??= const fb.ListReader<idl.AvailableFileExport>(
             const _AvailableFileExportReader())
@@ -3125,11 +3101,11 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (directiveInfo != null)
-      _result["directiveInfo"] = directiveInfo.toJson();
     if (declarations.isNotEmpty)
       _result["declarations"] =
           declarations.map((_value) => _value.toJson()).toList();
+    if (directiveInfo != null)
+      _result["directiveInfo"] = directiveInfo.toJson();
     if (exports.isNotEmpty)
       _result["exports"] = exports.map((_value) => _value.toJson()).toList();
     if (isLibrary != false) _result["isLibrary"] = isLibrary;
@@ -3141,8 +3117,8 @@
 
   @override
   Map<String, Object> toMap() => {
-        "directiveInfo": directiveInfo,
         "declarations": declarations,
+        "directiveInfo": directiveInfo,
         "exports": exports,
         "isLibrary": isLibrary,
         "isLibraryDeprecated": isLibraryDeprecated,
@@ -3164,7 +3140,7 @@
       _combinators ??= <AvailableFileExportCombinatorBuilder>[];
 
   /// Combinators contained in this export directive.
-  void set combinators(List<AvailableFileExportCombinatorBuilder> value) {
+  set combinators(List<AvailableFileExportCombinatorBuilder> value) {
     this._combinators = value;
   }
 
@@ -3172,7 +3148,7 @@
   String get uri => _uri ??= '';
 
   /// URI of the exported library.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -3181,16 +3157,12 @@
       : _combinators = combinators,
         _uri = uri;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _combinators?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._combinators == null) {
@@ -3291,7 +3263,7 @@
   List<String> get hides => _hides ??= <String>[];
 
   /// List of names which are hidden.  Empty if this is a `show` combinator.
-  void set hides(List<String> value) {
+  set hides(List<String> value) {
     this._hides = value;
   }
 
@@ -3299,7 +3271,7 @@
   List<String> get shows => _shows ??= <String>[];
 
   /// List of names which are shown.  Empty if this is a `hide` combinator.
-  void set shows(List<String> value) {
+  set shows(List<String> value) {
     this._shows = value;
   }
 
@@ -3307,14 +3279,10 @@
       : _hides = hides,
         _shows = shows;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._shows == null) {
       signature.addInt(0);
@@ -3422,7 +3390,7 @@
   int get length => _length ??= 0;
 
   /// Length of the element code.
-  void set length(int value) {
+  set length(int value) {
     assert(value == null || value >= 0);
     this._length = value;
   }
@@ -3431,7 +3399,7 @@
   int get offset => _offset ??= 0;
 
   /// Offset of the element code relative to the beginning of the file.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -3440,14 +3408,10 @@
       : _length = length,
         _offset = offset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._offset ?? 0);
     signature.addInt(this._length ?? 0);
@@ -3526,7 +3490,7 @@
   List<String> get templateNames => _templateNames ??= <String>[];
 
   /// The names of the defined templates.
-  void set templateNames(List<String> value) {
+  set templateNames(List<String> value) {
     this._templateNames = value;
   }
 
@@ -3534,7 +3498,7 @@
   List<String> get templateValues => _templateValues ??= <String>[];
 
   /// The values of the defined templates.
-  void set templateValues(List<String> value) {
+  set templateValues(List<String> value) {
     this._templateValues = value;
   }
 
@@ -3543,14 +3507,10 @@
       : _templateNames = templateNames,
         _templateValues = templateValues;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._templateNames == null) {
       signature.addInt(0);
@@ -3663,7 +3623,7 @@
   idl.EntityRefKind get entityKind => _entityKind ??= idl.EntityRefKind.named;
 
   /// The kind of entity being represented.
-  void set entityKind(idl.EntityRefKind value) {
+  set entityKind(idl.EntityRefKind value) {
     this._entityKind = value;
   }
 
@@ -3697,7 +3657,7 @@
   /// Note that if the entity being referred to is a generic method inside a
   /// generic class, then the type arguments in [typeArguments] are applied
   /// first to the class and then to the method.
-  void set implicitFunctionTypeIndices(List<int> value) {
+  set implicitFunctionTypeIndices(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._implicitFunctionTypeIndices = value;
   }
@@ -3722,7 +3682,7 @@
   ///
   /// If the type being referred to is not a type parameter, [paramReference] is
   /// zero.
-  void set paramReference(int value) {
+  set paramReference(int value) {
     assert(value == null || value >= 0);
     this._paramReference = value;
   }
@@ -3732,7 +3692,7 @@
 
   /// Index into [UnlinkedUnit.references] for the entity being referred to, or
   /// zero if this is a reference to a type parameter.
-  void set reference(int value) {
+  set reference(int value) {
     assert(value == null || value >= 0);
     this._reference = value;
   }
@@ -3750,7 +3710,7 @@
   /// This is called `refinedSlot` to clarify that if it points to an inferred
   /// type, it points to a type that is a "refinement" of this one (one in which
   /// some type arguments have been inferred).
-  void set refinedSlot(int value) {
+  set refinedSlot(int value) {
     assert(value == null || value >= 0);
     this._refinedSlot = value;
   }
@@ -3763,7 +3723,7 @@
   /// propagation or type inference with which this [EntityRef] is associated.
   ///
   /// Otherwise zero.
-  void set slot(int value) {
+  set slot(int value) {
     assert(value == null || value >= 0);
     this._slot = value;
   }
@@ -3776,7 +3736,7 @@
   /// [FunctionElement] is not in any library (e.g. a function type that was
   /// synthesized by a LUB computation), the function parameters.  Otherwise
   /// empty.
-  void set syntheticParams(List<UnlinkedParamBuilder> value) {
+  set syntheticParams(List<UnlinkedParamBuilder> value) {
     this._syntheticParams = value;
   }
 
@@ -3787,7 +3747,7 @@
   /// [FunctionElement] is not in any library (e.g. a function type that was
   /// synthesized by a LUB computation), the return type of the function.
   /// Otherwise `null`.
-  void set syntheticReturnType(EntityRefBuilder value) {
+  set syntheticReturnType(EntityRefBuilder value) {
     this._syntheticReturnType = value;
   }
 
@@ -3797,7 +3757,7 @@
 
   /// If this is an instantiation of a generic type or generic executable, the
   /// type arguments used to instantiate it (if any).
-  void set typeArguments(List<EntityRefBuilder> value) {
+  set typeArguments(List<EntityRefBuilder> value) {
     this._typeArguments = value;
   }
 
@@ -3807,7 +3767,7 @@
 
   /// If this is a function type, the type parameters defined for the function
   /// type (if any).
-  void set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
     this._typeParameters = value;
   }
 
@@ -3833,9 +3793,7 @@
         _typeArguments = typeArguments,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _syntheticParams?.forEach((b) => b.flushInformative());
     _syntheticReturnType?.flushInformative();
@@ -3843,9 +3801,7 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._reference ?? 0);
     if (this._typeArguments == null) {
@@ -4101,7 +4057,7 @@
 
   /// Absolute URI for the compilation units listed in the library's `part`
   /// declarations, empty string for invalid URI.
-  void set parts(List<String> value) {
+  set parts(List<String> value) {
     this._parts = value;
   }
 
@@ -4109,7 +4065,7 @@
   String get uri => _uri ??= '';
 
   /// The absolute URI of the dependent library, e.g. `package:foo/bar.dart`.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -4117,14 +4073,10 @@
       : _parts = parts,
         _uri = uri;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._parts == null) {
@@ -4223,7 +4175,7 @@
 
   /// Index into [LinkedLibrary.dependencies] for the library in which the
   /// entity is defined.
-  void set dependency(int value) {
+  set dependency(int value) {
     assert(value == null || value >= 0);
     this._dependency = value;
   }
@@ -4232,7 +4184,7 @@
   idl.ReferenceKind get kind => _kind ??= idl.ReferenceKind.classOrEnum;
 
   /// The kind of the entity being referred to.
-  void set kind(idl.ReferenceKind value) {
+  set kind(idl.ReferenceKind value) {
     this._kind = value;
   }
 
@@ -4241,7 +4193,7 @@
 
   /// Name of the exported entity.  For an exported setter, this name includes
   /// the trailing '='.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -4252,7 +4204,7 @@
   /// definition of the entity.  As with indices into [LinkedLibrary.units],
   /// zero represents the defining compilation unit, and nonzero values
   /// represent parts in the order of the corresponding `part` declarations.
-  void set unit(int value) {
+  set unit(int value) {
     assert(value == null || value >= 0);
     this._unit = value;
   }
@@ -4264,14 +4216,10 @@
         _name = name,
         _unit = unit;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._dependency ?? 0);
     signature.addString(this._name ?? '');
@@ -4400,7 +4348,7 @@
   /// implicitly refers to an element declared in the library) or
   /// anti-dependency (e.g. the result of type propagation or type inference
   /// depends on the lack of a certain declaration in the library).
-  void set dependencies(List<LinkedDependencyBuilder> value) {
+  set dependencies(List<LinkedDependencyBuilder> value) {
     this._dependencies = value;
   }
 
@@ -4409,7 +4357,7 @@
 
   /// For each export in [UnlinkedUnit.exports], an index into [dependencies]
   /// of the library being exported.
-  void set exportDependencies(List<int> value) {
+  set exportDependencies(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._exportDependencies = value;
   }
@@ -4423,7 +4371,7 @@
   /// brought into the namespace via `export` directives).
   ///
   /// Sorted by name.
-  void set exportNames(List<LinkedExportNameBuilder> value) {
+  set exportNames(List<LinkedExportNameBuilder> value) {
     this._exportNames = value;
   }
 
@@ -4436,7 +4384,7 @@
 
   /// For each import in [UnlinkedUnit.imports], an index into [dependencies]
   /// of the library being imported.
-  void set importDependencies(List<int> value) {
+  set importDependencies(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._importDependencies = value;
   }
@@ -4447,7 +4395,7 @@
   /// The number of elements in [dependencies] which are not "linked"
   /// dependencies (that is, the number of libraries in the direct imports plus
   /// the transitive closure of exports, plus the library itself).
-  void set numPrelinkedDependencies(int value) {
+  set numPrelinkedDependencies(int value) {
     assert(value == null || value >= 0);
     this._numPrelinkedDependencies = value;
   }
@@ -4459,7 +4407,7 @@
   /// library.  The summary of the defining compilation unit is listed first,
   /// followed by the summary of each part, in the order of the `part`
   /// declarations in the defining compilation unit.
-  void set units(List<LinkedUnitBuilder> value) {
+  set units(List<LinkedUnitBuilder> value) {
     this._units = value;
   }
 
@@ -4477,18 +4425,14 @@
         _numPrelinkedDependencies = numPrelinkedDependencies,
         _units = units;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _dependencies?.forEach((b) => b.flushInformative());
     _exportNames?.forEach((b) => b.flushInformative());
     _units?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._dependencies == null) {
       signature.addInt(0);
@@ -4702,6 +4646,7 @@
 class LinkedNodeBuilder extends Object
     with _LinkedNodeMixin
     implements idl.LinkedNode {
+  LinkedNodeTypeBuilder _variantField_24;
   List<LinkedNodeBuilder> _variantField_2;
   LinkedNodeBuilder _variantField_11;
   List<LinkedNodeBuilder> _variantField_4;
@@ -4713,7 +4658,6 @@
   int _variantField_17;
   int _variantField_18;
   int _variantField_19;
-  LinkedNodeTypeBuilder _variantField_24;
   bool _variantField_27;
   LinkedNodeBuilder _variantField_9;
   LinkedNodeBuilder _variantField_12;
@@ -4739,6 +4683,78 @@
   LinkedNodeVariablesDeclarationBuilder _variantField_32;
 
   @override
+  LinkedNodeTypeBuilder get actualReturnType {
+    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionExpression ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericFunctionType ||
+        kind == idl.LinkedNodeKind.methodDeclaration);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get actualType {
+    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get binaryExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get invocationExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
+        kind == idl.LinkedNodeKind.methodInvocation);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get typeName_type {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    return _variantField_24;
+  }
+
+  /// The explicit or inferred return type of a function typed node.
+  set actualReturnType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionExpression ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericFunctionType ||
+        kind == idl.LinkedNodeKind.methodDeclaration);
+    _variantField_24 = value;
+  }
+
+  set actualType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    _variantField_24 = value;
+  }
+
+  set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    _variantField_24 = value;
+  }
+
+  set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
+        kind == idl.LinkedNodeKind.methodInvocation);
+    _variantField_24 = value;
+  }
+
+  set typeName_type(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    _variantField_24 = value;
+  }
+
+  @override
   List<LinkedNodeBuilder> get adjacentStrings_strings {
     assert(kind == idl.LinkedNodeKind.adjacentStrings);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
@@ -4889,128 +4905,128 @@
     return _variantField_2 ??= <LinkedNodeBuilder>[];
   }
 
-  void set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
+  set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.adjacentStrings);
     _variantField_2 = value;
   }
 
-  void set argumentList_arguments(List<LinkedNodeBuilder> value) {
+  set argumentList_arguments(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     _variantField_2 = value;
   }
 
-  void set block_statements(List<LinkedNodeBuilder> value) {
+  set block_statements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.block);
     _variantField_2 = value;
   }
 
-  void set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
+  set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.cascadeExpression);
     _variantField_2 = value;
   }
 
-  void set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
+  set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     _variantField_2 = value;
   }
 
-  void set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
+  set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_2 = value;
   }
 
-  void set dottedName_components(List<LinkedNodeBuilder> value) {
+  set dottedName_components(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.dottedName);
     _variantField_2 = value;
   }
 
-  void set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
+  set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     _variantField_2 = value;
   }
 
-  void set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
+  set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     _variantField_2 = value;
   }
 
-  void set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) {
+  set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.hideCombinator);
     _variantField_2 = value;
   }
 
-  void set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
+  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.implementsClause);
     _variantField_2 = value;
   }
 
-  void set labeledStatement_labels(List<LinkedNodeBuilder> value) {
+  set labeledStatement_labels(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.labeledStatement);
     _variantField_2 = value;
   }
 
-  void set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
+  set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.libraryIdentifier);
     _variantField_2 = value;
   }
 
-  void set listLiteral_elements(List<LinkedNodeBuilder> value) {
+  set listLiteral_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     _variantField_2 = value;
   }
 
-  void set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
+  set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
     _variantField_2 = value;
   }
 
-  void set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
+  set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.onClause);
     _variantField_2 = value;
   }
 
-  void set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
+  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     _variantField_2 = value;
   }
 
-  void set showCombinator_shownNames(List<LinkedNodeBuilder> value) {
+  set showCombinator_shownNames(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.showCombinator);
     _variantField_2 = value;
   }
 
-  void set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
+  set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.stringInterpolation);
     _variantField_2 = value;
   }
 
-  void set switchStatement_members(List<LinkedNodeBuilder> value) {
+  set switchStatement_members(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     _variantField_2 = value;
   }
 
-  void set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
+  set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_2 = value;
   }
 
-  void set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
+  set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     _variantField_2 = value;
   }
 
-  void set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
+  set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     _variantField_2 = value;
   }
 
-  void set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
+  set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     _variantField_2 = value;
   }
 
-  void set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
+  set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.withClause);
     _variantField_2 = value;
   }
@@ -5041,7 +5057,7 @@
     return _variantField_11;
   }
 
-  void set annotatedNode_comment(LinkedNodeBuilder value) {
+  set annotatedNode_comment(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -5107,7 +5123,7 @@
     return _variantField_4 ??= <LinkedNodeBuilder>[];
   }
 
-  void set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
+  set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -5132,14 +5148,14 @@
     _variantField_4 = value;
   }
 
-  void set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
+  set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_4 = value;
   }
 
-  void set switchMember_statements(List<LinkedNodeBuilder> value) {
+  set switchMember_statements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     _variantField_4 = value;
@@ -5617,398 +5633,397 @@
     return _variantField_6;
   }
 
-  void set annotation_arguments(LinkedNodeBuilder value) {
+  set annotation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_6 = value;
   }
 
-  void set asExpression_expression(LinkedNodeBuilder value) {
+  set asExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     _variantField_6 = value;
   }
 
-  void set assertInitializer_condition(LinkedNodeBuilder value) {
+  set assertInitializer_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     _variantField_6 = value;
   }
 
-  void set assertStatement_condition(LinkedNodeBuilder value) {
+  set assertStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     _variantField_6 = value;
   }
 
-  void set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
+  set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     _variantField_6 = value;
   }
 
-  void set awaitExpression_expression(LinkedNodeBuilder value) {
+  set awaitExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.awaitExpression);
     _variantField_6 = value;
   }
 
-  void set binaryExpression_leftOperand(LinkedNodeBuilder value) {
+  set binaryExpression_leftOperand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     _variantField_6 = value;
   }
 
-  void set blockFunctionBody_block(LinkedNodeBuilder value) {
+  set blockFunctionBody_block(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     _variantField_6 = value;
   }
 
-  void set breakStatement_label(LinkedNodeBuilder value) {
+  set breakStatement_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     _variantField_6 = value;
   }
 
-  void set cascadeExpression_target(LinkedNodeBuilder value) {
+  set cascadeExpression_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.cascadeExpression);
     _variantField_6 = value;
   }
 
-  void set catchClause_body(LinkedNodeBuilder value) {
+  set catchClause_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_6 = value;
   }
 
-  void set classDeclaration_extendsClause(LinkedNodeBuilder value) {
+  set classDeclaration_extendsClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_6 = value;
   }
 
-  void set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_6 = value;
   }
 
-  void set compilationUnit_scriptTag(LinkedNodeBuilder value) {
+  set compilationUnit_scriptTag(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     _variantField_6 = value;
   }
 
-  void set conditionalExpression_condition(LinkedNodeBuilder value) {
+  set conditionalExpression_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_6 = value;
   }
 
-  void set configuration_name(LinkedNodeBuilder value) {
+  set configuration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_6 = value;
   }
 
-  void set constructorDeclaration_body(LinkedNodeBuilder value) {
+  set constructorDeclaration_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_6 = value;
   }
 
-  void set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
+  set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_6 = value;
   }
 
-  void set constructorName_name(LinkedNodeBuilder value) {
+  set constructorName_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     _variantField_6 = value;
   }
 
-  void set continueStatement_label(LinkedNodeBuilder value) {
+  set continueStatement_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     _variantField_6 = value;
   }
 
-  void set declaredIdentifier_identifier(LinkedNodeBuilder value) {
+  set declaredIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     _variantField_6 = value;
   }
 
-  void set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
+  set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_6 = value;
   }
 
-  void set doStatement_body(LinkedNodeBuilder value) {
+  set doStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     _variantField_6 = value;
   }
 
-  void set enumConstantDeclaration_name(LinkedNodeBuilder value) {
+  set enumConstantDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.enumConstantDeclaration);
     _variantField_6 = value;
   }
 
-  void set expressionFunctionBody_expression(LinkedNodeBuilder value) {
+  set expressionFunctionBody_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     _variantField_6 = value;
   }
 
-  void set expressionStatement_expression(LinkedNodeBuilder value) {
+  set expressionStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.expressionStatement);
     _variantField_6 = value;
   }
 
-  void set extendsClause_superclass(LinkedNodeBuilder value) {
+  set extendsClause_superclass(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.extendsClause);
     _variantField_6 = value;
   }
 
-  void set fieldDeclaration_fields(LinkedNodeBuilder value) {
+  set fieldDeclaration_fields(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     _variantField_6 = value;
   }
 
-  void set fieldFormalParameter_type(LinkedNodeBuilder value) {
+  set fieldFormalParameter_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_6 = value;
   }
 
-  void set forEachParts_iterable(LinkedNodeBuilder value) {
+  set forEachParts_iterable(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
         kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     _variantField_6 = value;
   }
 
-  void set forMixin_forLoopParts(LinkedNodeBuilder value) {
+  set forMixin_forLoopParts(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     _variantField_6 = value;
   }
 
-  void set forParts_condition(LinkedNodeBuilder value) {
+  set forParts_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     _variantField_6 = value;
   }
 
-  void set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
+  set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     _variantField_6 = value;
   }
 
-  void set functionDeclarationStatement_functionDeclaration(
+  set functionDeclarationStatement_functionDeclaration(
       LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
     _variantField_6 = value;
   }
 
-  void set functionExpression_body(LinkedNodeBuilder value) {
+  set functionExpression_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_6 = value;
   }
 
-  void set functionExpressionInvocation_function(LinkedNodeBuilder value) {
+  set functionExpressionInvocation_function(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
     _variantField_6 = value;
   }
 
-  void set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
+  set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_6 = value;
   }
 
-  void set functionTypedFormalParameter_formalParameters(
-      LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_6 = value;
   }
 
-  void set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
+  set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_6 = value;
   }
 
-  void set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     _variantField_6 = value;
   }
 
-  void set ifMixin_condition(LinkedNodeBuilder value) {
+  set ifMixin_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     _variantField_6 = value;
   }
 
-  void set importDirective_prefix(LinkedNodeBuilder value) {
+  set importDirective_prefix(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     _variantField_6 = value;
   }
 
-  void set indexExpression_index(LinkedNodeBuilder value) {
+  set indexExpression_index(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_6 = value;
   }
 
-  void set instanceCreationExpression_arguments(LinkedNodeBuilder value) {
+  set instanceCreationExpression_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_6 = value;
   }
 
-  void set interpolationExpression_expression(LinkedNodeBuilder value) {
+  set interpolationExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     _variantField_6 = value;
   }
 
-  void set isExpression_expression(LinkedNodeBuilder value) {
+  set isExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     _variantField_6 = value;
   }
 
-  void set label_label(LinkedNodeBuilder value) {
+  set label_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.label);
     _variantField_6 = value;
   }
 
-  void set labeledStatement_statement(LinkedNodeBuilder value) {
+  set labeledStatement_statement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.labeledStatement);
     _variantField_6 = value;
   }
 
-  void set libraryDirective_name(LinkedNodeBuilder value) {
+  set libraryDirective_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.libraryDirective);
     _variantField_6 = value;
   }
 
-  void set mapLiteralEntry_key(LinkedNodeBuilder value) {
+  set mapLiteralEntry_key(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     _variantField_6 = value;
   }
 
-  void set methodDeclaration_body(LinkedNodeBuilder value) {
+  set methodDeclaration_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_6 = value;
   }
 
-  void set methodInvocation_methodName(LinkedNodeBuilder value) {
+  set methodInvocation_methodName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_6 = value;
   }
 
-  void set mixinDeclaration_onClause(LinkedNodeBuilder value) {
+  set mixinDeclaration_onClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mixinDeclaration);
     _variantField_6 = value;
   }
 
-  void set namedExpression_expression(LinkedNodeBuilder value) {
+  set namedExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.namedExpression);
     _variantField_6 = value;
   }
 
-  void set nativeClause_name(LinkedNodeBuilder value) {
+  set nativeClause_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.nativeClause);
     _variantField_6 = value;
   }
 
-  void set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
+  set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     _variantField_6 = value;
   }
 
-  void set parenthesizedExpression_expression(LinkedNodeBuilder value) {
+  set parenthesizedExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     _variantField_6 = value;
   }
 
-  void set partOfDirective_libraryName(LinkedNodeBuilder value) {
+  set partOfDirective_libraryName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     _variantField_6 = value;
   }
 
-  void set postfixExpression_operand(LinkedNodeBuilder value) {
+  set postfixExpression_operand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     _variantField_6 = value;
   }
 
-  void set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
+  set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     _variantField_6 = value;
   }
 
-  void set prefixExpression_operand(LinkedNodeBuilder value) {
+  set prefixExpression_operand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     _variantField_6 = value;
   }
 
-  void set propertyAccess_propertyName(LinkedNodeBuilder value) {
+  set propertyAccess_propertyName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     _variantField_6 = value;
   }
 
-  void set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
+  set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     _variantField_6 = value;
   }
 
-  void set returnStatement_expression(LinkedNodeBuilder value) {
+  set returnStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     _variantField_6 = value;
   }
 
-  void set simpleFormalParameter_type(LinkedNodeBuilder value) {
+  set simpleFormalParameter_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_6 = value;
   }
 
-  void set spreadElement_expression(LinkedNodeBuilder value) {
+  set spreadElement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.spreadElement);
     _variantField_6 = value;
   }
 
-  void set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
+  set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     _variantField_6 = value;
   }
 
-  void set switchCase_expression(LinkedNodeBuilder value) {
+  set switchCase_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.switchCase);
     _variantField_6 = value;
   }
 
-  void set throwExpression_expression(LinkedNodeBuilder value) {
+  set throwExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.throwExpression);
     _variantField_6 = value;
   }
 
-  void set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
+  set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
     _variantField_6 = value;
   }
 
-  void set tryStatement_body(LinkedNodeBuilder value) {
+  set tryStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_6 = value;
   }
 
-  void set typeName_name(LinkedNodeBuilder value) {
+  set typeName_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     _variantField_6 = value;
   }
 
-  void set typeParameter_bound(LinkedNodeBuilder value) {
+  set typeParameter_bound(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     _variantField_6 = value;
   }
 
-  void set variableDeclaration_initializer(LinkedNodeBuilder value) {
+  set variableDeclaration_initializer(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_6 = value;
   }
 
-  void set variableDeclarationList_type(LinkedNodeBuilder value) {
+  set variableDeclarationList_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     _variantField_6 = value;
   }
 
-  void set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
+  set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
     _variantField_6 = value;
   }
 
-  void set whileStatement_body(LinkedNodeBuilder value) {
+  set whileStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_6 = value;
   }
 
-  void set yieldStatement_expression(LinkedNodeBuilder value) {
+  set yieldStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     _variantField_6 = value;
   }
@@ -6570,558 +6585,558 @@
     return _variantField_15 ??= 0;
   }
 
-  void set annotation_atSign(int value) {
+  set annotation_atSign(int value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set argumentList_leftParenthesis(int value) {
+  set argumentList_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set asExpression_asOperator(int value) {
+  set asExpression_asOperator(int value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assertInitializer_assertKeyword(int value) {
+  set assertInitializer_assertKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assertStatement_assertKeyword(int value) {
+  set assertStatement_assertKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assignmentExpression_element(int value) {
+  set assignmentExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set awaitExpression_awaitKeyword(int value) {
+  set awaitExpression_awaitKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.awaitExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set binaryExpression_element(int value) {
+  set binaryExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set block_leftBracket(int value) {
+  set block_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.block);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set blockFunctionBody_keyword(int value) {
+  set blockFunctionBody_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set booleanLiteral_literal(int value) {
+  set booleanLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.booleanLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set breakStatement_breakKeyword(int value) {
+  set breakStatement_breakKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set catchClause_catchKeyword(int value) {
+  set catchClause_catchKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set classDeclaration_abstractKeyword(int value) {
+  set classDeclaration_abstractKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set classTypeAlias_abstractKeyword(int value) {
+  set classTypeAlias_abstractKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set compilationUnit_beginToken(int value) {
+  set compilationUnit_beginToken(int value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set conditionalExpression_colon(int value) {
+  set conditionalExpression_colon(int value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set configuration_ifKeyword(int value) {
+  set configuration_ifKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorDeclaration_constKeyword(int value) {
+  set constructorDeclaration_constKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorFieldInitializer_equals(int value) {
+  set constructorFieldInitializer_equals(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorName_element(int value) {
+  set constructorName_element(int value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set continueStatement_continueKeyword(int value) {
+  set continueStatement_continueKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set declaredIdentifier_keyword(int value) {
+  set declaredIdentifier_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set defaultFormalParameter_separator(int value) {
+  set defaultFormalParameter_separator(int value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set doStatement_leftParenthesis(int value) {
+  set doStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set doubleLiteral_literal(int value) {
+  set doubleLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.doubleLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set emptyFunctionBody_semicolon(int value) {
+  set emptyFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set emptyStatement_semicolon(int value) {
+  set emptyStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.emptyStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set enumDeclaration_enumKeyword(int value) {
+  set enumDeclaration_enumKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set expressionFunctionBody_arrow(int value) {
+  set expressionFunctionBody_arrow(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set expressionStatement_semicolon(int value) {
+  set expressionStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.expressionStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set extendsClause_extendsKeyword(int value) {
+  set extendsClause_extendsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.extendsClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set fieldDeclaration_covariantKeyword(int value) {
+  set fieldDeclaration_covariantKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set fieldFormalParameter_keyword(int value) {
+  set fieldFormalParameter_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forEachParts_inKeyword(int value) {
+  set forEachParts_inKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
         kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set formalParameterList_leftDelimiter(int value) {
+  set formalParameterList_leftDelimiter(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forMixin_awaitKeyword(int value) {
+  set forMixin_awaitKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forParts_leftSeparator(int value) {
+  set forParts_leftSeparator(int value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set functionDeclaration_externalKeyword(int value) {
+  set functionDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set genericFunctionType_functionKeyword(int value) {
+  set genericFunctionType_functionKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set ifMixin_elseKeyword(int value) {
+  set ifMixin_elseKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set implementsClause_implementsKeyword(int value) {
+  set implementsClause_implementsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.implementsClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set importDirective_asKeyword(int value) {
+  set importDirective_asKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set indexExpression_element(int value) {
+  set indexExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set instanceCreationExpression_keyword(int value) {
+  set instanceCreationExpression_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set integerLiteral_literal(int value) {
+  set integerLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.integerLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set interpolationExpression_leftBracket(int value) {
+  set interpolationExpression_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set interpolationString_token(int value) {
+  set interpolationString_token(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationString);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set isExpression_isOperator(int value) {
+  set isExpression_isOperator(int value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set label_colon(int value) {
+  set label_colon(int value) {
     assert(kind == idl.LinkedNodeKind.label);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set listLiteral_leftBracket(int value) {
+  set listLiteral_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set mapLiteralEntry_separator(int value) {
+  set mapLiteralEntry_separator(int value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set methodDeclaration_externalKeyword(int value) {
+  set methodDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set methodInvocation_operator(int value) {
+  set methodInvocation_operator(int value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set mixinDeclaration_mixinKeyword(int value) {
+  set mixinDeclaration_mixinKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nativeClause_nativeKeyword(int value) {
+  set nativeClause_nativeKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.nativeClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nativeFunctionBody_nativeKeyword(int value) {
+  set nativeFunctionBody_nativeKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nullLiteral_literal(int value) {
+  set nullLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.nullLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set onClause_onKeyword(int value) {
+  set onClause_onKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.onClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set parenthesizedExpression_leftParenthesis(int value) {
+  set parenthesizedExpression_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set postfixExpression_element(int value) {
+  set postfixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set prefixedIdentifier_period(int value) {
+  set prefixedIdentifier_period(int value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set prefixExpression_element(int value) {
+  set prefixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set propertyAccess_operator(int value) {
+  set propertyAccess_operator(int value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set redirectingConstructorInvocation_element(int value) {
+  set redirectingConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set rethrowExpression_rethrowKeyword(int value) {
+  set rethrowExpression_rethrowKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.rethrowExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set returnStatement_returnKeyword(int value) {
+  set returnStatement_returnKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set scriptTag_scriptTag(int value) {
+  set scriptTag_scriptTag(int value) {
     assert(kind == idl.LinkedNodeKind.scriptTag);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set setOrMapLiteral_leftBracket(int value) {
+  set setOrMapLiteral_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleFormalParameter_keyword(int value) {
+  set simpleFormalParameter_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleIdentifier_element(int value) {
+  set simpleIdentifier_element(int value) {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleStringLiteral_token(int value) {
+  set simpleStringLiteral_token(int value) {
     assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set spreadElement_spreadOperator(int value) {
+  set spreadElement_spreadOperator(int value) {
     assert(kind == idl.LinkedNodeKind.spreadElement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set superConstructorInvocation_element(int value) {
+  set superConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set superExpression_superKeyword(int value) {
+  set superExpression_superKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.superExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set switchMember_keyword(int value) {
+  set switchMember_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set switchStatement_leftParenthesis(int value) {
+  set switchStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set symbolLiteral_poundSign(int value) {
+  set symbolLiteral_poundSign(int value) {
     assert(kind == idl.LinkedNodeKind.symbolLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set thisExpression_thisKeyword(int value) {
+  set thisExpression_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.thisExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set throwExpression_throwKeyword(int value) {
+  set throwExpression_throwKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.throwExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set topLevelVariableDeclaration_semicolon(int value) {
+  set topLevelVariableDeclaration_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set tryStatement_finallyKeyword(int value) {
+  set tryStatement_finallyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeArgumentList_leftBracket(int value) {
+  set typeArgumentList_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeName_question(int value) {
+  set typeName_question(int value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeParameter_extendsKeyword(int value) {
+  set typeParameter_extendsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeParameterList_leftBracket(int value) {
+  set typeParameterList_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclaration_equals(int value) {
+  set variableDeclaration_equals(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclarationList_keyword(int value) {
+  set variableDeclarationList_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclarationStatement_semicolon(int value) {
+  set variableDeclarationStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set whileStatement_leftParenthesis(int value) {
+  set whileStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set withClause_withKeyword(int value) {
+  set withClause_withKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.withClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set yieldStatement_yieldKeyword(int value) {
+  set yieldStatement_yieldKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
@@ -7421,248 +7436,248 @@
     return _variantField_7;
   }
 
-  void set annotation_constructorName(LinkedNodeBuilder value) {
+  set annotation_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_7 = value;
   }
 
-  void set asExpression_type(LinkedNodeBuilder value) {
+  set asExpression_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     _variantField_7 = value;
   }
 
-  void set assertInitializer_message(LinkedNodeBuilder value) {
+  set assertInitializer_message(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     _variantField_7 = value;
   }
 
-  void set assertStatement_message(LinkedNodeBuilder value) {
+  set assertStatement_message(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     _variantField_7 = value;
   }
 
-  void set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
+  set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     _variantField_7 = value;
   }
 
-  void set binaryExpression_rightOperand(LinkedNodeBuilder value) {
+  set binaryExpression_rightOperand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     _variantField_7 = value;
   }
 
-  void set catchClause_exceptionParameter(LinkedNodeBuilder value) {
+  set catchClause_exceptionParameter(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_7 = value;
   }
 
-  void set classDeclaration_withClause(LinkedNodeBuilder value) {
+  set classDeclaration_withClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_7 = value;
   }
 
-  void set classTypeAlias_superclass(LinkedNodeBuilder value) {
+  set classTypeAlias_superclass(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_7 = value;
   }
 
-  void set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
+  set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_7 = value;
   }
 
-  void set configuration_value(LinkedNodeBuilder value) {
+  set configuration_value(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_7 = value;
   }
 
-  void set constructorDeclaration_name(LinkedNodeBuilder value) {
+  set constructorDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_7 = value;
   }
 
-  void set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
+  set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_7 = value;
   }
 
-  void set constructorName_type(LinkedNodeBuilder value) {
+  set constructorName_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     _variantField_7 = value;
   }
 
-  void set declaredIdentifier_type(LinkedNodeBuilder value) {
+  set declaredIdentifier_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     _variantField_7 = value;
   }
 
-  void set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
+  set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_7 = value;
   }
 
-  void set doStatement_condition(LinkedNodeBuilder value) {
+  set doStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     _variantField_7 = value;
   }
 
-  void set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
+  set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_7 = value;
   }
 
-  void set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
+  set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
     _variantField_7 = value;
   }
 
-  void set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
+  set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     _variantField_7 = value;
   }
 
-  void set forElement_body(LinkedNodeBuilder value) {
+  set forElement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forElement);
     _variantField_7 = value;
   }
 
-  void set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
+  set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
     _variantField_7 = value;
   }
 
-  void set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
+  set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
     _variantField_7 = value;
   }
 
-  void set forStatement_body(LinkedNodeBuilder value) {
+  set forStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forStatement);
     _variantField_7 = value;
   }
 
-  void set functionDeclaration_returnType(LinkedNodeBuilder value) {
+  set functionDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     _variantField_7 = value;
   }
 
-  void set functionExpression_formalParameters(LinkedNodeBuilder value) {
+  set functionExpression_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_7 = value;
   }
 
-  void set functionTypeAlias_returnType(LinkedNodeBuilder value) {
+  set functionTypeAlias_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_7 = value;
   }
 
-  void set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_7 = value;
   }
 
-  void set genericFunctionType_returnType(LinkedNodeBuilder value) {
+  set genericFunctionType_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_7 = value;
   }
 
-  void set genericTypeAlias_functionType(LinkedNodeBuilder value) {
+  set genericTypeAlias_functionType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     _variantField_7 = value;
   }
 
-  void set ifStatement_elseStatement(LinkedNodeBuilder value) {
+  set ifStatement_elseStatement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifStatement);
     _variantField_7 = value;
   }
 
-  void set indexExpression_target(LinkedNodeBuilder value) {
+  set indexExpression_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_7 = value;
   }
 
-  void set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
+  set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_7 = value;
   }
 
-  void set isExpression_type(LinkedNodeBuilder value) {
+  set isExpression_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     _variantField_7 = value;
   }
 
-  void set mapLiteralEntry_value(LinkedNodeBuilder value) {
+  set mapLiteralEntry_value(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     _variantField_7 = value;
   }
 
-  void set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
+  set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_7 = value;
   }
 
-  void set methodInvocation_target(LinkedNodeBuilder value) {
+  set methodInvocation_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_7 = value;
   }
 
-  void set namedExpression_name(LinkedNodeBuilder value) {
+  set namedExpression_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.namedExpression);
     _variantField_7 = value;
   }
 
-  void set partOfDirective_uri(LinkedNodeBuilder value) {
+  set partOfDirective_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     _variantField_7 = value;
   }
 
-  void set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
+  set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     _variantField_7 = value;
   }
 
-  void set propertyAccess_target(LinkedNodeBuilder value) {
+  set propertyAccess_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     _variantField_7 = value;
   }
 
-  void set redirectingConstructorInvocation_constructorName(
+  set redirectingConstructorInvocation_constructorName(
       LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     _variantField_7 = value;
   }
 
-  void set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
+  set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     _variantField_7 = value;
   }
 
-  void set switchStatement_expression(LinkedNodeBuilder value) {
+  set switchStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     _variantField_7 = value;
   }
 
-  void set tryStatement_finallyBlock(LinkedNodeBuilder value) {
+  set tryStatement_finallyBlock(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_7 = value;
   }
 
-  void set typeName_typeArguments(LinkedNodeBuilder value) {
+  set typeName_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     _variantField_7 = value;
   }
 
-  void set typeParameter_name(LinkedNodeBuilder value) {
+  set typeParameter_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     _variantField_7 = value;
   }
 
-  void set variableDeclaration_name(LinkedNodeBuilder value) {
+  set variableDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_7 = value;
   }
 
-  void set whileStatement_condition(LinkedNodeBuilder value) {
+  set whileStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_7 = value;
   }
@@ -7763,83 +7778,82 @@
     return _variantField_8;
   }
 
-  void set annotation_name(LinkedNodeBuilder value) {
+  set annotation_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_8 = value;
   }
 
-  void set catchClause_exceptionType(LinkedNodeBuilder value) {
+  set catchClause_exceptionType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_8 = value;
   }
 
-  void set classDeclaration_nativeClause(LinkedNodeBuilder value) {
+  set classDeclaration_nativeClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_8 = value;
   }
 
-  void set classTypeAlias_withClause(LinkedNodeBuilder value) {
+  set classTypeAlias_withClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_8 = value;
   }
 
-  void set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
+  set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_8 = value;
   }
 
-  void set configuration_uri(LinkedNodeBuilder value) {
+  set configuration_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_8 = value;
   }
 
-  void set constructorDeclaration_parameters(LinkedNodeBuilder value) {
+  set constructorDeclaration_parameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_8 = value;
   }
 
-  void set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
+  set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_8 = value;
   }
 
-  void set functionExpression_typeParameters(LinkedNodeBuilder value) {
+  set functionExpression_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_8 = value;
   }
 
-  void set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_8 = value;
   }
 
-  void set functionTypedFormalParameter_typeParameters(
-      LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_8 = value;
   }
 
-  void set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
+  set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_8 = value;
   }
 
-  void set ifElement_thenElement(LinkedNodeBuilder value) {
+  set ifElement_thenElement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifElement);
     _variantField_8 = value;
   }
 
-  void set ifStatement_thenStatement(LinkedNodeBuilder value) {
+  set ifStatement_thenStatement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifStatement);
     _variantField_8 = value;
   }
 
-  void set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
+  set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_8 = value;
   }
 
-  void set methodDeclaration_returnType(LinkedNodeBuilder value) {
+  set methodDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_8 = value;
   }
@@ -8178,335 +8192,335 @@
     return _variantField_16 ??= 0;
   }
 
-  void set annotation_period(int value) {
+  set annotation_period(int value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set argumentList_rightParenthesis(int value) {
+  set argumentList_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assertInitializer_comma(int value) {
+  set assertInitializer_comma(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assertStatement_comma(int value) {
+  set assertStatement_comma(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assignmentExpression_operator(int value) {
+  set assignmentExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set binaryExpression_operator(int value) {
+  set binaryExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set block_rightBracket(int value) {
+  set block_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.block);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set blockFunctionBody_star(int value) {
+  set blockFunctionBody_star(int value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set breakStatement_semicolon(int value) {
+  set breakStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set catchClause_comma(int value) {
+  set catchClause_comma(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set classDeclaration_classKeyword(int value) {
+  set classDeclaration_classKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set classTypeAlias_equals(int value) {
+  set classTypeAlias_equals(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set compilationUnit_endToken(int value) {
+  set compilationUnit_endToken(int value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set conditionalExpression_question(int value) {
+  set conditionalExpression_question(int value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set configuration_leftParenthesis(int value) {
+  set configuration_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorDeclaration_externalKeyword(int value) {
+  set constructorDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorFieldInitializer_period(int value) {
+  set constructorFieldInitializer_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorName_period(int value) {
+  set constructorName_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set continueStatement_semicolon(int value) {
+  set continueStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set doStatement_rightParenthesis(int value) {
+  set doStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set enumDeclaration_leftBracket(int value) {
+  set enumDeclaration_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set expressionFunctionBody_keyword(int value) {
+  set expressionFunctionBody_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set fieldDeclaration_semicolon(int value) {
+  set fieldDeclaration_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set fieldFormalParameter_period(int value) {
+  set fieldFormalParameter_period(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set formalParameterList_leftParenthesis(int value) {
+  set formalParameterList_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set forMixin_forKeyword(int value) {
+  set forMixin_forKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set forParts_rightSeparator(int value) {
+  set forParts_rightSeparator(int value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set functionDeclaration_propertyKeyword(int value) {
+  set functionDeclaration_propertyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set genericFunctionType_question(int value) {
+  set genericFunctionType_question(int value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set genericTypeAlias_equals(int value) {
+  set genericTypeAlias_equals(int value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set ifMixin_ifKeyword(int value) {
+  set ifMixin_ifKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set importDirective_deferredKeyword(int value) {
+  set importDirective_deferredKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set indexExpression_period(int value) {
+  set indexExpression_period(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set integerLiteral_value(int value) {
+  set integerLiteral_value(int value) {
     assert(kind == idl.LinkedNodeKind.integerLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set interpolationExpression_rightBracket(int value) {
+  set interpolationExpression_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set isExpression_notOperator(int value) {
+  set isExpression_notOperator(int value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set listLiteral_rightBracket(int value) {
+  set listLiteral_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set methodDeclaration_modifierKeyword(int value) {
+  set methodDeclaration_modifierKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set nativeFunctionBody_semicolon(int value) {
+  set nativeFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set parenthesizedExpression_rightParenthesis(int value) {
+  set parenthesizedExpression_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set partOfDirective_ofKeyword(int value) {
+  set partOfDirective_ofKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set postfixExpression_operator(int value) {
+  set postfixExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set prefixExpression_operator(int value) {
+  set prefixExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set redirectingConstructorInvocation_period(int value) {
+  set redirectingConstructorInvocation_period(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set returnStatement_semicolon(int value) {
+  set returnStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set setOrMapLiteral_rightBracket(int value) {
+  set setOrMapLiteral_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set simpleIdentifier_token(int value) {
+  set simpleIdentifier_token(int value) {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set superConstructorInvocation_period(int value) {
+  set superConstructorInvocation_period(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set switchMember_colon(int value) {
+  set switchMember_colon(int value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set switchStatement_rightParenthesis(int value) {
+  set switchStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set tryStatement_tryKeyword(int value) {
+  set tryStatement_tryKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set typeArgumentList_rightBracket(int value) {
+  set typeArgumentList_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set typeParameterList_rightBracket(int value) {
+  set typeParameterList_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set whileStatement_rightParenthesis(int value) {
+  set whileStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set yieldStatement_star(int value) {
+  set yieldStatement_star(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
@@ -8640,129 +8654,129 @@
     return _variantField_17 ??= 0;
   }
 
-  void set assertInitializer_leftParenthesis(int value) {
+  set assertInitializer_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set assertStatement_leftParenthesis(int value) {
+  set assertStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set catchClause_leftParenthesis(int value) {
+  set catchClause_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set configuration_rightParenthesis(int value) {
+  set configuration_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set constructorDeclaration_factoryKeyword(int value) {
+  set constructorDeclaration_factoryKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set constructorFieldInitializer_thisKeyword(int value) {
+  set constructorFieldInitializer_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set doStatement_doKeyword(int value) {
+  set doStatement_doKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set enumDeclaration_rightBracket(int value) {
+  set enumDeclaration_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set expressionFunctionBody_semicolon(int value) {
+  set expressionFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set fieldDeclaration_staticKeyword(int value) {
+  set fieldDeclaration_staticKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set fieldFormalParameter_thisKeyword(int value) {
+  set fieldFormalParameter_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set formalParameterList_rightDelimiter(int value) {
+  set formalParameterList_rightDelimiter(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set forMixin_leftParenthesis(int value) {
+  set forMixin_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set ifMixin_leftParenthesis(int value) {
+  set ifMixin_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set indexExpression_leftBracket(int value) {
+  set indexExpression_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set methodDeclaration_operatorKeyword(int value) {
+  set methodDeclaration_operatorKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set redirectingConstructorInvocation_thisKeyword(int value) {
+  set redirectingConstructorInvocation_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set superConstructorInvocation_superKeyword(int value) {
+  set superConstructorInvocation_superKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set switchStatement_switchKeyword(int value) {
+  set switchStatement_switchKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set whileStatement_whileKeyword(int value) {
+  set whileStatement_whileKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set yieldStatement_semicolon(int value) {
+  set yieldStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
@@ -8860,44 +8874,44 @@
     return _variantField_18 ??= 0;
   }
 
-  void set assertInitializer_rightParenthesis(int value) {
+  set assertInitializer_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set assertStatement_rightParenthesis(int value) {
+  set assertStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set catchClause_onKeyword(int value) {
+  set catchClause_onKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set classOrMixinDeclaration_rightBracket(int value) {
+  set classOrMixinDeclaration_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set configuration_equalToken(int value) {
+  set configuration_equalToken(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set constructorDeclaration_period(int value) {
+  set constructorDeclaration_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set directive_keyword(int value) {
+  set directive_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.libraryDirective ||
@@ -8907,44 +8921,44 @@
     _variantField_18 = value;
   }
 
-  void set doStatement_semicolon(int value) {
+  set doStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set formalParameterList_rightParenthesis(int value) {
+  set formalParameterList_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set ifMixin_rightParenthesis(int value) {
+  set ifMixin_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set indexExpression_rightBracket(int value) {
+  set indexExpression_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set methodDeclaration_propertyKeyword(int value) {
+  set methodDeclaration_propertyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set switchStatement_leftBracket(int value) {
+  set switchStatement_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set typeAlias_typedefKeyword(int value) {
+  set typeAlias_typedefKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9040,58 +9054,58 @@
     return _variantField_19 ??= 0;
   }
 
-  void set assertStatement_semicolon(int value) {
+  set assertStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set catchClause_rightParenthesis(int value) {
+  set catchClause_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set classOrMixinDeclaration_leftBracket(int value) {
+  set classOrMixinDeclaration_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set combinator_keyword(int value) {
+  set combinator_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.hideCombinator ||
         kind == idl.LinkedNodeKind.showCombinator);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set constructorDeclaration_separator(int value) {
+  set constructorDeclaration_separator(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set doStatement_whileKeyword(int value) {
+  set doStatement_whileKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set forMixin_rightParenthesis(int value) {
+  set forMixin_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set methodDeclaration_actualProperty(int value) {
+  set methodDeclaration_actualProperty(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set normalFormalParameter_covariantKeyword(int value) {
+  set normalFormalParameter_covariantKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
@@ -9099,13 +9113,13 @@
     _variantField_19 = value;
   }
 
-  void set switchStatement_rightBracket(int value) {
+  set switchStatement_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set typeAlias_semicolon(int value) {
+  set typeAlias_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9113,14 +9127,14 @@
     _variantField_19 = value;
   }
 
-  void set typedLiteral_constKeyword(int value) {
+  set typedLiteral_constKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set uriBasedDirective_uriElement(int value) {
+  set uriBasedDirective_uriElement(int value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.partDirective);
@@ -9129,131 +9143,6 @@
   }
 
   @override
-  LinkedNodeTypeBuilder get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get fieldFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionDeclaration_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionTypeAlias_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionTypedFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get genericFunctionType_returnType2 {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get invocationExpression_invokeType {
-    assert(kind == i