Version 2.13.0-76.0.dev

Merge commit '61007372457bd6a358bd02f0443100a0ba6dd56d' into 'dev'
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
index f63d1bd..f3873dc 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
@@ -32,9 +32,6 @@
   /// Initialize a newly created fix to have the given [kind] and [change].
   Fix(this.kind, this.change);
 
-  /// Returns `true` if this fix is the union of multiple fixes.
-  bool isFixAllFix() => change.message == kind.appliedTogetherMessage;
-
   @override
   String toString() {
     return 'Fix(kind=$kind, change=$change)';
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index aa7ec99..c0f9ae0 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -50,6 +50,7 @@
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
@@ -209,7 +210,7 @@
   /// Return the cached analysis result for the file with the given [path].
   /// If there is no cached result, return `null`.
   ResolvedUnitResult getCachedResolvedUnit(String path) {
-    if (!AnalysisEngine.isDartFileName(path)) {
+    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
       return null;
     }
 
@@ -583,7 +584,7 @@
       // The result will be produced by the "results" stream with
       // the fully resolved unit, and processed with sending analysis
       // notifications as it happens after content changes.
-      if (AnalysisEngine.isDartFileName(file)) {
+      if (file_paths.isDart(resourceProvider.pathContext, file)) {
         getResolvedUnit(file, sendCachedToStream: true);
       }
     }
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 0a38cf0..6ce204b 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -42,6 +42,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 
 /// Implementations of [AbstractAnalysisServer] implement a server that listens
 /// on a [CommunicationChannel] for analysis messages and process them.
@@ -311,7 +312,7 @@
 
   /// Return the unresolved unit for the file with the given [path].
   ParsedUnitResult getParsedUnit(String path) {
-    if (!AnalysisEngine.isDartFileName(path)) {
+    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
       return null;
     }
 
@@ -323,7 +324,7 @@
   /// otherwise in the first driver, otherwise `null` is returned.
   Future<ResolvedUnitResult> getResolvedUnit(String path,
       {bool sendCachedToStream = false}) {
-    if (!AnalysisEngine.isDartFileName(path)) {
+    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
       return null;
     }
 
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 9ff6e06..94f48ef 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -261,7 +261,7 @@
 
   /// Use the given analysis [driver] to analyze the content of the analysis
   /// options file at the given [path].
-  void _analyzeAnalysisOptionsFile(AnalysisDriver driver, String path) {
+  void _analyzeAnalysisOptionsYaml(AnalysisDriver driver, String path) {
     var convertedErrors = const <protocol.AnalysisError>[];
     try {
       var content = _readFile(path);
@@ -281,8 +281,29 @@
   }
 
   /// Use the given analysis [driver] to analyze the content of the
+  /// AndroidManifest file at the given [path].
+  void _analyzeAndroidManifestXml(AnalysisDriver driver, String path) {
+    var convertedErrors = const <protocol.AnalysisError>[];
+    try {
+      var content = _readFile(path);
+      var validator =
+          ManifestValidator(resourceProvider.getFile(path).createSource());
+      var lineInfo = _computeLineInfo(content);
+      var errors = validator.validate(
+          content, driver.analysisOptions.chromeOsManifestChecks);
+      var converter = 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.recordAnalysisErrors(path, convertedErrors);
+  }
+
+  /// Use the given analysis [driver] to analyze the content of the
   /// data file at the given [path].
-  void _analyzeDataFile(AnalysisDriver driver, String path) {
+  void _analyzeFixDataYaml(AnalysisDriver driver, String path) {
     var convertedErrors = const <protocol.AnalysisError>[];
     try {
       var file = resourceProvider.getFile(path);
@@ -302,30 +323,9 @@
     callbacks.recordAnalysisErrors(path, convertedErrors);
   }
 
-  /// Use the given analysis [driver] to analyze the content of the
-  /// AndroidManifest file at the given [path].
-  void _analyzeManifestFile(AnalysisDriver driver, String path) {
-    var convertedErrors = const <protocol.AnalysisError>[];
-    try {
-      var content = _readFile(path);
-      var validator =
-          ManifestValidator(resourceProvider.getFile(path).createSource());
-      var lineInfo = _computeLineInfo(content);
-      var errors = validator.validate(
-          content, driver.analysisOptions.chromeOsManifestChecks);
-      var converter = 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.recordAnalysisErrors(path, convertedErrors);
-  }
-
   /// Use the given analysis [driver] to analyze the content of the pubspec file
   /// at the given [path].
-  void _analyzePubspecFile(AnalysisDriver driver, String path) {
+  void _analyzePubspecYaml(AnalysisDriver driver, String path) {
     var convertedErrors = const <protocol.AnalysisError>[];
     try {
       var content = _readFile(path);
@@ -379,19 +379,19 @@
     callbacks.recordAnalysisErrors(path, convertedErrors);
   }
 
-  void _checkForDataFileUpdate(String path) {
-    if (file_paths.isFixDataYaml(pathContext, path)) {
-      var context = getContextFor(path);
-      var driver = context.driver;
-      _analyzeDataFile(driver, path);
-    }
-  }
-
-  void _checkForManifestUpdate(String path) {
+  void _checkForAndroidManifestXmlUpdate(String path) {
     if (file_paths.isAndroidManifestXml(pathContext, path)) {
       var context = getContextFor(path);
       var driver = context.driver;
-      _analyzeManifestFile(driver, path);
+      _analyzeAndroidManifestXml(driver, path);
+    }
+  }
+
+  void _checkForFixDataYamlUpdate(String path) {
+    if (file_paths.isFixDataYaml(pathContext, path)) {
+      var context = getContextFor(path);
+      var driver = context.driver;
+      _analyzeFixDataYaml(driver, path);
     }
   }
 
@@ -441,19 +441,19 @@
 
       var optionsFile = context.contextRoot.optionsFile;
       if (optionsFile != null) {
-        _analyzeAnalysisOptionsFile(driver, optionsFile.path);
+        _analyzeAnalysisOptionsYaml(driver, optionsFile.path);
       }
 
-      var dataFile = rootFolder
+      var fixDataYamlFile = rootFolder
           .getChildAssumingFolder('lib')
           .getChildAssumingFile(file_paths.fixDataYaml);
-      if (dataFile.exists) {
-        _analyzeDataFile(driver, dataFile.path);
+      if (fixDataYamlFile.exists) {
+        _analyzeFixDataYaml(driver, fixDataYamlFile.path);
       }
 
       var pubspecFile = rootFolder.getChildAssumingFile(file_paths.pubspecYaml);
       if (pubspecFile.exists) {
-        _analyzePubspecFile(driver, pubspecFile.path);
+        _analyzePubspecYaml(driver, pubspecFile.path);
       }
 
       void checkManifestFilesIn(Folder folder) {
@@ -466,7 +466,7 @@
           if (child is File) {
             if (file_paths.isAndroidManifestXml(pathContext, child.path) &&
                 !excludedPaths.contains(child.path)) {
-              _analyzeManifestFile(driver, child.path);
+              _analyzeAndroidManifestXml(driver, child.path);
             }
           } else if (child is Folder) {
             if (!excludedPaths.contains(child.path)) {
@@ -594,8 +594,8 @@
     switch (type) {
       case ChangeType.ADD:
       case ChangeType.MODIFY:
-        _checkForManifestUpdate(path);
-        _checkForDataFileUpdate(path);
+        _checkForAndroidManifestXmlUpdate(path);
+        _checkForFixDataYamlUpdate(path);
         break;
       case ChangeType.REMOVE:
         callbacks.applyFileRemoved(path);
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index dc88ddf..a2849de 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -46,8 +46,6 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
 import 'package:analyzer/src/exception/exception.dart';
-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/manifest/manifest_validator.dart';
@@ -498,7 +496,9 @@
     if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
-    if (!engine.AnalysisEngine.isDartFileName(file)) {
+
+    var pathContext = server.resourceProvider.pathContext;
+    if (!file_paths.isDart(pathContext, file)) {
       server.sendResponse(Response.fileNotAnalyzed(request, file));
       return;
     }
@@ -535,7 +535,9 @@
     if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
-    if (!engine.AnalysisEngine.isDartFileName(file)) {
+
+    var pathContext = server.resourceProvider.pathContext;
+    if (!file_paths.isDart(pathContext, file)) {
       server.sendResponse(Response.sortMembersInvalidFile(request));
       return;
     }
@@ -782,13 +784,13 @@
   Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
       Request request, String file, int offset) async {
     var pathContext = server.resourceProvider.pathContext;
-    if (AnalysisEngine.isDartFileName(file)) {
+    if (file_paths.isDart(pathContext, file)) {
       return _computeDartFixes(request, file, offset);
     } else if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
       return _computeAnalysisOptionsFixes(file, offset);
     } else if (file_paths.isPubspecYaml(pathContext, file)) {
       return _computePubspecFixes(file, offset);
-    } else if (pathContext.basename(file) == 'manifest.xml') {
+    } else if (file_paths.isAndroidManifestXml(pathContext, file)) {
       // TODO(brianwilkerson) Do we need to check more than the file name?
       return _computeManifestFixes(file, offset);
     }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 24a0131..f291e25 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -24,7 +24,7 @@
 import 'package:analyzer/dart/analysis/session.dart'
     show InconsistentAnalysisException;
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:collection/collection.dart' show groupBy;
 
 class CodeActionHandler extends MessageHandler<CodeActionParams,
@@ -354,7 +354,8 @@
     ResolvedUnitResult unit,
   ) async {
     // The refactor actions supported are only valid for Dart files.
-    if (!AnalysisEngine.isDartFileName(path)) {
+    var pathContext = server.resourceProvider.pathContext;
+    if (!file_paths.isDart(pathContext, path)) {
       return const [];
     }
 
@@ -429,7 +430,8 @@
     String path,
   ) async {
     // The source actions supported are only valid for Dart files.
-    if (!AnalysisEngine.isDartFileName(path)) {
+    var pathContext = server.resourceProvider.pathContext;
+    if (!file_paths.isDart(pathContext, path)) {
       return const [];
     }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 373bcee..580160f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -39,8 +39,8 @@
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -96,7 +96,8 @@
     bool enableUriContributor = true,
   }) async {
     request.checkAborted();
-    if (!AnalysisEngine.isDartFileName(request.result.path)) {
+    var pathContext = request.resourceProvider.pathContext;
+    if (!file_paths.isDart(pathContext, request.result.path)) {
       return const <CompletionSuggestion>[];
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index f020e2a..7f4ab1f 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -23,9 +23,9 @@
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -176,8 +176,9 @@
   /// diagnostics in the libraries in the given [contexts].
   Future<ChangeBuilder> fixErrors(List<AnalysisContext> contexts) async {
     for (var context in contexts) {
+      var pathContext = context.contextRoot.resourceProvider.pathContext;
       for (var path in context.contextRoot.analyzedFiles()) {
-        if (!AnalysisEngine.isDartFileName(path)) {
+        if (!file_paths.isDart(pathContext, path)) {
           continue;
         }
         var kind = await context.currentSession.getSourceKind(path);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 559d342..b7e0c1c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -307,6 +307,15 @@
   /// Return the fix kind that should be used to build a fix, or `null` if this
   /// producer doesn't support fixes.
   FixKind get fixKind => null;
+
+  /// Return the arguments that should be used when composing the message for a
+  /// multi-fix, or `null` if the fix message has no parameters or if this
+  /// producer doesn't support multi-fixes.
+  List<Object> get multiFixArguments => null;
+
+  /// Return the fix kind that should be used to build a multi-fix, or `null` if
+  /// this producer doesn't support multi-fixes.
+  FixKind get multiFixKind => null;
 }
 
 /// The behavior shared by [CorrectionProducer] and [MultiCorrectionProducer].
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
index 3089665..6e72eae 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_await.dart
@@ -12,6 +12,9 @@
   FixKind get fixKind => DartFixKind.ADD_AWAIT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_AWAIT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(node.offset, 'await ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart
index 170cdef..c0e5abe 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_const.dart
@@ -13,6 +13,9 @@
   FixKind get fixKind => DartFixKind.ADD_CONST;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_CONST_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is SimpleIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
index ec78b1d..283dfb0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart
@@ -22,6 +22,10 @@
   FixKind get fixKind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
 
   @override
+  FixKind get multiFixKind =>
+      DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     final node = this.node;
     if (node is! SimpleIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart
index 8dfac60..92958f1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_override.dart
@@ -16,6 +16,9 @@
   FixKind get fixKind => DartFixKind.ADD_OVERRIDE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_OVERRIDE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var member = node.thisOrAncestorOfType<ClassMember>();
     if (member == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart
index ed474b4..0a5d869 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required.dart
@@ -12,6 +12,9 @@
   FixKind get fixKind => DartFixKind.ADD_REQUIRED;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_REQUIRED_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleInsertion(node.parent.offset, '@required ');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
index 98e2195..e2912b0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_type_annotation.dart
@@ -22,6 +22,9 @@
   FixKind get fixKind => DartFixKind.ADD_TYPE_ANNOTATION;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_TYPE_ANNOTATION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is SimpleIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
index d4269d4..181ec8f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_add_all_to_spread.dart
@@ -37,6 +37,11 @@
       : DartFixKind.CONVERT_TO_SPREAD;
 
   @override
+  FixKind get multiFixKind => _isInlineInvocation
+      ? DartFixKind.INLINE_INVOCATION_MULTI
+      : DartFixKind.CONVERT_TO_SPREAD_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
index 6fc0b90..5f8cc29 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_conditional_expression_to_if_element.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_IF_ELEMENT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_IF_ELEMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
     if (node == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
index d2c7fd5..f82eeca 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_documentation_into_line.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_LINE_COMMENT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_LINE_COMMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var comment = node.thisOrAncestorOfType<Comment>();
     if (comment == null ||
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
index fd31707..517a309 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -21,6 +21,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_FOR_ELEMENT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_FOR_ELEMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Ensure that the selection is inside an invocation of Map.fromIterable.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
index 00bed8c..0a90211 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_quotes.dart
@@ -95,6 +95,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_SINGLE_QUOTED_STRING_MULTI;
+
+  @override
   bool get _fromDouble => true;
 
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
index b4699fe..1da824e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_CONTAINS;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_CONTAINS_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var comparison = node.thisOrAncestorOfType<BinaryExpression>();
     if (comparison == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
index 767c412..138adcc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_INTO_EXPRESSION_BODY;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_INTO_EXPRESSION_BODY_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     // prepare current body
     var body = getEnclosingFunctionBody();
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
index ed860a2..c101539 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -20,6 +20,10 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX;
 
   @override
+  FixKind get multiFixKind =>
+      DartFixKind.CONVERT_TO_GENERIC_FUNCTION_SYNTAX_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     while (node != null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
index 55986c9..d8ca1d2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_IF_NULL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_IF_NULL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is ConditionalExpression &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
index 7682a76..6ccea99 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_INT_LITERAL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_INT_LITERAL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is! DoubleLiteral) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
index acd756c..0f915cd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_LIST_LITERAL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_LIST_LITERAL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Ensure that this is the default constructor defined on `List`.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
index 5db3377..e1c555a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_MAP_LITERAL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_MAP_LITERAL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Ensure that this is the default constructor defined on either `Map` or
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index feb830d..3a92192 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -21,6 +21,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_NULL_AWARE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node.parent is BinaryExpression &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
index 28bbe9e..08e3f39 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_PACKAGE_IMPORT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_PACKAGE_IMPORT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is StringLiteral) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
index d927238..ee82eb3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_RELATIVE_IMPORT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_RELATIVE_IMPORT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is StringLiteral) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
index f6a8db3..4fcf3c9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_SET_LITERAL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_SET_LITERAL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Check whether this is an invocation of `toSet` on a list literal.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
index 2753a81..5fe1a84 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.CONVERT_TO_WHERE_TYPE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CONVERT_TO_WHERE_TYPE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart
index e4d15a2..e64471b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_file.dart
@@ -5,7 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
@@ -29,8 +29,9 @@
         var source = parent.uriSource;
         if (source != null) {
           var fullName = source.fullName;
-          if (resourceProvider.pathContext.isAbsolute(fullName) &&
-              AnalysisEngine.isDartFileName(fullName)) {
+          var pathContext = resourceProvider.pathContext;
+          if (pathContext.isAbsolute(fullName) &&
+              file_paths.isDart(pathContext, fullName)) {
             await builder.addDartFileEdit(fullName, (builder) {
               builder.addSimpleInsertion(0, '// TODO Implement this library.');
             });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
index dd39818..9ded1dc 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
@@ -27,6 +27,9 @@
   FixKind get fixKind => DartFixKind.CREATE_METHOD;
 
   @override
+  FixKind get multiFixKind => DartFixKind.CREATE_METHOD_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (_kind == _MethodKind.equalsOrHashCode) {
       await createEqualsOrHashCode(builder);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
index 7e57e93..de2dac5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_invocation.dart
@@ -25,6 +25,9 @@
   FixKind get fixKind => DartFixKind.INLINE_INVOCATION;
 
   @override
+  FixKind get multiFixKind => DartFixKind.INLINE_INVOCATION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
index b310414..6cc3abd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/inline_typedef.dart
@@ -21,6 +21,9 @@
   FixKind get fixKind => DartFixKind.INLINE_TYPEDEF;
 
   @override
+  FixKind get multiFixKind => DartFixKind.INLINE_TYPEDEF_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Extract the information needed to build the edit.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
index 6db5457..3ae0f99a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_final.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.MAKE_FINAL;
 
   @override
+  FixKind get multiFixKind => DartFixKind.MAKE_FINAL_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is SimpleIdentifier &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
index 807a069..e864bb9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_argument.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_ARGUMENT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_ARGUMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var arg = node;
     if (arg.parent is NamedExpression) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
index 1ba9eed..b5671b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_await.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_AWAIT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_AWAIT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     final awaitExpression = node;
     if (awaitExpression is AwaitExpression) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
index b51dcef..485e7da 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
@@ -23,6 +23,9 @@
   @override
   FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_CONST;
 
+  @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_UNNECESSARY_CONST_MULTI;
+
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
   static RemoveUnnecessaryConst newInstance() => RemoveUnnecessaryConst();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
index 3ef7bda..88e3bfd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_DUPLICATE_CASE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_DUPLICATE_CASE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = coveredNode;
     if (node is SwitchCase) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
index 5118cc8..c2ac9e5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_catch.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_EMPTY_CATCH;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_EMPTY_CATCH_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node.parent is! CatchClause) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
index b07fa5c..07e6a47 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_constructor_body.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       if (node is Block && node.parent is BlockFunctionBody) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
index d3acc75..3c07e57 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_else.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_EMPTY_ELSE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_EMPTY_ELSE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var parent = node.parent;
     if (parent is IfStatement) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
index 321f447..e45057a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_empty_statement.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_EMPTY_STATEMENT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_EMPTY_STATEMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is EmptyStatement && node.parent is Block) {
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
index ebf5ded..5d75e08 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_if_null_operator.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_IF_NULL_OPERATOR;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_IF_NULL_OPERATOR_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var expression = node.thisOrAncestorOfType<BinaryExpression>();
     if (expression == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
index 142a418..a927201 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_initializer.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_INITIALIZER;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_INITIALIZER_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var parameter = node.thisOrAncestorOfType<DefaultFormalParameter>();
     if (parameter != null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
index 0364c14..03ceb42 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_interpolation_braces.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_INTERPOLATION_BRACES;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_INTERPOLATION_BRACES_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is InterpolationExpression) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
index c4e3c2d..db3ac40 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_method_declaration.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_METHOD_DECLARATION;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_METHOD_DECLARATION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var declaration = node.thisOrAncestorOfType<MethodDeclaration>();
     if (declaration != null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
index 5d0053a..1b44daf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_operator.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_OPERATOR;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_OPERATOR_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is BinaryExpression) {
       var expression = node as BinaryExpression;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
index af0f47b..378c883 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_QUESTION_MARK;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_QUESTION_MARK_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is VariableDeclaration) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
index 4ce4ad0..0f41278 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_this_expression.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_THIS_EXPRESSION;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_THIS_EXPRESSION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is ConstructorFieldInitializer) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index cd84ee6..e58c795 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_TYPE_ANNOTATION;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_TYPE_ANNOTATION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     for (var node = this.node; node != null; node = node.parent) {
       if (node is DeclaredIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
index a2654d3..a613dfd 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_new.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_NEW;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_UNNECESSARY_NEW_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     final instanceCreationExpression = node;
     if (instanceCreationExpression is InstanceCreationExpression) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
index b3d860c..7baa9e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_PARENTHESES;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REMOVE_UNNECESSARY_PARENTHESES_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var outer = coveredNode;
     if (outer is ParenthesizedExpression &&
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart
index 31692a1..6651bf4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_string_interpolation.dart
@@ -15,6 +15,10 @@
   FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_STRING_INTERPOLATION;
 
   @override
+  FixKind get multiFixKind =>
+      DartFixKind.REMOVE_UNNECESSARY_STRING_INTERPOLATION_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     final interpolation = node;
     if (interpolation is StringInterpolation) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
index acb1201..4130747 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/rename_to_camel_case.dart
@@ -23,6 +23,9 @@
   FixKind get fixKind => DartFixKind.RENAME_TO_CAMEL_CASE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.RENAME_TO_CAMEL_CASE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is! SimpleIdentifier) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
index 8e9ede9..eba59da 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
@@ -25,6 +25,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_CASCADE_WITH_DOT;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_CASCADE_WITH_DOT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is CascadeExpression) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
index 92076a5..70f6134 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_colon_with_equals.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_COLON_WITH_EQUALS;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_COLON_WITH_EQUALS_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is DefaultFormalParameter) {
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
index 3204819..c644020 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_FINAL_WITH_CONST;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_FINAL_WITH_CONST_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is VariableDeclarationList) {
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart
index 56bb894..85c1ae0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_new_with_const.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_NEW_WITH_CONST;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_NEW_WITH_CONST_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is ConstructorName) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
index 2bafcfb..0744780 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_with_closure.dart
@@ -16,6 +16,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_NULL_WITH_CLOSURE;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_NULL_WITH_CLOSURE_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     AstNode nodeToFix;
     var parameters = const <ParameterElement>[];
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
index 0b7daad..eb4fc02 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_brackets.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_BRACKETS;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_BRACKETS_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is EmptyStatement && node.parent is! Block) {
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
index 83ff3ba..0d81cddf 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_conditional_assignment.dart
@@ -14,6 +14,10 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT;
 
   @override
+  FixKind get multiFixKind =>
+      DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     IfStatement ifStatement =
         node is IfStatement ? node : node.thisOrAncestorOfType<IfStatement>();
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
index 863bc23..65db348 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_eight_digit_hex.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_EIGHT_DIGIT_HEX;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_EIGHT_DIGIT_HEX_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     //
     // Extract the information needed to build the edit.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
index bacc3b3..9b30817 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_identifier.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_IDENTIFIER;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_IDENTIFIER_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var functionTyped =
         node.thisOrAncestorOfType<FunctionTypedFormalParameter>();
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
index 5abb0e9..4238767 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_is_empty.dart
@@ -15,6 +15,9 @@
   FixKind fixKind;
 
   @override
+  FixKind multiFixKind;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     /// Return the value of an integer literal or prefix expression with a
     /// minus and then an integer literal. For anything else, returns `null`.
@@ -56,9 +59,11 @@
         if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
           getter = 'isEmpty';
           fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
         } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
           getter = 'isNotEmpty';
           fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
         }
       } else if (rightValue == 1) {
         // 'length >= 1' is same as 'isNotEmpty',
@@ -66,9 +71,11 @@
         if (operator == TokenType.GT_EQ) {
           getter = 'isNotEmpty';
           fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
         } else if (operator == TokenType.LT) {
           getter = 'isEmpty';
           fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
         }
       }
     } else {
@@ -79,10 +86,12 @@
           if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
             getter = 'isEmpty';
             fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+            multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
           } else if (operator == TokenType.LT ||
               operator == TokenType.BANG_EQ) {
             getter = 'isNotEmpty';
             fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+            multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
           }
         } else if (leftValue == 1) {
           // '1 <= length' is same as 'isNotEmpty',
@@ -90,9 +99,11 @@
           if (operator == TokenType.LT_EQ) {
             getter = 'isNotEmpty';
             fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+            multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
           } else if (operator == TokenType.GT) {
             getter = 'isEmpty';
             fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+            multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
           }
         }
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
index d638789..6d6434f 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_tear_off.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_TEAR_OFF;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_TEAR_OFF_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var ancestor = node.thisOrAncestorOfType<FunctionExpression>();
     if (ancestor == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
index 8ac0b18..64a2f1d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_var.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.REPLACE_WITH_VAR;
 
   @override
+  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_VAR_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var type = _findType(node);
     if (type == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
index bbf8d3b..4475559 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/sort_child_property_last.dart
@@ -20,6 +20,9 @@
   FixKind get fixKind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
 
   @override
+  FixKind get multiFixKind => DartFixKind.SORT_CHILD_PROPERTY_LAST_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var childProp = _findNamedExpression(node);
     if (childProp == null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
index e6fead3..fc35192 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_curly_braces.dart
@@ -19,6 +19,9 @@
   FixKind get fixKind => DartFixKind.ADD_CURLY_BRACES;
 
   @override
+  FixKind get multiFixKind => DartFixKind.ADD_CURLY_BRACES_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     var statement = node.thisOrAncestorOfType<Statement>();
     var parent = statement?.parent;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
index cc06b0d..665dc9c 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_is_not_empty.dart
@@ -15,6 +15,9 @@
   FixKind get fixKind => DartFixKind.USE_IS_NOT_EMPTY;
 
   @override
+  FixKind get multiFixKind => DartFixKind.USE_IS_NOT_EMPTY_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (node is! PrefixExpression) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
index 2afd4ed..8c31100 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_rethrow.dart
@@ -14,6 +14,9 @@
   FixKind get fixKind => DartFixKind.USE_RETHROW;
 
   @override
+  FixKind get multiFixKind => DartFixKind.USE_RETHROW_MULTI;
+
+  @override
   Future<void> compute(ChangeBuilder builder) async {
     if (coveredNode is ThrowExpression) {
       await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 6528ff6..4138e15 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -145,24 +145,30 @@
 class DartFixKind {
   static const ADD_ASYNC =
       FixKind('dart.fix.add.async', 50, "Add 'async' modifier");
-  static const ADD_AWAIT = FixKind(
-      'dart.fix.add.await', 50, "Add 'await' keyword",
-      appliedTogetherMessage: "Add 'await's everywhere in file");
-  static const ADD_EXPLICIT_CAST = FixKind(
-      'dart.fix.add.explicitCast', 50, 'Add cast',
-      appliedTogetherMessage: 'Add all casts in file');
-  static const ADD_CONST = FixKind(
-      'dart.fix.add.const', 50, "Add 'const' modifier",
-      appliedTogetherMessage: "Add 'const' modifiers everywhere in file");
-  static const ADD_CURLY_BRACES = FixKind(
-      'dart.fix.add.curlyBraces', 50, 'Add curly braces',
-      appliedTogetherMessage: 'Add curly braces everywhere in file');
+  static const ADD_AWAIT =
+      FixKind('dart.fix.add.await', 50, "Add 'await' keyword");
+  static const ADD_AWAIT_MULTI = FixKind('dart.fix.add.await.multi',
+      DartFixKindPriority.IN_FILE, "Add 'await's everywhere in file");
+  static const ADD_EXPLICIT_CAST =
+      FixKind('dart.fix.add.explicitCast', 50, 'Add cast');
+  static const ADD_CONST =
+      FixKind('dart.fix.add.const', 50, "Add 'const' modifier");
+  static const ADD_CONST_MULTI = FixKind('dart.fix.add.const.multi',
+      DartFixKindPriority.IN_FILE, "Add 'const' modifiers everywhere in file");
+  static const ADD_CURLY_BRACES =
+      FixKind('dart.fix.add.curlyBraces', 50, 'Add curly braces');
+  static const ADD_CURLY_BRACES_MULTI = FixKind(
+      'dart.fix.add.curlyBraces.multi',
+      DartFixKindPriority.IN_FILE,
+      'Add curly braces everywhere in file');
   static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = FixKind(
       'dart.fix.add.diagnosticPropertyReference',
       50,
-      'Add a debug reference to this property',
-      appliedTogetherMessage:
-          'Add missing debug property references everywhere in file');
+      'Add a debug reference to this property');
+  static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE_MULTI = FixKind(
+      'dart.fix.add.diagnosticPropertyReference.multi',
+      DartFixKindPriority.IN_FILE,
+      'Add missing debug property references everywhere in file');
   static const ADD_FIELD_FORMAL_PARAMETERS = FixKind(
       'dart.fix.add.fieldFormalParameters',
       70,
@@ -185,31 +191,45 @@
       'dart.fix.add.missingRequiredArgument',
       70,
       "Add required argument '{0}'");
-  static const ADD_NE_NULL = FixKind('dart.fix.add.neNull', 50, 'Add != null',
-      appliedTogetherMessage: 'Add != null everywhere in file');
+  static const ADD_NE_NULL = FixKind('dart.fix.add.neNull', 50, 'Add != null');
+  static const ADD_NE_NULL_MULTI = FixKind('dart.fix.add.neNull.multi',
+      DartFixKindPriority.IN_FILE, 'Add != null everywhere in file');
   static const ADD_NULL_CHECK =
       FixKind('dart.fix.add.nullCheck', 50, 'Add a null check (!)');
-  static const ADD_OVERRIDE = FixKind(
-      'dart.fix.add.override', 50, "Add '@override' annotation",
-      appliedTogetherMessage: "Add '@override' annotations everywhere in file");
-  static const ADD_REQUIRED = FixKind(
-      'dart.fix.add.required', 50, "Add '@required' annotation",
-      appliedTogetherMessage: "Add '@required' annotations everywhere in file");
-  static const ADD_REQUIRED2 = FixKind(
-      'dart.fix.add.required', 50, "Add 'required' keyword",
-      appliedTogetherMessage: "Add 'required' keywords everywhere in file");
-  static const ADD_RETURN_TYPE = FixKind(
-      'dart.fix.add.returnType', 50, 'Add return type',
-      appliedTogetherMessage: 'Add return types everywhere in file');
+  static const ADD_OVERRIDE =
+      FixKind('dart.fix.add.override', 50, "Add '@override' annotation");
+  static const ADD_OVERRIDE_MULTI = FixKind(
+      'dart.fix.add.override.multi',
+      DartFixKindPriority.IN_FILE,
+      "Add '@override' annotations everywhere in file");
+  static const ADD_REQUIRED =
+      FixKind('dart.fix.add.required', 50, "Add '@required' annotation");
+  static const ADD_REQUIRED_MULTI = FixKind(
+      'dart.fix.add.required.multi',
+      DartFixKindPriority.IN_FILE,
+      "Add '@required' annotations everywhere in file");
+  static const ADD_REQUIRED2 =
+      FixKind('dart.fix.add.required', 50, "Add 'required' keyword");
+  static const ADD_REQUIRED2_MULTI = FixKind(
+      'dart.fix.add.required.multi',
+      DartFixKindPriority.IN_FILE,
+      "Add 'required' keywords everywhere in file");
+  static const ADD_RETURN_TYPE =
+      FixKind('dart.fix.add.returnType', 50, 'Add return type');
+  static const ADD_RETURN_TYPE_MULTI = FixKind('dart.fix.add.returnType.multi',
+      DartFixKindPriority.IN_FILE, 'Add return types everywhere in file');
   static const ADD_STATIC =
       FixKind('dart.fix.add.static', 50, "Add 'static' modifier");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = FixKind(
       'dart.fix.add.superConstructorInvocation',
       50,
       'Add super constructor {0} invocation');
-  static const ADD_TYPE_ANNOTATION = FixKind(
-      'dart.fix.add.typeAnnotation', 50, 'Add type annotation',
-      appliedTogetherMessage: 'Add type annotations everywhere in file');
+  static const ADD_TYPE_ANNOTATION =
+      FixKind('dart.fix.add.typeAnnotation', 50, 'Add type annotation');
+  static const ADD_TYPE_ANNOTATION_MULTI = FixKind(
+      'dart.fix.add.typeAnnotation.multi',
+      DartFixKindPriority.IN_FILE,
+      'Add type annotations everywhere in file');
   static const CHANGE_ARGUMENT_NAME =
       FixKind('dart.fix.change.argumentName', 60, "Change to '{0}'");
   static const CHANGE_TO = FixKind('dart.fix.change.to', 51, "Change to '{0}'");
@@ -230,75 +250,123 @@
   static const CONVERT_FLUTTER_CHILDREN = FixKind(
       'dart.fix.flutter.convert.childrenToChild', 50, 'Convert to child:');
   static const CONVERT_INTO_EXPRESSION_BODY = FixKind(
-      'dart.fix.convert.toExpressionBody', 50, 'Convert to expression body',
-      appliedTogetherMessage:
-          'Convert to expression bodies everywhere in file');
-  static const CONVERT_TO_CONTAINS = FixKind(
-      'dart.fix.convert.toContains', 50, "Convert to using 'contains'",
-      appliedTogetherMessage: "Convert to using 'contains' everywhere in file");
+      'dart.fix.convert.toExpressionBody', 50, 'Convert to expression body');
+  static const CONVERT_INTO_EXPRESSION_BODY_MULTI = FixKind(
+      'dart.fix.convert.toExpressionBody.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to expression bodies everywhere in file');
+  static const CONVERT_TO_CONTAINS =
+      FixKind('dart.fix.convert.toContains', 50, "Convert to using 'contains'");
+  static const CONVERT_TO_CONTAINS_MULTI = FixKind(
+      'dart.fix.convert.toContains.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to using 'contains' everywhere in file");
   static const CONVERT_TO_FOR_ELEMENT = FixKind(
-      'dart.fix.convert.toForElement', 50, "Convert to a 'for' element",
-      appliedTogetherMessage: "Convert to 'for' elements everywhere in file");
+      'dart.fix.convert.toForElement', 50, "Convert to a 'for' element");
+  static const CONVERT_TO_FOR_ELEMENT_MULTI = FixKind(
+      'dart.fix.convert.toForElement.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to 'for' elements everywhere in file");
   static const CONVERT_TO_GENERIC_FUNCTION_SYNTAX = FixKind(
       'dart.fix.convert.toGenericFunctionSyntax',
       50,
-      "Convert into 'Function' syntax",
-      appliedTogetherMessage:
-          "Convert to 'Function' syntax everywhere in file");
-  static const CONVERT_TO_IF_ELEMENT = FixKind(
-      'dart.fix.convert.toIfElement', 50, "Convert to an 'if' element",
-      appliedTogetherMessage: "Convert to 'if' elements everywhere in file");
-  static const CONVERT_TO_IF_NULL = FixKind(
-      'dart.fix.convert.toIfNull', 50, "Convert to use '??'",
-      appliedTogetherMessage: "Convert to '??'s everywhere in file");
-  static const CONVERT_TO_INT_LITERAL = FixKind(
-      'dart.fix.convert.toIntLiteral', 50, 'Convert to an int literal',
-      appliedTogetherMessage: 'Convert to int literals everywhere in file');
+      "Convert into 'Function' syntax");
+  static const CONVERT_TO_GENERIC_FUNCTION_SYNTAX_MULTI = FixKind(
+      'dart.fix.convert.toGenericFunctionSyntax.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to 'Function' syntax everywhere in file");
+  static const CONVERT_TO_IF_ELEMENT =
+      FixKind('dart.fix.convert.toIfElement', 50, "Convert to an 'if' element");
+  static const CONVERT_TO_IF_ELEMENT_MULTI = FixKind(
+      'dart.fix.convert.toIfElement.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to 'if' elements everywhere in file");
+  static const CONVERT_TO_IF_NULL =
+      FixKind('dart.fix.convert.toIfNull', 50, "Convert to use '??'");
+  static const CONVERT_TO_IF_NULL_MULTI = FixKind(
+      'dart.fix.convert.toIfNull.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to '??'s everywhere in file");
+  static const CONVERT_TO_INT_LITERAL =
+      FixKind('dart.fix.convert.toIntLiteral', 50, 'Convert to an int literal');
+  static const CONVERT_TO_INT_LITERAL_MULTI = FixKind(
+      'dart.fix.convert.toIntLiteral.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to int literals everywhere in file');
   static const CONVERT_TO_LINE_COMMENT = FixKind(
       'dart.fix.convert.toLineComment',
       50,
-      'Convert to line documentation comment',
-      appliedTogetherMessage:
-          'Convert to line documentation comments everywhere in file');
-  static const CONVERT_TO_LIST_LITERAL = FixKind(
-      'dart.fix.convert.toListLiteral', 50, 'Convert to list literal',
-      appliedTogetherMessage: 'Convert to list literals everywhere in file');
-  static const CONVERT_TO_MAP_LITERAL = FixKind(
-      'dart.fix.convert.toMapLiteral', 50, 'Convert to map literal',
-      appliedTogetherMessage: 'Convert to map literals everywhere in file');
+      'Convert to line documentation comment');
+  static const CONVERT_TO_LINE_COMMENT_MULTI = FixKind(
+      'dart.fix.convert.toLineComment.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to line documentation comments everywhere in file');
+  static const CONVERT_TO_LIST_LITERAL =
+      FixKind('dart.fix.convert.toListLiteral', 50, 'Convert to list literal');
+  static const CONVERT_TO_LIST_LITERAL_MULTI = FixKind(
+      'dart.fix.convert.toListLiteral.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to list literals everywhere in file');
+  static const CONVERT_TO_MAP_LITERAL =
+      FixKind('dart.fix.convert.toMapLiteral', 50, 'Convert to map literal');
+  static const CONVERT_TO_MAP_LITERAL_MULTI = FixKind(
+      'dart.fix.convert.toMapLiteral.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to map literals everywhere in file');
   static const CONVERT_TO_NAMED_ARGUMENTS = FixKind(
       'dart.fix.convert.toNamedArguments', 50, 'Convert to named arguments');
-  static const CONVERT_TO_NULL_AWARE = FixKind(
-      'dart.fix.convert.toNullAware', 50, "Convert to use '?.'",
-      appliedTogetherMessage: "Convert to use '?.' everywhere in file");
+  static const CONVERT_TO_NULL_AWARE =
+      FixKind('dart.fix.convert.toNullAware', 50, "Convert to use '?.'");
+  static const CONVERT_TO_NULL_AWARE_MULTI = FixKind(
+      'dart.fix.convert.toNullAware.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to use '?.' everywhere in file");
   static const CONVERT_TO_NULL_AWARE_SPREAD = FixKind(
-      'dart.fix.convert.toNullAwareSpread', 50, "Convert to use '...?'",
-      appliedTogetherMessage: "Convert to use '...?' everywhere in file");
+      'dart.fix.convert.toNullAwareSpread', 50, "Convert to use '...?'");
+  static const CONVERT_TO_NULL_AWARE_SPREAD_MULTI = FixKind(
+      'dart.fix.convert.toNullAwareSpread.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to use '...?' everywhere in file");
   static const CONVERT_TO_ON_TYPE =
       FixKind('dart.fix.convert.toOnType', 50, "Convert to 'on {0}'");
   static const CONVERT_TO_PACKAGE_IMPORT = FixKind(
-      'dart.fix.convert.toPackageImport', 50, "Convert to 'package:' import",
-      appliedTogetherMessage:
-          "Convert to 'package:' imports everywhere in file");
+      'dart.fix.convert.toPackageImport', 50, "Convert to 'package:' import");
+  static const CONVERT_TO_PACKAGE_IMPORT_MULTI = FixKind(
+      'dart.fix.convert.toPackageImport.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to 'package:' imports everywhere in file");
   static const CONVERT_TO_RELATIVE_IMPORT = FixKind(
-      'dart.fix.convert.toRelativeImport', 50, 'Convert to relative import',
-      appliedTogetherMessage: 'Convert to relative imports everywhere in file');
-  static const CONVERT_TO_SET_LITERAL = FixKind(
-      'dart.fix.convert.toSetLiteral', 50, 'Convert to set literal',
-      appliedTogetherMessage: 'Convert to set literals everywhere in file');
+      'dart.fix.convert.toRelativeImport', 50, 'Convert to relative import');
+  static const CONVERT_TO_RELATIVE_IMPORT_MULTI = FixKind(
+      'dart.fix.convert.toRelativeImport.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to relative imports everywhere in file');
+  static const CONVERT_TO_SET_LITERAL =
+      FixKind('dart.fix.convert.toSetLiteral', 50, 'Convert to set literal');
+  static const CONVERT_TO_SET_LITERAL_MULTI = FixKind(
+      'dart.fix.convert.toSetLiteral.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to set literals everywhere in file');
   static const CONVERT_TO_SINGLE_QUOTED_STRING = FixKind(
       'dart.fix.convert.toSingleQuotedString',
       50,
-      'Convert to single quoted string',
-      appliedTogetherMessage:
-          'Convert to single quoted strings everywhere in file');
-  static const CONVERT_TO_SPREAD = FixKind(
-      'dart.fix.convert.toSpread', 50, 'Convert to a spread',
-      appliedTogetherMessage: 'Convert to spreads everywhere in file');
-  static const CONVERT_TO_WHERE_TYPE = FixKind(
-      'dart.fix.convert.toWhereType', 50, "Convert to use 'whereType'",
-      appliedTogetherMessage:
-          "Convert to using 'whereType' everywhere in file");
+      'Convert to single quoted string');
+  static const CONVERT_TO_SINGLE_QUOTED_STRING_MULTI = FixKind(
+      'dart.fix.convert.toSingleQuotedString.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to single quoted strings everywhere in file');
+  static const CONVERT_TO_SPREAD =
+      FixKind('dart.fix.convert.toSpread', 50, 'Convert to a spread');
+  static const CONVERT_TO_SPREAD_MULTI = FixKind(
+      'dart.fix.convert.toSpread.multi',
+      DartFixKindPriority.IN_FILE,
+      'Convert to spreads everywhere in file');
+  static const CONVERT_TO_WHERE_TYPE =
+      FixKind('dart.fix.convert.toWhereType', 50, "Convert to use 'whereType'");
+  static const CONVERT_TO_WHERE_TYPE_MULTI = FixKind(
+      'dart.fix.convert.toWhereType.multi',
+      DartFixKindPriority.IN_FILE,
+      "Convert to using 'whereType' everywhere in file");
   static const CREATE_CLASS =
       FixKind('dart.fix.create.class', 50, "Create class '{0}'");
   static const CREATE_CONSTRUCTOR =
@@ -320,9 +388,10 @@
   static const CREATE_LOCAL_VARIABLE = FixKind(
       'dart.fix.create.localVariable', 50, "Create local variable '{0}'");
   static const CREATE_METHOD =
-      FixKind('dart.fix.create.method', 50, "Create method '{0}'",
-          // todo (pq): used by LintNames.hash_and_equals; consider removing.
-          appliedTogetherMessage: 'Create methods in file');
+      FixKind('dart.fix.create.method', 50, "Create method '{0}'");
+  // todo (pq): used by LintNames.hash_and_equals; consider removing.
+  static const CREATE_METHOD_MULTI = FixKind('dart.fix.create.method.multi',
+      DartFixKindPriority.IN_FILE, 'Create methods in file');
   static const CREATE_MISSING_OVERRIDES = FixKind(
       'dart.fix.create.missingOverrides', 51, 'Create {0} missing override(s)');
   static const CREATE_MIXIN =
@@ -348,21 +417,28 @@
       FixKind('dart.fix.import.librarySdk', 54, "Import library '{0}'");
   static const IMPORT_LIBRARY_SHOW =
       FixKind('dart.fix.import.libraryShow', 55, "Update library '{0}' import");
-  static const INLINE_INVOCATION = FixKind(
-      'dart.fix.inlineInvocation', 30, "Inline invocation of '{0}'",
-      appliedTogetherMessage: 'Inline invocations everywhere in file');
-  static const INLINE_TYPEDEF = FixKind(
-      'dart.fix.inlineTypedef', 30, "Inline the definition of '{0}'",
-      appliedTogetherMessage: 'Inline type definitions everywhere in file');
+  static const INLINE_INVOCATION =
+      FixKind('dart.fix.inlineInvocation', 30, "Inline invocation of '{0}'");
+  static const INLINE_INVOCATION_MULTI = FixKind(
+      'dart.fix.inlineInvocation.multi',
+      DartFixKindPriority.IN_FILE - 20,
+      'Inline invocations everywhere in file');
+  static const INLINE_TYPEDEF =
+      FixKind('dart.fix.inlineTypedef', 30, "Inline the definition of '{0}'");
+  static const INLINE_TYPEDEF_MULTI = FixKind(
+      'dart.fix.inlineTypedef.multi',
+      DartFixKindPriority.IN_FILE - 20,
+      'Inline type definitions everywhere in file');
   static const INSERT_SEMICOLON =
       FixKind('dart.fix.insertSemicolon', 50, "Insert ';'");
   static const MAKE_CLASS_ABSTRACT =
       FixKind('dart.fix.makeClassAbstract', 50, "Make class '{0}' abstract");
   static const MAKE_FIELD_NOT_FINAL =
       FixKind('dart.fix.makeFieldNotFinal', 50, "Make field '{0}' not final");
-  static const MAKE_FINAL = FixKind('dart.fix.makeFinal', 50, 'Make final',
-      // todo (pq): consider parameterizing: 'Make {fields} final...'
-      appliedTogetherMessage: 'Make final where possible in file');
+  static const MAKE_FINAL = FixKind('dart.fix.makeFinal', 50, 'Make final');
+  // todo (pq): consider parameterizing: 'Make {fields} final...'
+  static const MAKE_FINAL_MULTI = FixKind('dart.fix.makeFinal.multi',
+      DartFixKindPriority.IN_FILE, 'Make final where possible in file');
   static const MAKE_RETURN_TYPE_NULLABLE = FixKind(
       'dart.fix.makeReturnTypeNullable', 50, 'Make the return type nullable');
   static const MOVE_TYPE_ARGUMENTS_TO_CLASS = FixKind(
@@ -379,13 +455,15 @@
       FixKind('dart.fix.qualifyReference', 50, "Use '{0}'");
   static const REMOVE_ANNOTATION =
       FixKind('dart.fix.remove.annotation', 50, "Remove the '{0}' annotation");
-  static const REMOVE_ARGUMENT = FixKind(
-      'dart.fix.remove.argument', 50, 'Remove argument',
-      // todo (pq): used by LintNames.avoid_redundant_argument_values; consider a parameterized message
-      appliedTogetherMessage: 'Remove arguments in file');
-  static const REMOVE_AWAIT = FixKind(
-      'dart.fix.remove.await', 50, 'Remove await',
-      appliedTogetherMessage: 'Remove awaits in file');
+  static const REMOVE_ARGUMENT =
+      FixKind('dart.fix.remove.argument', 50, 'Remove argument');
+  // todo (pq): used by LintNames.avoid_redundant_argument_values; consider a parameterized message
+  static const REMOVE_ARGUMENT_MULTI = FixKind('dart.fix.remove.argument.multi',
+      DartFixKindPriority.IN_FILE, 'Remove arguments in file');
+  static const REMOVE_AWAIT =
+      FixKind('dart.fix.remove.await', 50, 'Remove await');
+  static const REMOVE_AWAIT_MULTI = FixKind('dart.fix.remove.await.multi',
+      DartFixKindPriority.IN_FILE, 'Remove awaits in file');
   static const REMOVE_COMPARISON =
       FixKind('dart.fix.remove.comparison', 50, 'Remove comparison');
   static const REMOVE_CONST =
@@ -393,49 +471,75 @@
   static const REMOVE_DEAD_CODE =
       FixKind('dart.fix.remove.deadCode', 50, 'Remove dead code');
   static const REMOVE_DUPLICATE_CASE = FixKind(
-      'dart.fix.remove.duplicateCase', 50, 'Remove duplicate case statement',
-      // todo (pq): is this dangerous to bulk apply?  Consider removing.
-      appliedTogetherMessage:
-          'Remove duplicate case statements everywhere in file');
-  static const REMOVE_EMPTY_CATCH = FixKind(
-      'dart.fix.remove.emptyCatch', 50, 'Remove empty catch clause',
-      appliedTogetherMessage: 'Remove empty catch clauses everywhere in file');
+      'dart.fix.remove.duplicateCase', 50, 'Remove duplicate case statement');
+  // todo (pq): is this dangerous to bulk apply?  Consider removing.
+  static const REMOVE_DUPLICATE_CASE_MULTI = FixKind(
+      'dart.fix.remove.duplicateCase.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove duplicate case statement');
+  static const REMOVE_EMPTY_CATCH =
+      FixKind('dart.fix.remove.emptyCatch', 50, 'Remove empty catch clause');
+  static const REMOVE_EMPTY_CATCH_MULTI = FixKind(
+      'dart.fix.remove.emptyCatch.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove empty catch clauses everywhere in file');
   static const REMOVE_EMPTY_CONSTRUCTOR_BODY = FixKind(
       'dart.fix.remove.emptyConstructorBody',
       50,
-      'Remove empty constructor body',
-      appliedTogetherMessage: 'Remove empty constructor bodies in file');
-  static const REMOVE_EMPTY_ELSE = FixKind(
-      'dart.fix.remove.emptyElse', 50, 'Remove empty else clause',
-      appliedTogetherMessage: 'Remove empty else clauses everywhere in file');
-  static const REMOVE_EMPTY_STATEMENT = FixKind(
-      'dart.fix.remove.emptyStatement', 50, 'Remove empty statement',
-      appliedTogetherMessage: 'Remove empty statements everywhere in file');
-  static const REMOVE_IF_NULL_OPERATOR = FixKind(
-      'dart.fix.remove.ifNullOperator', 50, "Remove the '??' operator",
-      appliedTogetherMessage:
-          "Remove unnecessary '??' operators everywhere in file");
-  static const REMOVE_INITIALIZER = FixKind(
-      'dart.fix.remove.initializer', 50, 'Remove initializer',
-      appliedTogetherMessage:
-          'Remove unnecessary initializers everywhere in file');
+      'Remove empty constructor body');
+  static const REMOVE_EMPTY_CONSTRUCTOR_BODY_MULTI = FixKind(
+      'dart.fix.remove.emptyConstructorBody.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove empty constructor bodies in file');
+  static const REMOVE_EMPTY_ELSE =
+      FixKind('dart.fix.remove.emptyElse', 50, 'Remove empty else clause');
+  static const REMOVE_EMPTY_ELSE_MULTI = FixKind(
+      'dart.fix.remove.emptyElse.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove empty else clauses everywhere in file');
+  static const REMOVE_EMPTY_STATEMENT =
+      FixKind('dart.fix.remove.emptyStatement', 50, 'Remove empty statement');
+  static const REMOVE_EMPTY_STATEMENT_MULTI = FixKind(
+      'dart.fix.remove.emptyStatement.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove empty statements everywhere in file');
+  static const REMOVE_IF_NULL_OPERATOR =
+      FixKind('dart.fix.remove.ifNullOperator', 50, "Remove the '??' operator");
+  static const REMOVE_IF_NULL_OPERATOR_MULTI = FixKind(
+      'dart.fix.remove.ifNullOperator.multi',
+      DartFixKindPriority.IN_FILE,
+      "Remove unnecessary '??' operators everywhere in file");
+  static const REMOVE_INITIALIZER =
+      FixKind('dart.fix.remove.initializer', 50, 'Remove initializer');
+  static const REMOVE_INITIALIZER_MULTI = FixKind(
+      'dart.fix.remove.initializer.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary initializers everywhere in file');
   static const REMOVE_INTERPOLATION_BRACES = FixKind(
       'dart.fix.remove.interpolationBraces',
       50,
-      'Remove unnecessary interpolation braces',
-      appliedTogetherMessage:
-          'Remove unnecessary interpolation braces everywhere in file');
+      'Remove unnecessary interpolation braces');
+  static const REMOVE_INTERPOLATION_BRACES_MULTI = FixKind(
+      'dart.fix.remove.interpolationBraces.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary interpolation braces everywhere in file');
   static const REMOVE_METHOD_DECLARATION = FixKind(
-      'dart.fix.remove.methodDeclaration', 50, 'Remove method declaration',
-      // todo (pq): parameterize to make scope explicit
-      appliedTogetherMessage: 'Remove unnecessary method declarations in file');
+      'dart.fix.remove.methodDeclaration', 50, 'Remove method declaration');
+  // todo (pq): parameterize to make scope explicit
+  static const REMOVE_METHOD_DECLARATION_MULTI = FixKind(
+      'dart.fix.remove.methodDeclaration.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary method declarations in file');
   static const REMOVE_NAME_FROM_COMBINATOR = FixKind(
       'dart.fix.remove.nameFromCombinator', 50, "Remove name from '{0}'");
   static const REMOVE_NON_NULL_ASSERTION =
       FixKind('dart.fix.remove.nonNullAssertion', 50, "Remove the '!'");
-  static const REMOVE_OPERATOR = FixKind(
-      'dart.fix.remove.operator', 50, 'Remove the operator',
-      appliedTogetherMessage: 'Remove operators in file');
+  static const REMOVE_OPERATOR =
+      FixKind('dart.fix.remove.operator', 50, 'Remove the operator');
+  static const REMOVE_OPERATOR_MULTI = FixKind(
+      'dart.fix.remove.operator.multi.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove operators in file');
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = FixKind(
       'dart.fix.remove.parametersInGetterDeclaration',
       50,
@@ -444,42 +548,62 @@
       'dart.fix.remove.parenthesisInGetterInvocation',
       50,
       'Remove parentheses in getter invocation');
-  static const REMOVE_QUESTION_MARK = FixKind(
-      'dart.fix.remove.questionMark', 50, "Remove the '?'",
-      appliedTogetherMessage: 'Remove unnecessary question marks in file');
-  static const REMOVE_THIS_EXPRESSION = FixKind(
-      'dart.fix.remove.thisExpression', 50, 'Remove this expression',
-      appliedTogetherMessage:
-          'Remove unnecessary this expressions everywhere in file');
-  static const REMOVE_TYPE_ANNOTATION = FixKind(
-      'dart.fix.remove.typeAnnotation', 50, 'Remove type annotation',
-      appliedTogetherMessage: 'Remove unnecessary type annotations in file');
+  static const REMOVE_QUESTION_MARK =
+      FixKind('dart.fix.remove.questionMark', 50, "Remove the '?'");
+  static const REMOVE_QUESTION_MARK_MULTI = FixKind(
+      'dart.fix.remove.questionMark.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary question marks in file');
+  static const REMOVE_THIS_EXPRESSION =
+      FixKind('dart.fix.remove.thisExpression', 50, 'Remove this expression');
+  static const REMOVE_THIS_EXPRESSION_MULTI = FixKind(
+      'dart.fix.remove.thisExpression.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary this expressions everywhere in file');
+  static const REMOVE_TYPE_ANNOTATION =
+      FixKind('dart.fix.remove.typeAnnotation', 50, 'Remove type annotation');
+  static const REMOVE_TYPE_ANNOTATION_MULTI = FixKind(
+      'dart.fix.remove.typeAnnotation.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary type annotations in file');
   static const REMOVE_TYPE_ARGUMENTS =
       FixKind('dart.fix.remove.typeArguments', 49, 'Remove type arguments');
-  static const REMOVE_UNNECESSARY_CAST = FixKind(
-      'dart.fix.remove.unnecessaryCast', 50, 'Remove unnecessary cast',
-      appliedTogetherMessage: 'Remove all unnecessary casts in file');
+  static const REMOVE_UNNECESSARY_CAST =
+      FixKind('dart.fix.remove.unnecessaryCast', 50, 'Remove unnecessary cast');
+  static const REMOVE_UNNECESSARY_CAST_MULTI = FixKind(
+      'dart.fix.remove.unnecessaryCast.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove all unnecessary casts in file');
   static const REMOVE_UNNECESSARY_CONST = FixKind(
       'dart.fix.remove.unnecessaryConst',
       50,
-      'Remove unnecessary const keyword',
-      appliedTogetherMessage:
-          'Remove unnecessary const keywords everywhere in file');
+      'Remove unnecessary const keyword');
+  static const REMOVE_UNNECESSARY_CONST_MULTI = FixKind(
+      'dart.fix.remove.unnecessaryConst.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary const keywords everywhere in file');
   static const REMOVE_UNNECESSARY_NEW = FixKind(
-      'dart.fix.remove.unnecessaryNew', 50, 'Remove unnecessary new keyword',
-      appliedTogetherMessage:
-          'Remove unnecessary new keywords everywhere in file');
+      'dart.fix.remove.unnecessaryNew', 50, 'Remove unnecessary new keyword');
+  static const REMOVE_UNNECESSARY_NEW_MULTI = FixKind(
+      'dart.fix.remove.unnecessaryNew.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unnecessary new keywords everywhere in file');
   static const REMOVE_UNNECESSARY_PARENTHESES = FixKind(
       'dart.fix.remove.unnecessaryParentheses',
       50,
-      'Remove unnecessary parentheses',
-      appliedTogetherMessage: 'Remove all unnecessary parentheses in file');
+      'Remove unnecessary parentheses');
+  static const REMOVE_UNNECESSARY_PARENTHESES_MULTI = FixKind(
+      'dart.fix.remove.unnecessaryParentheses.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove all unnecessary parentheses in file');
   static const REMOVE_UNNECESSARY_STRING_INTERPOLATION = FixKind(
       'dart.fix.remove.unnecessaryStringInterpolation',
       50,
-      'Remove unnecessary string interpolation',
-      appliedTogetherMessage:
-          'Remove all unnecessary string interpolations in file');
+      'Remove unnecessary string interpolation');
+  static const REMOVE_UNNECESSARY_STRING_INTERPOLATION_MULTI = FixKind(
+      'dart.fix.remove.unnecessaryStringInterpolation.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove all unnecessary string interpolations in file');
   static const REMOVE_UNUSED_CATCH_CLAUSE = FixKind(
       'dart.fix.remove.unusedCatchClause', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = FixKind(
@@ -490,9 +614,12 @@
       FixKind('dart.fix.remove.unusedElement', 50, 'Remove unused element');
   static const REMOVE_UNUSED_FIELD =
       FixKind('dart.fix.remove.unusedField', 50, 'Remove unused field');
-  static const REMOVE_UNUSED_IMPORT = FixKind(
-      'dart.fix.remove.unusedImport', 50, 'Remove unused import',
-      appliedTogetherMessage: 'Remove all unused imports in file');
+  static const REMOVE_UNUSED_IMPORT =
+      FixKind('dart.fix.remove.unusedImport', 50, 'Remove unused import');
+  static const REMOVE_UNUSED_IMPORT_MULTI = FixKind(
+      'dart.fix.remove.unusedImport.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove all unused imports in file');
   static const REMOVE_UNUSED_LABEL =
       FixKind('dart.fix.remove.unusedLabel', 50, 'Remove unused label');
   static const REMOVE_UNUSED_LOCAL_VARIABLE = FixKind(
@@ -500,63 +627,106 @@
       50,
       'Remove unused local variable');
   static const REMOVE_UNUSED_PARAMETER = FixKind(
-      'dart.fix.remove.unusedParameter', 50, 'Remove the unused parameter',
-      appliedTogetherMessage: 'Remove unused parameters everywhere in file');
-  static const RENAME_TO_CAMEL_CASE = FixKind(
-      'dart.fix.rename.toCamelCase', 50, "Rename to '{0}'",
-      appliedTogetherMessage: 'Rename to camel case everywhere in file');
+      'dart.fix.remove.unusedParameter', 50, 'Remove the unused parameter');
+  static const REMOVE_UNUSED_PARAMETER_MULTI = FixKind(
+      'dart.fix.remove.unusedParameter.multi',
+      DartFixKindPriority.IN_FILE,
+      'Remove unused parameters everywhere in file');
+  static const RENAME_TO_CAMEL_CASE =
+      FixKind('dart.fix.rename.toCamelCase', 50, "Rename to '{0}'");
+  static const RENAME_TO_CAMEL_CASE_MULTI = FixKind(
+      'dart.fix.rename.toCamelCase.multi',
+      DartFixKindPriority.IN_FILE,
+      'Rename to camel case everywhere in file');
   static const REPLACE_BOOLEAN_WITH_BOOL = FixKind(
-      'dart.fix.replace.booleanWithBool', 50, "Replace 'boolean' with 'bool'",
-      appliedTogetherMessage: "Replace all 'boolean's with 'bool' in file");
-  static const REPLACE_CASCADE_WITH_DOT = FixKind(
-      'dart.fix.replace.cascadeWithDot', 50, "Replace '..' with '.'",
-      appliedTogetherMessage:
-          "Replace unnecessary '..'s with '.'s everywhere in file");
-  static const REPLACE_COLON_WITH_EQUALS = FixKind(
-      'dart.fix.replace.colonWithEquals', 50, "Replace ':' with '='",
-      appliedTogetherMessage: "Replace ':'s with '='s everywhere in file");
+      'dart.fix.replace.booleanWithBool', 50, "Replace 'boolean' with 'bool'");
+  static const REPLACE_BOOLEAN_WITH_BOOL_MULTI = FixKind(
+      'dart.fix.replace.booleanWithBool.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace all 'boolean's with 'bool' in file");
+  static const REPLACE_CASCADE_WITH_DOT =
+      FixKind('dart.fix.replace.cascadeWithDot', 50, "Replace '..' with '.'");
+  static const REPLACE_CASCADE_WITH_DOT_MULTI = FixKind(
+      'dart.fix.replace.cascadeWithDot.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace unnecessary '..'s with '.'s everywhere in file");
+  static const REPLACE_COLON_WITH_EQUALS =
+      FixKind('dart.fix.replace.colonWithEquals', 50, "Replace ':' with '='");
+  static const REPLACE_COLON_WITH_EQUALS_MULTI = FixKind(
+      'dart.fix.replace.colonWithEquals.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace ':'s with '='s everywhere in file");
   static const REPLACE_WITH_FILLED = FixKind(
       'dart.fix.replace.finalWithListFilled', 50, "Replace with 'List.filled'");
   static const REPLACE_FINAL_WITH_CONST = FixKind(
-      'dart.fix.replace.finalWithConst', 50, "Replace 'final' with 'const'",
-      appliedTogetherMessage:
-          "Replace 'final' with 'const' where possible in file");
+      'dart.fix.replace.finalWithConst', 50, "Replace 'final' with 'const'");
+  static const REPLACE_FINAL_WITH_CONST_MULTI = FixKind(
+      'dart.fix.replace.finalWithConst.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace 'final' with 'const' where possible in file");
   static const REPLACE_NEW_WITH_CONST = FixKind(
       'dart.fix.replace.newWithConst', 50, "Replace 'new' with 'const'");
+  static const REPLACE_NEW_WITH_CONST_MULTI = FixKind(
+      'dart.fix.replace.newWithConst.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace 'new' with 'const' where possible in file");
   static const REPLACE_NULL_WITH_CLOSURE = FixKind(
-      'dart.fix.replace.nullWithClosure', 50, "Replace 'null' with a closure",
-      appliedTogetherMessage:
-          "Replace 'null's with closures where possible in file");
+      'dart.fix.replace.nullWithClosure', 50, "Replace 'null' with a closure");
+  static const REPLACE_NULL_WITH_CLOSURE_MULTI = FixKind(
+      'dart.fix.replace.nullWithClosure.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace 'null's with closures where possible in file");
   static const REPLACE_RETURN_TYPE_FUTURE = FixKind(
       'dart.fix.replace.returnTypeFuture',
       50,
       "Return 'Future' from 'async' function");
   static const REPLACE_VAR_WITH_DYNAMIC = FixKind(
       'dart.fix.replace.varWithDynamic', 50, "Replace 'var' with 'dynamic'");
-  static const REPLACE_WITH_EIGHT_DIGIT_HEX = FixKind(
-      'dart.fix.replace.withEightDigitHex', 50, "Replace with '{0}'",
-      appliedTogetherMessage: 'Replace with hex digits everywhere in file');
-  static const REPLACE_WITH_BRACKETS = FixKind(
-      'dart.fix.replace.withBrackets', 50, 'Replace with { }',
-      appliedTogetherMessage: 'Replace with { } everywhere in file');
+  static const REPLACE_WITH_EIGHT_DIGIT_HEX =
+      FixKind('dart.fix.replace.withEightDigitHex', 50, "Replace with '{0}'");
+  static const REPLACE_WITH_EIGHT_DIGIT_HEX_MULTI = FixKind(
+      'dart.fix.replace.withEightDigitHex.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace with hex digits everywhere in file');
+  static const REPLACE_WITH_BRACKETS =
+      FixKind('dart.fix.replace.withBrackets', 50, 'Replace with { }');
+  static const REPLACE_WITH_BRACKETS_MULTI = FixKind(
+      'dart.fix.replace.withBrackets.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace with { } everywhere in file');
   static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = FixKind(
-      'dart.fix.replace.withConditionalAssignment', 50, 'Replace with ??=',
-      appliedTogetherMessage: 'Replace with ??= everywhere in file');
+      'dart.fix.replace.withConditionalAssignment', 50, 'Replace with ??=');
+  static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT_MULTI = FixKind(
+      'dart.fix.replace.withConditionalAssignment.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace with ??= everywhere in file');
   static const REPLACE_WITH_EXTENSION_NAME =
       FixKind('dart.fix.replace.withExtensionName', 50, "Replace with '{0}'");
-  static const REPLACE_WITH_IDENTIFIER = FixKind(
-      'dart.fix.replace.withIdentifier', 50, 'Replace with identifier',
-      // todo (pq): parameterize message (used by LintNames.avoid_types_on_closure_parameters)
-      appliedTogetherMessage: 'Replace with identifier everywhere in file');
+  static const REPLACE_WITH_IDENTIFIER =
+      FixKind('dart.fix.replace.withIdentifier', 50, 'Replace with identifier');
+  // todo (pq): parameterize message (used by LintNames.avoid_types_on_closure_parameters)
+  static const REPLACE_WITH_IDENTIFIER_MULTI = FixKind(
+      'dart.fix.replace.withIdentifier.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace with identifier everywhere in file');
   static const REPLACE_WITH_INTERPOLATION = FixKind(
-      'dart.fix.replace.withInterpolation', 50, 'Replace with interpolation',
-      appliedTogetherMessage: 'Replace with interpolations everywhere in file');
-  static const REPLACE_WITH_IS_EMPTY = FixKind(
-      'dart.fix.replace.withIsEmpty', 50, "Replace with 'isEmpty'",
-      appliedTogetherMessage: "Replace with 'isEmpty' everywhere in file");
+      'dart.fix.replace.withInterpolation', 50, 'Replace with interpolation');
+  static const REPLACE_WITH_INTERPOLATION_MULTI = FixKind(
+      'dart.fix.replace.withInterpolation.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace with interpolations everywhere in file');
+  static const REPLACE_WITH_IS_EMPTY =
+      FixKind('dart.fix.replace.withIsEmpty', 50, "Replace with 'isEmpty'");
+  static const REPLACE_WITH_IS_EMPTY_MULTI = FixKind(
+      'dart.fix.replace.withIsEmpty.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace with 'isEmpty' everywhere in file");
   static const REPLACE_WITH_IS_NOT_EMPTY = FixKind(
-      'dart.fix.replace.withIsNotEmpty', 50, "Replace with 'isNotEmpty'",
-      appliedTogetherMessage: "Replace with 'isNotEmpty' everywhere in file");
+      'dart.fix.replace.withIsNotEmpty', 50, "Replace with 'isNotEmpty'");
+  static const REPLACE_WITH_IS_NOT_EMPTY_MULTI = FixKind(
+      'dart.fix.replace.withIsNotEmpty.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace with 'isNotEmpty' everywhere in file");
   static const REPLACE_WITH_NOT_NULL_AWARE =
       FixKind('dart.fix.replace.withNotNullAware', 50, "Replace with '{0}'");
   static const REPLACE_WITH_NULL_AWARE = FixKind(
@@ -564,19 +734,25 @@
       50,
       "Replace the '.' with a '?.' in the invocation");
   static const REPLACE_WITH_TEAR_OFF = FixKind('dart.fix.replace.withTearOff',
-      50, 'Replace function literal with tear-off',
-      appliedTogetherMessage:
-          'Replace function literals with tear-offs everywhere in file');
+      50, 'Replace function literal with tear-off');
+  static const REPLACE_WITH_TEAR_OFF_MULTI = FixKind(
+      'dart.fix.replace.withTearOff.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace function literals with tear-offs everywhere in file');
   static const REPLACE_WITH_VAR = FixKind(
-      'dart.fix.replace.withVar', 50, "Replace type annotation with 'var'",
-      appliedTogetherMessage:
-          "Replace unnecessary type annotations with 'var' in file");
+      'dart.fix.replace.withVar', 50, "Replace type annotation with 'var'");
+  static const REPLACE_WITH_VAR_MULTI = FixKind(
+      'dart.fix.replace.withVar.multi',
+      DartFixKindPriority.IN_FILE,
+      "Replace unnecessary type annotations with 'var' in file");
   static const SORT_CHILD_PROPERTY_LAST = FixKind(
       'dart.fix.sort.childPropertyLast',
       50,
-      'Move child property to end of arguments',
-      appliedTogetherMessage:
-          'Move child properties to ends of arguments everywhere in file');
+      'Move child property to end of arguments');
+  static const SORT_CHILD_PROPERTY_LAST_MULTI = FixKind(
+      'dart.fix.sort.childPropertyLast.multi',
+      DartFixKindPriority.IN_FILE,
+      'Move child properties to ends of arguments everywhere in file');
   static const UPDATE_SDK_CONSTRAINTS = FixKind(
       'dart.fix.updateSdkConstraints', 50, 'Update the SDK constraints');
   static const USE_CONST =
@@ -585,28 +761,42 @@
       'dart.fix.use.effectiveIntegerDivision',
       50,
       'Use effective integer division ~/');
-  static const USE_EQ_EQ_NULL = FixKind(
-      'dart.fix.use.eqEqNull', 50, "Use == null instead of 'is Null'",
-      appliedTogetherMessage:
-          "Use == null instead of 'is Null' everywhere in file");
-  static const USE_IS_NOT_EMPTY = FixKind(
-      'dart.fix.use.isNotEmpty', 50, "Use x.isNotEmpty instead of '!x.isEmpty'",
-      appliedTogetherMessage:
-          "Use x.isNotEmpty instead of '!x.isEmpty' everywhere in file");
+  static const USE_EQ_EQ_NULL =
+      FixKind('dart.fix.use.eqEqNull', 50, "Use == null instead of 'is Null'");
+  static const USE_EQ_EQ_NULL_MULTI = FixKind(
+      'dart.fix.use.eqEqNull.multi',
+      DartFixKindPriority.IN_FILE,
+      "Use == null instead of 'is Null' everywhere in file");
+  static const USE_IS_NOT_EMPTY = FixKind('dart.fix.use.isNotEmpty', 50,
+      "Use x.isNotEmpty instead of '!x.isEmpty'");
+  static const USE_IS_NOT_EMPTY_MULTI = FixKind(
+      'dart.fix.use.isNotEmpty.multi',
+      DartFixKindPriority.IN_FILE,
+      "Use x.isNotEmpty instead of '!x.isEmpty' everywhere in file");
   static const USE_NOT_EQ_NULL = FixKind(
-      'dart.fix.use.notEqNull', 50, "Use != null instead of 'is! Null'",
-      appliedTogetherMessage:
-          "Use != null instead of 'is! Null' everywhere in file");
-  static const USE_RETHROW = FixKind(
-      'dart.fix.use.rethrow', 50, 'Replace throw with rethrow',
-      appliedTogetherMessage:
-          'Replace throw with rethrow where possible in file');
+      'dart.fix.use.notEqNull', 50, "Use != null instead of 'is! Null'");
+  static const USE_NOT_EQ_NULL_MULTI = FixKind(
+      'dart.fix.use.notEqNull.multi',
+      DartFixKindPriority.IN_FILE,
+      "Use != null instead of 'is! Null' everywhere in file");
+  static const USE_RETHROW =
+      FixKind('dart.fix.use.rethrow', 50, 'Replace throw with rethrow');
+  static const USE_RETHROW_MULTI = FixKind(
+      'dart.fix.use.rethrow.multi',
+      DartFixKindPriority.IN_FILE,
+      'Replace throw with rethrow where possible in file');
   static const WRAP_IN_FUTURE =
       FixKind('dart.fix.wrap.future', 50, "Wrap in 'Future.value'");
   static const WRAP_IN_TEXT =
       FixKind('dart.fix.flutter.wrap.text', 50, "Wrap in a 'Text' widget");
 }
 
+class DartFixKindPriority {
+  // todo (pq): update all priorities to use these constants.
+  static const int DEFAULT = 50;
+  static const int IN_FILE = 40;
+}
+
 /// An enumeration of quick fix kinds for the errors found in an Android
 /// manifest file.
 class ManifestFixKind {}
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 cb7e610..eeecbf0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -233,8 +233,8 @@
       var sourceChange = fixState.builder.sourceChange;
       if (sourceChange.edits.isNotEmpty) {
         var fixKind = fixState.fixKind;
-        if (fixKind.canBeAppliedTogether() && fixState.fixCount > 1) {
-          sourceChange.message = fixKind.appliedTogetherMessage;
+        if (fixState.fixCount > 1) {
+          sourceChange.message = fixKind.message;
           fixes.add(Fix(fixKind, sourceChange));
         }
       }
@@ -267,7 +267,7 @@
       fixState.builder = localBuilder;
       // todo (pq): consider discarding the change if the producer's fixKind
       // doesn't match a previously cached one.
-      fixState.fixKind = producer.fixKind;
+      fixState.fixKind = producer.multiFixKind;
       fixState.fixCount++;
     } on ConflictingEditException {
       // If a conflicting edit was added in [compute], then the [localBuilder]
@@ -279,11 +279,14 @@
       ErrorCode errorCode, CorrectionProducerContext context) {
     var producers = <ProducerGenerator>[];
     if (errorCode is LintCode) {
-      var generators = FixProcessor.lintProducerMap[errorCode.name];
-      if (generators != null) {
-        producers.addAll(generators);
+      var fixInfos = FixProcessor.lintProducerMap2[errorCode.name] ?? [];
+      for (var fixInfo in fixInfos) {
+        if (fixInfo.canBeAppliedToFile) {
+          producers.addAll(fixInfo.generators);
+        }
       }
     } else {
+      // todo (pq): update to a new nonLintProducerMap2
       var generators = FixProcessor.nonLintProducerMap[errorCode];
       if (generators != null) {
         if (generators != null) {
@@ -775,7 +778,8 @@
     // todo (pq): note this is not in lintProducerMap
     LintNames.prefer_is_not_operator: [
       FixInfo(
-        canBeAppliedToFile: true,
+        // todo (pq): consider enabling
+        canBeAppliedToFile: false,
         canBeBulkApplied: true,
         generators: [
           ConvertIntoIsNot.newInstance,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart
index 14e8d76..c03d633b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_in_file_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -57,14 +58,45 @@
 
 @reflectiveTest
 class SingleFixInFileTest extends FixInFileProcessorTest {
-  Future<void> test_fix_isNull() async {
+  Future<void> test_fix_lint_annotate_overrides() async {
+    createAnalysisOptionsFile(lints: [LintNames.annotate_overrides]);
+    await resolveTestCode('''
+class A {
+  void a() {}
+  void aa() {}
+}
+
+class B extends A {
+  void a() {}
+  void aa() {}
+}
+''');
+    var fixes = await getFixesForFirstError();
+    expect(fixes, hasLength(1));
+    assertProduces(fixes.first, '''
+class A {
+  void a() {}
+  void aa() {}
+}
+
+class B extends A {
+  @override
+  void a() {}
+  @override
+  void aa() {}
+}
+''');
+  }
+
+  @FailingTest(reason: 'enable once nonLintProducers are supported')
+  Future<void> test_fix_nonLint_isNull() async {
     await resolveTestCode('''
 bool f(p, q) {
   return p is Null && q is Null;
 }
 ''');
 
-    var fixes = await getFixes();
+    var fixes = await getFixesForFirstError();
     expect(fixes, hasLength(1));
     assertProduces(fixes.first, '''
 bool f(p, q) {
@@ -80,32 +112,16 @@
 }
 ''');
 
-    var fixes = await getFixes();
+    var fixes = await getFixesForFirstError();
     expect(fixes, isEmpty);
   }
 }
 
-@reflectiveTest
-class VerificationTest extends FixInFileProcessorTest {
-  Future<void> test_fixInFileTestsHaveApplyTogetherMessages() async {
-    for (var fixInfos in FixProcessor.lintProducerMap2.values) {
-      for (var fixInfo in fixInfos) {
-        if (fixInfo.canBeBulkApplied) {
-          for (var generator in fixInfo.generators) {
-            test('', () {
-              expect(generator().fixKind.canBeAppliedTogether(), isTrue);
-            });
-          }
-        }
-      }
-    }
-  }
-}
-
 class VerificationTests {
   static void defineTests() {
     verify_fixInFileFixesHaveBulkFixTests();
-    verify_fixInFileFixKindsHaveApplyTogetherMessages();
+    verify_fixInFileFixKindsHaveMultiFixes();
+    verify_fixInFileFixesHaveUniqueBulkFixes();
   }
 
   static void verify_fixInFileFixesHaveBulkFixTests() {
@@ -123,24 +139,50 @@
     });
   }
 
-  static void verify_fixInFileFixKindsHaveApplyTogetherMessages() {
-    group('VerificationTests | fixInFileFixKindsHaveApplyTogetherMessages |',
-        () {
+  static void verify_fixInFileFixesHaveUniqueBulkFixes() {
+    group('VerificationTests | fixInFileFixesHaveUniqueBulkFixes | lint |', () {
       for (var fixEntry in FixProcessor.lintProducerMap2.entries) {
         var errorCode = fixEntry.key;
         for (var fixInfo in fixEntry.value) {
           if (fixInfo.canBeAppliedToFile) {
-            var generators = fixInfo.generators;
-            for (var i = 0; i < generators.length; ++i) {
-              var generator = generators[i];
-              var fixKind = generator().fixKind;
-              // Cases where fix kinds are determined by context are not verified here.
-              if (fixKind != null) {
-                test('$errorCode | generator ($i) | ${fixKind.id}', () {
-                  expect(fixKind.canBeAppliedTogether(), isTrue);
-                });
+            test('$errorCode |', () {
+              for (var generator in fixInfo.generators) {
+                var g = generator();
+                var multiFixKind = g.multiFixKind;
+                var fixKind = g.fixKind;
+                if (multiFixKind != null) {
+                  expect(multiFixKind, isNot(equals(fixKind)));
+                }
               }
-            }
+              expect(fixInfo.canBeBulkApplied, isTrue);
+            });
+          }
+        }
+      }
+    });
+  }
+
+  static void verify_fixInFileFixKindsHaveMultiFixes() {
+    // todo (pq): find a better way to verify dynamic producers.
+    var dynamicProducerTypes = ['ReplaceWithIsEmpty'];
+
+    group('VerificationTests | fixInFileFixKindsHaveMultiFixes | lint |', () {
+      for (var fixEntry in FixProcessor.lintProducerMap2.entries) {
+        var errorCode = fixEntry.key;
+        for (var fixInfo in fixEntry.value) {
+          // At least one generator should have a multiFix.
+          if (fixInfo.canBeAppliedToFile) {
+            test('$errorCode |', () {
+              var generators = fixInfo.generators;
+              var foundMultiFix = false;
+              for (var i = 0; i < generators.length && !foundMultiFix; ++i) {
+                var generator = generators[i]();
+                foundMultiFix = generator.multiFixKind != null ||
+                    dynamicProducerTypes
+                        .contains(generator.runtimeType.toString());
+              }
+              expect(foundMultiFix, isTrue);
+            });
           }
         }
       }
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 bcc8d35..67e4ffe 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
@@ -108,7 +108,7 @@
     expect(resultCode, expected);
   }
 
-  Future<List<Fix>> getFixes() async {
+  Future<List<Fix>> getFixesForFirstError() async {
     var errors = await _computeErrors();
     expect(errors, isNotEmpty);
     String errorCode;
@@ -430,3 +430,13 @@
     );
   }
 }
+
+/// todo (pq): temporary
+extension FixExtension on Fix {
+  bool isFixAllFix() => kind.canBeAppliedTogether();
+}
+
+extension FixKindExtension on FixKind {
+  /// todo (pq): temporary
+  bool canBeAppliedTogether() => priority == DartFixKindPriority.IN_FILE;
+}
diff --git a/pkg/analysis_server/tool/code_completion/code_metrics.dart b/pkg/analysis_server/tool/code_completion/code_metrics.dart
index 0876be9..97510ff 100644
--- a/pkg/analysis_server/tool/code_completion/code_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/code_metrics.dart
@@ -12,7 +12,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:args/args.dart';
 
 /// Compute and print lexical and semantic information about a package.
@@ -1389,8 +1389,9 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     var context = collection.contexts[0];
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           var resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index b9c2038..fbb23b7 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -41,8 +41,8 @@
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:args/args.dart';
@@ -901,8 +901,9 @@
 
     // Loop through each file, resolve the file and call
     // forEachExpectedCompletion
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           _resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
index dee0616..74cc153 100644
--- a/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/flutter_metrics.dart
@@ -12,7 +12,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:args/args.dart';
 
 /// Compute and print information about flutter packages.
@@ -202,8 +202,9 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     var context = collection.contexts[0];
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           var resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
index c788082..056ff2e 100644
--- a/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
+++ b/pkg/analysis_server/tool/code_completion/implicit_type_declarations.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:args/args.dart';
 import 'package:meta/meta.dart';
 
@@ -180,8 +180,9 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     var context = collection.contexts[0];
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           var resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
index 2664da1..c4a6398 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_metrics.dart
@@ -32,7 +32,7 @@
 import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:args/args.dart';
 import 'package:meta/meta.dart';
 
@@ -1939,8 +1939,9 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     var context = collection.contexts[0];
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           var resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
index 53e3fe2..b1d7d79 100644
--- a/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/code_completion/relevance_table_generator.dart
@@ -23,7 +23,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_utilities/package_root.dart' as package_root;
 import 'package:analyzer_utilities/tools.dart';
 import 'package:args/args.dart';
@@ -38,18 +38,19 @@
   if (validArguments(parser, result)) {
     var provider = PhysicalResourceProvider.INSTANCE;
     var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
-    var generatedFilePath = provider.pathContext.join(
-        packageRoot,
-        'analysis_server',
-        'lib',
-        'src',
-        'services',
-        'completion',
-        'dart',
-        'relevance_tables.g.dart');
-    var generatedFile = provider.getFile(generatedFilePath);
 
-    void writeRelevanceTable(RelevanceData data, File generatedFile) {
+    void writeRelevanceTable(RelevanceData data, {String suffix = ''}) {
+      var generatedFilePath = provider.pathContext.join(
+          packageRoot,
+          'analysis_server',
+          'lib',
+          'src',
+          'services',
+          'completion',
+          'dart',
+          'relevance_tables$suffix.g.dart');
+      var generatedFile = provider.getFile(generatedFilePath);
+
       var buffer = StringBuffer();
       var writer = RelevanceTableWriter(buffer);
       writer.write(data);
@@ -60,13 +61,14 @@
     if (result.wasParsed('reduceDir')) {
       var data = RelevanceData();
       var dir = provider.getFolder(result['reduceDir']);
+      var suffix = result.rest.isNotEmpty ? result.rest[0] : '';
       for (var child in dir.getChildren()) {
         if (child is File) {
           var newData = RelevanceData.fromJson(child.readAsStringSync());
           data.addData(newData);
         }
       }
-      writeRelevanceTable(data, generatedFile);
+      writeRelevanceTable(data, suffix: suffix);
       return;
     }
 
@@ -102,7 +104,7 @@
       var dataFile = uniqueDataFile();
       dataFile.writeAsStringSync(computer.data.toJson());
     } else {
-      writeRelevanceTable(computer.data, generatedFile);
+      writeRelevanceTable(computer.data);
     }
     stopwatch.stop();
 
@@ -160,11 +162,6 @@
     printUsage(parser);
     return false;
   } else if (result.wasParsed('reduceDir')) {
-    if (result.rest.isNotEmpty) {
-      printUsage(parser,
-          error: 'A package path is not allowed in reduce mode.');
-      return false;
-    }
     return validateDir(parser, result['reduceDir']);
   } else if (result.rest.length != 1) {
     printUsage(parser, error: 'No package path specified.');
@@ -1477,8 +1474,9 @@
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
     var context = collection.contexts[0];
+    var pathContext = context.contextRoot.resourceProvider.pathContext;
     for (var filePath in context.contextRoot.analyzedFiles()) {
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      if (file_paths.isDart(pathContext, filePath)) {
         try {
           var resolvedUnitResult =
               await context.currentSession.getResolvedUnit(filePath);
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 7f8587d..677f728 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -295,11 +295,6 @@
   }
 
   String _resolveLinks(String path) {
-    var linkTarget = _pathToLinkedPath[path];
-    if (linkTarget != null) {
-      return linkTarget;
-    }
-
     var parentPath = _pathContext.dirname(path);
     if (parentPath == path) {
       return path;
@@ -310,10 +305,14 @@
     var baseName = _pathContext.basename(path);
     var result = _pathContext.join(canonicalParentPath, baseName);
 
-    linkTarget = _pathToLinkedPath[result];
-    if (linkTarget != null) {
-      return linkTarget;
-    }
+    do {
+      var linkTarget = _pathToLinkedPath[result];
+      if (linkTarget != null) {
+        result = linkTarget;
+      } else {
+        break;
+      }
+    } while (true);
 
     return result;
   }
@@ -638,7 +637,13 @@
   @override
   Folder resolveSymbolicLinksSync() {
     var canonicalPath = provider._resolveLinks(path);
-    return provider.getFolder(canonicalPath);
+    var result = provider.getFolder(canonicalPath);
+
+    if (!result.exists) {
+      throw FileSystemException(path, 'Folder "$path" does not exist.');
+    }
+
+    return result;
   }
 
   @override
diff --git a/pkg/analyzer/lib/file_system/overlay_file_system.dart b/pkg/analyzer/lib/file_system/overlay_file_system.dart
index 5936481..3c218f1 100644
--- a/pkg/analyzer/lib/file_system/overlay_file_system.dart
+++ b/pkg/analyzer/lib/file_system/overlay_file_system.dart
@@ -395,8 +395,17 @@
   }
 
   @override
-  Resource resolveSymbolicLinksSync() =>
-      _OverlayResource._from(provider, _resource.resolveSymbolicLinksSync());
+  Resource resolveSymbolicLinksSync() {
+    try {
+      var resolved = _resource.resolveSymbolicLinksSync();
+      return _OverlayResource._from(provider, resolved);
+    } catch (_) {
+      if (provider.hasOverlay(path) || provider._hasOverlayIn(path)) {
+        return this;
+      }
+      rethrow;
+    }
+  }
 
   @override
   String toString() => path;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index b9e2a2d..ef912afc 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -41,6 +41,7 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:meta/meta.dart';
 
 /// TODO(scheglov) We could use generalized Function in
@@ -447,7 +448,7 @@
       return;
     }
     analyzedFiles.reset();
-    if (AnalysisEngine.isDartFileName(path)) {
+    if (file_paths.isDart(resourceProvider.pathContext, path)) {
       _fileTracker.addFile(path);
       // If the file is known, it has already been read, even if it did not
       // exist. Now we are notified that the file exists, so we need to
@@ -834,7 +835,7 @@
   /// The [path] must be absolute and normalized.
   Future<SourceKind?> getSourceKind(String path) async {
     _throwIfNotAbsolutePath(path);
-    if (AnalysisEngine.isDartFileName(path)) {
+    if (file_paths.isDart(resourceProvider.pathContext, path)) {
       FileState file = _fileTracker.getFile(path);
       return file.isPart ? SourceKind.PART : SourceKind.LIBRARY;
     }
@@ -2304,10 +2305,11 @@
 
   void _appendFilesRecursively(Folder folder) {
     try {
+      var pathContext = driver.resourceProvider.pathContext;
       for (var child in folder.getChildren()) {
         if (child is File) {
           var path = child.path;
-          if (AnalysisEngine.isDartFileName(path)) {
+          if (file_paths.isDart(pathContext, path)) {
             files!.add(path);
           }
         } else if (child is Folder) {
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 12491b5..3848bf9 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/summary/api_signature.dart';
@@ -88,9 +87,6 @@
 /// The entry point for the functionality provided by the analysis engine. There
 /// is a single instance of this class.
 class AnalysisEngine {
-  /// The suffix used for Dart source files.
-  static const String SUFFIX_DART = "dart";
-
   /// The file name used for analysis options files.
   static const String ANALYSIS_OPTIONS_YAML_FILE = 'analysis_options.yaml';
 
@@ -139,16 +135,6 @@
   /// process any other plugins.
   @deprecated
   void processRequiredPlugins() {}
-
-  /// Return `true` if the given [fileName] is assumed to contain Dart source
-  /// code.
-  static bool isDartFileName(String? fileName) {
-    if (fileName == null) {
-      return false;
-    }
-    String extension = FileNameUtilities.getExtension(fileName).toLowerCase();
-    return extension == SUFFIX_DART;
-  }
 }
 
 /// The analysis errors and line information for the errors.
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index 4457470..82c2f23 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -10,19 +10,6 @@
 /// A predicate is a one-argument function that returns a boolean value.
 typedef Predicate<E> = bool Function(E argument);
 
-class FileNameUtilities {
-  static String getExtension(String? fileName) {
-    if (fileName == null) {
-      return "";
-    }
-    int index = fileName.lastIndexOf('.');
-    if (index >= 0) {
-      return fileName.substring(index + 1);
-    }
-    return "";
-  }
-}
-
 class StringUtilities {
   static const String EMPTY = '';
   static const List<String> EMPTY_ARRAY = <String>[];
diff --git a/pkg/analyzer/test/file_system/file_system_test_support.dart b/pkg/analyzer/test/file_system/file_system_test_support.dart
index 2323080..b3e8e9e 100644
--- a/pkg/analyzer/test/file_system/file_system_test_support.dart
+++ b/pkg/analyzer/test/file_system/file_system_test_support.dart
@@ -305,9 +305,40 @@
 
   test_renameSync_notExisting();
 
-  test_resolveSymbolicLinksSync_links_existing();
+  test_resolveSymbolicLinksSync_links_existing() {
+    var a_path = join(tempPath, 'aaa', 'a.dart');
+    var b_path = join(tempPath, 'bbb', 'b.dart');
 
-  test_resolveSymbolicLinksSync_links_notExisting();
+    getFile(exists: true, filePath: a_path);
+    createLink(path: b_path, target: a_path);
+
+    var resolved = provider.getFile(b_path).resolveSymbolicLinksSync();
+    expect(resolved.path, a_path);
+  }
+
+  test_resolveSymbolicLinksSync_links_existing2() {
+    var a = join(tempPath, 'aaa', 'a.dart');
+    var b = join(tempPath, 'bbb', 'b.dart');
+    var c = join(tempPath, 'ccc', 'c.dart');
+
+    getFile(exists: true, filePath: a);
+    createLink(path: b, target: a);
+    createLink(path: c, target: b);
+
+    var resolved = provider.getFile(c).resolveSymbolicLinksSync();
+    expect(resolved.path, a);
+  }
+
+  test_resolveSymbolicLinksSync_links_notExisting() {
+    var a = join(tempPath, 'a.dart');
+    var b = join(tempPath, 'b.dart');
+
+    createLink(path: b, target: a);
+
+    expect(() {
+      provider.getFile(b).resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
 
   test_resolveSymbolicLinksSync_noLinks_existing() {
     File file = getFile(exists: true);
@@ -315,7 +346,13 @@
     expect(file.resolveSymbolicLinksSync(), file);
   }
 
-  test_resolveSymbolicLinksSync_noLinks_notExisting();
+  test_resolveSymbolicLinksSync_noLinks_notExisting() {
+    var path = join(tempPath, 'a.dart');
+
+    expect(() {
+      provider.getFile(path).resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
 
   test_shortName() {
     File file = getFile(exists: false);
@@ -740,6 +777,36 @@
     }
   }
 
+  test_resolveSymbolicLinksSync_links_existing() {
+    var foo = join(tempPath, 'foo');
+    var bar = join(tempPath, 'bar');
+
+    getFolder(exists: true, folderPath: foo);
+    createLink(path: bar, target: foo);
+
+    var resolved = provider.getFolder(bar).resolveSymbolicLinksSync();
+    expect(resolved.path, foo);
+  }
+
+  test_resolveSymbolicLinksSync_links_notExisting() {
+    var foo = join(tempPath, 'foo');
+    var bar = join(tempPath, 'bar');
+
+    createLink(path: bar, target: foo);
+
+    expect(() {
+      provider.getFolder(bar).resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
+
+  test_resolveSymbolicLinksSync_noLinks_notExisting() {
+    var path = join(tempPath, 'foo');
+
+    expect(() {
+      provider.getFolder(path).resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
+
   test_toUri() {
     Folder folder = getFolder(exists: true);
 
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 9dc70d1..c4a447c 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -256,39 +256,6 @@
   }
 
   @override
-  test_resolveSymbolicLinksSync_links_existing() {
-    var a_path = provider.convertPath('/test/lib/a.dart');
-    var b_path = provider.convertPath('/test/lib/b.dart');
-
-    provider.newLink(b_path, a_path);
-    provider.newFile(a_path, '');
-
-    var resolved = provider.getFile(b_path).resolveSymbolicLinksSync();
-    expect(resolved.path, a_path);
-  }
-
-  @override
-  test_resolveSymbolicLinksSync_links_notExisting() {
-    var a = provider.convertPath('/test/lib/a.dart');
-    var b = provider.convertPath('/test/lib/b.dart');
-
-    provider.newLink(b, a);
-
-    expect(() {
-      provider.getFile(b).resolveSymbolicLinksSync();
-    }, throwsA(isFileSystemException));
-  }
-
-  @override
-  test_resolveSymbolicLinksSync_noLinks_notExisting() {
-    File file = getFile(exists: false);
-
-    expect(() {
-      file.resolveSymbolicLinksSync();
-    }, throwsA(isFileSystemException));
-  }
-
-  @override
   test_writeAsBytesSync_notExisting() {
     File file = getFile(exists: false);
 
@@ -318,17 +285,6 @@
     var path = provider.convertPath('/');
     expect(provider.getFolder(path).isRoot, isTrue);
   }
-
-  test_resolveSymbolicLinksSync() {
-    var lib = provider.convertPath('/test/lib');
-    var foo = provider.convertPath('/test/lib/foo');
-
-    provider.newLink(foo, lib);
-    provider.newFolder(lib);
-
-    var resolved = provider.getFolder(foo).resolveSymbolicLinksSync();
-    expect(resolved.path, lib);
-  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/file_system/overlay_file_system_test.dart b/pkg/analyzer/test/file_system/overlay_file_system_test.dart
index 0cb1c68..dc0035f 100644
--- a/pkg/analyzer/test/file_system/overlay_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/overlay_file_system_test.dart
@@ -350,9 +350,7 @@
       withOverlay: true,
     );
 
-    expect(() {
-      file.resolveSymbolicLinksSync();
-    }, throwsA(isFileSystemException));
+    expect(file.resolveSymbolicLinksSync(), file);
   }
 
   test_shortName() {
@@ -485,12 +483,46 @@
     expect(() => folder.delete(), throwsA(TypeMatcher<ArgumentError>()));
   }
 
-  test_exists_false() {
+  void test_exists_links_existing() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    baseProvider.newFolder(foo_path);
+    baseProvider.newLink(bar_path, foo_path);
+
+    var bar = provider.getFolder(bar_path);
+    expect(bar.exists, isTrue);
+  }
+
+  void test_exists_links_notExisting() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    baseProvider.newLink(bar_path, foo_path);
+
+    var bar = provider.getFolder(bar_path);
+    expect(bar.exists, isFalse);
+  }
+
+  void test_exists_links_notExisting_withOverlay() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    _file(exists: false, path: '/foo/aaa/a.dart', withOverlay: true);
+    baseProvider.newLink(bar_path, foo_path);
+
+    // We cannot resolve `/bar` to `/foo` using the base provider.
+    // So, we don't know that we should check that `/foo/aaa/a.dart` exists.
+    var bar = provider.getFolder(bar_path);
+    expect(bar.exists, isFalse);
+  }
+
+  test_exists_noLinks_false() {
     Folder folder = _folder(exists: false);
     expect(folder.exists, isFalse);
   }
 
-  test_exists_true() {
+  test_exists_noLinks_true() {
     Folder folder = _folder(exists: true);
     expect(folder.exists, isTrue);
   }
@@ -615,14 +647,61 @@
     fail('Not tested');
   }
 
-  void test_resolveSymbolicLinksSync_noLinks_existingFile() {
-    _resolveSymbolicLinksSync_noLinks(
-        _folder(exists: true, path: '/temp/a/b/test.txt'));
+  void test_resolveSymbolicLinksSync_links_existing() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    baseProvider.newFolder(foo_path);
+    baseProvider.newLink(bar_path, foo_path);
+
+    var foo = provider.getFolder(foo_path);
+    var bar = provider.getFolder(bar_path);
+    expect(bar.resolveSymbolicLinksSync(), foo);
+  }
+
+  void test_resolveSymbolicLinksSync_links_notExisting() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    baseProvider.newLink(bar_path, foo_path);
+
+    expect(() {
+      var bar = provider.getFolder(bar_path);
+      bar.resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
+
+  void test_resolveSymbolicLinksSync_links_notExisting_withOverlay() {
+    var foo_path = baseProvider.convertPath('/foo');
+    var bar_path = baseProvider.convertPath('/bar');
+
+    _file(exists: false, path: '/foo/aaa/a.dart', withOverlay: true);
+    baseProvider.newLink(bar_path, foo_path);
+
+    // We cannot resolve `/bar` to `/foo` using the base provider.
+    // So, we don't know that we should check that `/foo/aaa/a.dart` exists.
+    expect(() {
+      var bar = provider.getFolder(bar_path);
+      bar.resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
+
+  void test_resolveSymbolicLinksSync_noLinks_existing() {
+    var folder = _folder(exists: true, path: '/test');
+    expect(folder.resolveSymbolicLinksSync(), folder);
   }
 
   void test_resolveSymbolicLinksSync_noLinks_notExisting() {
-    _resolveSymbolicLinksSync_noLinks(
-        _folder(exists: false, path: '/temp/a/b/test.txt'));
+    var folder = _folder(exists: false, path: '/test');
+    expect(() {
+      folder.resolveSymbolicLinksSync();
+    }, throwsA(isFileSystemException));
+  }
+
+  void test_resolveSymbolicLinksSync_noLinks_notExisting_withOverlay() {
+    _file(exists: false, path: '/test/aaa/a.dart', withOverlay: true);
+    var folder = _folder(exists: false, path: '/test');
+    expect(folder.resolveSymbolicLinksSync(), folder);
   }
 
   test_shortName() {
@@ -634,16 +713,6 @@
     expect(folder.toUri(), Uri.directory(folder.path));
   }
 
-  void _resolveSymbolicLinksSync_noLinks(Folder folder) {
-    //
-    // On some platforms the path to the temp directory includes a symbolic
-    // link. We remove that from the equation before creating the File in order
-    // to show that the operation works as expected without symbolic links.
-    //
-    folder = baseProvider.getFolder(folder.resolveSymbolicLinksSync().path);
-    expect(folder.resolveSymbolicLinksSync(), folder);
-  }
-
   /// Verify that the [copy] has the same name and content as the [source].
   void _verifyStructure(Folder copy, Folder source) {
     expect(copy.shortName, source.shortName);
diff --git a/pkg/analyzer/test/file_system/physical_file_system_test.dart b/pkg/analyzer/test/file_system/physical_file_system_test.dart
index 48a75fa..9f871dd 100644
--- a/pkg/analyzer/test/file_system/physical_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/physical_file_system_test.dart
@@ -54,7 +54,7 @@
 
   @override
   void createLink({required String path, required String target}) {
-    io.Link(path).createSync(target);
+    io.Link(path).createSync(target, recursive: true);
   }
 
   /// Create the resource provider to be used by the tests. Subclasses can
@@ -125,51 +125,6 @@
   }
 
   @override
-  test_resolveSymbolicLinksSync_links_existing() {
-    String pathA = join(tempPath, defaultFileContent);
-    String pathB = join(pathA, 'b');
-    io.Directory(pathB).createSync(recursive: true);
-    String filePath = join(pathB, 'test.txt');
-    io.File testFile = io.File(filePath);
-    testFile.writeAsStringSync('test');
-
-    String pathC = join(tempPath, 'c');
-    String pathD = join(pathC, 'd');
-    io.Link(pathD).createSync(pathA, recursive: true);
-
-    String pathE = join(tempPath, 'e');
-    String pathF = join(pathE, 'f');
-    io.Link(pathF).createSync(pathC, recursive: true);
-
-    String linkPath = join(tempPath, 'e', 'f', 'd', 'b', 'test.txt');
-    File file = provider.getFile(linkPath);
-
-    expect(file.resolveSymbolicLinksSync().path,
-        testFile.resolveSymbolicLinksSync());
-  }
-
-  @override
-  test_resolveSymbolicLinksSync_links_notExisting() {
-    var a = join(tempPath, 'a.dart');
-    var b = join(tempPath, 'b.dart');
-
-    io.Link(b).createSync(a, recursive: true);
-
-    expect(() {
-      provider.getFile(b).resolveSymbolicLinksSync();
-    }, throwsA(isFileSystemException));
-  }
-
-  @override
-  test_resolveSymbolicLinksSync_noLinks_notExisting() {
-    File file = getFile(exists: false);
-
-    expect(() {
-      file.resolveSymbolicLinksSync();
-    }, throwsA(isFileSystemException));
-  }
-
-  @override
   test_writeAsBytesSync_notExisting() {
     File file = getFile(exists: false);
 
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
index 8455680..4971543 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
@@ -33,7 +33,8 @@
 abstract class FixContributor {
   /// Contribute fixes for the location in the file specified by the given
   /// [request] into the given [collector].
-  Future<void> computeFixes(covariant FixesRequest request, FixCollector collector);
+  Future<void> computeFixes(
+      covariant FixesRequest request, FixCollector collector);
 }
 
 /// The information about a requested set of fixes.
@@ -105,15 +106,9 @@
   /// message `"Create a component named '{0}' in '{1}'"` contains two parameters.
   final String message;
 
-  /// A human-readable description of the changes that will be applied by this
-  /// kind of 'applied together' fix.
-  final String appliedTogetherMessage;
-
   /// Initialize a newly created kind of fix to have the given [id],
-  /// [priority], [message], and optionally [canBeAppliedTogether] and
-  /// [appliedTogetherMessage].
-  const FixKind(this.id, this.priority, this.message,
-      {this.appliedTogetherMessage});
+  /// [priority], and [message].
+  const FixKind(this.id, this.priority, this.message);
 
   @override
   int get hashCode => id.hashCode;
@@ -121,9 +116,6 @@
   @override
   bool operator ==(o) => o is FixKind && o.id == id;
 
-  /// The change can be made with other fixes of this [FixKind].
-  bool canBeAppliedTogether() => appliedTogetherMessage != null;
-
   @override
   String toString() => id;
 }
diff --git a/pkg/compiler/lib/src/serialization/binary_source.dart b/pkg/compiler/lib/src/serialization/binary_source.dart
index 11132b9..92888ad 100644
--- a/pkg/compiler/lib/src/serialization/binary_source.dart
+++ b/pkg/compiler/lib/src/serialization/binary_source.dart
@@ -10,9 +10,12 @@
 class BinarySourceImpl extends AbstractDataSource {
   int _byteOffset = 0;
   final List<int> _bytes;
+  final StringInterner _stringInterner;
 
-  BinarySourceImpl(this._bytes, {bool useDataKinds: false})
-      : super(useDataKinds: useDataKinds);
+  BinarySourceImpl(this._bytes,
+      {bool useDataKinds: false, StringInterner stringInterner})
+      : _stringInterner = stringInterner,
+        super(useDataKinds: useDataKinds);
 
   @override
   void _begin(String tag) {}
@@ -27,7 +30,9 @@
     List<int> bytes = new Uint8List(length);
     bytes.setRange(0, bytes.length, _bytes, _byteOffset);
     _byteOffset += bytes.length;
-    return utf8.decode(bytes);
+    String string = utf8.decode(bytes);
+    if (_stringInterner == null) return string;
+    return _stringInterner.internString(string);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 14fb2f7..e684b95 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -33,6 +33,10 @@
 part 'object_sink.dart';
 part 'object_source.dart';
 
+abstract class StringInterner {
+  String internString(String string);
+}
+
 /// Interface for serialization.
 abstract class DataSink {
   /// The amount of data written to this data sink.
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 4a9efbf..6e5c4c8 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -94,11 +94,21 @@
       options, reporter, environment, abstractValueStrategy, component, source);
 }
 
+class _StringInterner implements ir.StringInterner, StringInterner {
+  Map<String, String> _map = {};
+
+  @override
+  String internString(String string) {
+    return _map[string] ??= string;
+  }
+}
+
 class SerializationTask extends CompilerTask {
   final CompilerOptions _options;
   final DiagnosticReporter _reporter;
   final api.CompilerInput _provider;
   final api.CompilerOutput _outputProvider;
+  final _stringInterner = _StringInterner();
 
   SerializationTask(this._options, this._reporter, this._provider,
       this._outputProvider, Measurer measurer)
@@ -129,7 +139,8 @@
           .readFromUri(_options.entryPoint, inputKind: api.InputKind.binary);
       ir.Component component = new ir.Component();
       // Not using growable lists saves memory.
-      new ir.BinaryBuilder(dillInput.data, useGrowableLists: false)
+      ir.BinaryBuilder(dillInput.data,
+              useGrowableLists: false, stringInterner: _stringInterner)
           .readComponent(component);
       return component;
     });
@@ -181,7 +192,8 @@
       api.Input<List<int>> dataInput = await _provider.readFromUri(
           _options.readClosedWorldUri,
           inputKind: api.InputKind.binary);
-      DataSource source = new BinarySourceImpl(dataInput.data);
+      DataSource source =
+          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
       return deserializeClosedWorldFromSource(_options, _reporter, environment,
           abstractValueStrategy, component, source);
     });
@@ -210,7 +222,8 @@
       _reporter.log('Reading data from ${_options.readDataUri}');
       api.Input<List<int>> dataInput = await _provider
           .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
-      DataSource source = new BinarySourceImpl(dataInput.data);
+      DataSource source =
+          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
       return deserializeGlobalTypeInferenceResultsFromSource(_options,
           _reporter, environment, abstractValueStrategy, component, source);
     });
@@ -225,7 +238,8 @@
       _reporter.log('Reading data from ${_options.readDataUri}');
       api.Input<List<int>> dataInput = await _provider
           .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
-      DataSource source = BinarySourceImpl(dataInput.data);
+      DataSource source =
+          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
       return deserializeGlobalAnalysisFromSource(_options, _reporter,
           environment, abstractValueStrategy, component, closedWorld, source);
     });
@@ -293,7 +307,8 @@
       Uri uri,
       api.Input<List<int>> dataInput,
       Map<MemberEntity, CodegenResult> results) {
-    DataSource source = new BinarySourceImpl(dataInput.data);
+    DataSource source =
+        BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
     backendStrategy.prepareCodegenReader(source);
     Map<MemberEntity, CodegenResult> codegenResults =
         source.readMemberMap((MemberEntity member) {
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 8555cb1..4f9b333 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -100,6 +100,18 @@
       this.libraries, this.componentStartOffset, this.componentFileSize);
 }
 
+/// [StringInterner] allows Strings created from the binary to be shared with
+/// other components.
+///
+/// The [StringInterner] is an optional parameter to [BinaryBuilder], so sharing
+/// should not be required for correctness, and an implementation of
+/// [StringInterner] method may be partial (sometimes not finding an existing
+/// object) or trivial (returning the argument).
+abstract class StringInterner {
+  /// Returns a string with the same contents as [string].
+  String internString(String string);
+}
+
 class BinaryBuilder {
   final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
   final List<LabeledStatement> labelStack = <LabeledStatement>[];
@@ -135,6 +147,10 @@
   /// will not be resolved correctly.
   bool _disableLazyClassReading = false;
 
+  /// [stringInterner] (optional) may be used to allow components to share
+  /// instances of [String] that have the same contents.
+  final StringInterner /*?*/ stringInterner;
+
   /// When creating lists that *might* be growable, use this boolean as the
   /// setting to pass to `growable` so the dill can be loaded in a more compact
   /// manner if the caller knows that the growability isn't needed.
@@ -147,6 +163,7 @@
       bool disableLazyReading = false,
       bool disableLazyClassReading = false,
       bool alwaysCreateNewNamedNodes,
+      this.stringInterner,
       this.useGrowableLists = true})
       : _disableLazyReading = disableLazyReading,
         _disableLazyClassReading = disableLazyReading ||
@@ -225,6 +242,12 @@
   }
 
   String readStringEntry(int numBytes) {
+    String string = _readStringEntry(numBytes);
+    if (stringInterner == null) return string;
+    return stringInterner.internString(string);
+  }
+
+  String _readStringEntry(int numBytes) {
     int start = _byteOffset;
     int end = start + numBytes;
     _byteOffset = end;
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 2616a66..a42852b 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -4785,18 +4785,22 @@
                                                         bool opt) const {
   ASSERT((from_representation() == kUnboxedInt32) ||
          (from_representation() == kUnboxedUint32));
+#if !defined(DART_COMPRESSED_POINTERS)
+  // ValueFitsSmi() may be overly conservative and false because we only
+  // perform range analysis during optimized compilation.
+  const bool kMayAllocateMint = false;
+#else
+  const bool kMayAllocateMint = !ValueFitsSmi();
+#endif
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
+  const intptr_t kNumTemps = kMayAllocateMint ? 1 : 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps,
-                      ValueFitsSmi() ? LocationSummary::kNoCall
-                                     : LocationSummary::kCallOnSlowPath);
-  const bool needs_writable_input =
-      ValueFitsSmi() || (from_representation() == kUnboxedUint32) || true;
-  summary->set_in(0, needs_writable_input ? Location::WritableRegister()
-                                          : Location::RequiresRegister());
+                      kMayAllocateMint ? LocationSummary::kCallOnSlowPath
+                                       : LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
-  if (!ValueFitsSmi()) {
+  if (kMayAllocateMint) {
     summary->set_temp(0, Location::RequiresRegister());
   }
   return summary;
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index b187eb6..9372d86 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -1270,7 +1270,7 @@
   ASSERT(thread->IsMutatorThread());
   ASSERT(!thread->IsAtSafepoint());
 
-  MonitorLocker ml_done(&done_monitor_);
+  SafepointMonitorLocker ml_done(&done_monitor_);
   disabled_depth_--;
   if (disabled_depth_ < 0) {
     FATAL("Mismatched number of calls to BackgroundCompiler::Enable/Disable.");
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 230bde3..f8c40d1 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -26,8 +26,6 @@
 #define OFFSET_OF_FROM(obj)                                                    \
   obj.ptr()->from() - reinterpret_cast<ObjectPtr*>(obj.ptr()->untag())
 
-// TODO(18854): Need to assert No GC can happen here, even though
-// allocations may happen.
 #define READ_OBJECT_FIELDS(object, from, to, as_reference)                     \
   intptr_t num_flds = (to) - (from);                                           \
   for (intptr_t i = 0; i <= num_flds; i++) {                                   \
diff --git a/tests/corelib/unsigned_shift_test.dart b/tests/corelib/unsigned_shift_test.dart
index fd52016..c190ff3 100644
--- a/tests/corelib/unsigned_shift_test.dart
+++ b/tests/corelib/unsigned_shift_test.dart
@@ -30,9 +30,17 @@
     testShift(0x55555555, i);
     testShift(0xaaaaaaaa, i);
     testShift(0x80000000, i);
+    //         .   .   .   .
+    testShift(0x7fffffffffff, i);
+    testShift(0xffffffffffff, i);
     //         .   .   .   .   .
-    testShift(0x7fffffffffffffff, i);
-    testShift(0xffffffffffffffff, i);
+    testShift(0x7ffffffffffff000, i);
+    testShift(0xfffffffffffff000, i);
+    // Construct the values below to get 'all ones' values on the VM without a
+    // compile-time error for roundned literals on the web. The arithmetic
+    // produces rounded values on the web, so they are effectively testing zero.
+    testShift(0x7ffffffffffff000 + 0xfff, i);
+    testShift(0xfffffffffffff000 + 0xfff, i);
   }
 
   // JavaScript numbers may consider Infinity as an integer.
diff --git a/tests/corelib_2/unsigned_shift_test.dart b/tests/corelib_2/unsigned_shift_test.dart
index fd52016..c190ff3 100644
--- a/tests/corelib_2/unsigned_shift_test.dart
+++ b/tests/corelib_2/unsigned_shift_test.dart
@@ -30,9 +30,17 @@
     testShift(0x55555555, i);
     testShift(0xaaaaaaaa, i);
     testShift(0x80000000, i);
+    //         .   .   .   .
+    testShift(0x7fffffffffff, i);
+    testShift(0xffffffffffff, i);
     //         .   .   .   .   .
-    testShift(0x7fffffffffffffff, i);
-    testShift(0xffffffffffffffff, i);
+    testShift(0x7ffffffffffff000, i);
+    testShift(0xfffffffffffff000, i);
+    // Construct the values below to get 'all ones' values on the VM without a
+    // compile-time error for roundned literals on the web. The arithmetic
+    // produces rounded values on the web, so they are effectively testing zero.
+    testShift(0x7ffffffffffff000 + 0xfff, i);
+    testShift(0xfffffffffffff000 + 0xfff, i);
   }
 
   // JavaScript numbers may consider Infinity as an integer.
diff --git a/tools/VERSION b/tools/VERSION
index d068d72..147ceb0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 75
+PRERELEASE 76
 PRERELEASE_PATCH 0
\ No newline at end of file