Version 2.12.0-256.0.dev

Merge commit 'ba0159688e1ae9cd4b10513d4f4647009f51dfe7' into 'dev'
diff --git a/DEPS b/DEPS
index 2ec4a05..32a1981 100644
--- a/DEPS
+++ b/DEPS
@@ -133,7 +133,7 @@
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
   "protobuf_rev": "0d03fd588df69e9863e2a2efc0059dee8f18d5b2",
-  "pub_rev": "267fb68add3b85a0f6698bf5ae2648f1a1df515b",
+  "pub_rev": "0402c467547daa5886352cb315338ae54552d21c",
   "pub_semver_rev": "10569a1e867e909cf5db201f73118020453e5db8",
   "resource_rev": "6b79867d0becf5395e5819a75720963b8298e9a7",
   "root_certificates_rev": "7e5ec82c99677a2e5b95ce296c4d68b0d3378ed8",
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 3bf7d05..3d33316 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.32.2
+  1.32.3
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -236,13 +236,20 @@
   ignoring the item or treating it with some default/fallback handling.
 </p>
 <h3>Changelog</h3>
+<h4>1.32.3</h4>
+<ul>
+  <li>Removed the experimental <tt>completion.listTokenDetails</tt> request and
+    the associated data types.</li>
+</ul>
 <h4>1.32.2</h4>
 <ul>
-  <li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of comments.</li>
+  <li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of
+    comments.</li>
 </ul>
 <h4>1.32.1</h4>
 <ul>
-  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt>.</li>
+  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name
+    completions in <tt>pubspec.yaml</tt>.</li>
 </ul>
 <h3>Domains</h3>
 <p>
@@ -1497,7 +1504,6 @@
   
   
   
-  
 <h3>Requests</h3><dl><dt class="request"><a name="request_completion.getSuggestions">completion.getSuggestions</a></dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "completion.getSuggestions"
@@ -3056,7 +3062,6 @@
   
   
   
-  
 <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
     <p>
       A directive to begin overlaying the contents of a file. The supplied
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 68ea10f..ff997f0 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.32.2';
+const String PROTOCOL_VERSION = '1.32.3';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -145,9 +145,6 @@
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
-const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS =
-    'completion.listTokenDetails';
-const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS_FILE = 'file';
 const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
     'completion.registerLibraryPaths';
 const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
@@ -159,7 +156,6 @@
 const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
 const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
     'completion';
-const String COMPLETION_RESPONSE_LIST_TOKEN_DETAILS_TOKENS = 'tokens';
 const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
 const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
 const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 6d05e71..1ae7337 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -5886,168 +5886,6 @@
   }
 }
 
-/// completion.listTokenDetails params
-///
-/// {
-///   "file": FilePath
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class CompletionListTokenDetailsParams implements RequestParams {
-  String _file;
-
-  /// The path to the file from which tokens should be returned.
-  String get file => _file;
-
-  /// The path to the file from which tokens should be returned.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  CompletionListTokenDetailsParams(String file) {
-    this.file = file;
-  }
-
-  factory CompletionListTokenDetailsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      String file;
-      if (json.containsKey('file')) {
-        file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'file');
-      }
-      return CompletionListTokenDetailsParams(file);
-    } else {
-      throw jsonDecoder.mismatch(
-          jsonPath, 'completion.listTokenDetails params', json);
-    }
-  }
-
-  factory CompletionListTokenDetailsParams.fromRequest(Request request) {
-    return CompletionListTokenDetailsParams.fromJson(
-        RequestDecoder(request), 'params', request.params);
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['file'] = file;
-    return result;
-  }
-
-  @override
-  Request toRequest(String id) {
-    return Request(id, 'completion.listTokenDetails', toJson());
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is CompletionListTokenDetailsParams) {
-      return file == other.file;
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, file.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
-/// completion.listTokenDetails result
-///
-/// {
-///   "tokens": List<TokenDetails>
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class CompletionListTokenDetailsResult implements ResponseResult {
-  List<TokenDetails> _tokens;
-
-  /// A list of the file's scanned tokens including analysis information about
-  /// them.
-  List<TokenDetails> get tokens => _tokens;
-
-  /// A list of the file's scanned tokens including analysis information about
-  /// them.
-  set tokens(List<TokenDetails> value) {
-    assert(value != null);
-    _tokens = value;
-  }
-
-  CompletionListTokenDetailsResult(List<TokenDetails> tokens) {
-    this.tokens = tokens;
-  }
-
-  factory CompletionListTokenDetailsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      List<TokenDetails> tokens;
-      if (json.containsKey('tokens')) {
-        tokens = jsonDecoder.decodeList(
-            jsonPath + '.tokens',
-            json['tokens'],
-            (String jsonPath, Object json) =>
-                TokenDetails.fromJson(jsonDecoder, jsonPath, json));
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'tokens');
-      }
-      return CompletionListTokenDetailsResult(tokens);
-    } else {
-      throw jsonDecoder.mismatch(
-          jsonPath, 'completion.listTokenDetails result', json);
-    }
-  }
-
-  factory CompletionListTokenDetailsResult.fromResponse(Response response) {
-    return CompletionListTokenDetailsResult.fromJson(
-        ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
-        'result',
-        response.result);
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['tokens'] =
-        tokens.map((TokenDetails value) => value.toJson()).toList();
-    return result;
-  }
-
-  @override
-  Response toResponse(String id) {
-    return Response(id, result: toJson());
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is CompletionListTokenDetailsResult) {
-      return listEqual(
-          tokens, other.tokens, (TokenDetails a, TokenDetails b) => a == b);
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
 /// completion.registerLibraryPaths params
 ///
 /// {
@@ -21345,151 +21183,6 @@
   }
 }
 
-/// TokenDetails
-///
-/// {
-///   "lexeme": String
-///   "type": optional String
-///   "validElementKinds": optional List<String>
-///   "offset": int
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class TokenDetails implements HasToJson {
-  String _lexeme;
-
-  String _type;
-
-  List<String> _validElementKinds;
-
-  int _offset;
-
-  /// The token's lexeme.
-  String get lexeme => _lexeme;
-
-  /// The token's lexeme.
-  set lexeme(String value) {
-    assert(value != null);
-    _lexeme = value;
-  }
-
-  /// A unique id for the type of the identifier. Omitted if the token is not
-  /// an identifier in a reference position.
-  String get type => _type;
-
-  /// A unique id for the type of the identifier. Omitted if the token is not
-  /// an identifier in a reference position.
-  set type(String value) {
-    _type = value;
-  }
-
-  /// An indication of whether this token is in a declaration or reference
-  /// position. (If no other purpose is found for this field then it should be
-  /// renamed and converted to a boolean value.) Omitted if the token is not an
-  /// identifier.
-  List<String> get validElementKinds => _validElementKinds;
-
-  /// An indication of whether this token is in a declaration or reference
-  /// position. (If no other purpose is found for this field then it should be
-  /// renamed and converted to a boolean value.) Omitted if the token is not an
-  /// identifier.
-  set validElementKinds(List<String> value) {
-    _validElementKinds = value;
-  }
-
-  /// The offset of the first character of the token in the file which it
-  /// originated from.
-  int get offset => _offset;
-
-  /// The offset of the first character of the token in the file which it
-  /// originated from.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  TokenDetails(String lexeme, int offset,
-      {String type, List<String> validElementKinds}) {
-    this.lexeme = lexeme;
-    this.type = type;
-    this.validElementKinds = validElementKinds;
-    this.offset = offset;
-  }
-
-  factory TokenDetails.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      String lexeme;
-      if (json.containsKey('lexeme')) {
-        lexeme = jsonDecoder.decodeString(jsonPath + '.lexeme', json['lexeme']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'lexeme');
-      }
-      String type;
-      if (json.containsKey('type')) {
-        type = jsonDecoder.decodeString(jsonPath + '.type', json['type']);
-      }
-      List<String> validElementKinds;
-      if (json.containsKey('validElementKinds')) {
-        validElementKinds = jsonDecoder.decodeList(
-            jsonPath + '.validElementKinds',
-            json['validElementKinds'],
-            jsonDecoder.decodeString);
-      }
-      int offset;
-      if (json.containsKey('offset')) {
-        offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'offset');
-      }
-      return TokenDetails(lexeme, offset,
-          type: type, validElementKinds: validElementKinds);
-    } else {
-      throw jsonDecoder.mismatch(jsonPath, 'TokenDetails', json);
-    }
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['lexeme'] = lexeme;
-    if (type != null) {
-      result['type'] = type;
-    }
-    if (validElementKinds != null) {
-      result['validElementKinds'] = validElementKinds;
-    }
-    result['offset'] = offset;
-    return result;
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is TokenDetails) {
-      return lexeme == other.lexeme &&
-          type == other.type &&
-          listEqual(validElementKinds, other.validElementKinds,
-              (String a, String b) => a == b) &&
-          offset == other.offset;
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
-    hash = JenkinsSmiHash.combine(hash, type.hashCode);
-    hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
-    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
 /// TypeHierarchyItem
 ///
 /// {
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 0aafdda..d649879 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/services/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/token_details/token_detail_builder.dart';
 import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
 import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
 import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
@@ -251,9 +250,6 @@
       } else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
         processRequest(request);
         return Response.DELAYED_RESPONSE;
-      } else if (requestName == COMPLETION_REQUEST_LIST_TOKEN_DETAILS) {
-        listTokenDetails(request);
-        return Response.DELAYED_RESPONSE;
       } else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
         return setSubscriptions(request);
       }
@@ -273,40 +269,6 @@
     }
   }
 
-  /// Process a `completion.listTokenDetails` request.
-  Future<void> listTokenDetails(Request request) async {
-    var params = CompletionListTokenDetailsParams.fromRequest(request);
-
-    var file = params.file;
-    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
-      return;
-    }
-
-    var analysisDriver = server.getAnalysisDriver(file);
-    if (analysisDriver == null) {
-      server.sendResponse(Response.invalidParameter(
-        request,
-        'file',
-        'File is not being analyzed: $file',
-      ));
-    }
-    var session = analysisDriver.currentSession;
-    var result = await session.getResolvedUnit(file);
-    if (result.state != ResultState.VALID) {
-      server.sendResponse(Response.invalidParameter(
-        request,
-        'file',
-        'File does not exist or cannot be read: $file',
-      ));
-    }
-
-    var builder = TokenDetailBuilder();
-    builder.visitNode(result.unit);
-    server.sendResponse(
-      CompletionListTokenDetailsResult(builder.details).toResponse(request.id),
-    );
-  }
-
   /// Process a `completion.getSuggestions` request.
   Future<void> processRequest(Request request) async {
     performance = CompletionPerformance();
diff --git a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
deleted file mode 100644
index 44c3ad9..0000000
--- a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-
-/// An object used to build the details for each token in the code being
-/// analyzed.
-class TokenDetailBuilder {
-  /// The list of details that were built.
-  List<TokenDetails> details = [];
-
-  /// Initialize a newly created builder.
-  TokenDetailBuilder();
-
-  /// Visit a [node] in the AST structure to build details for all of the tokens
-  /// contained by that node.
-  void visitNode(AstNode node) {
-    for (var entity in node.childEntities) {
-      if (entity is Token) {
-        _createDetails(entity, null, null);
-      } else if (entity is SimpleIdentifier) {
-        String type;
-        var typeNameNode = _getTypeName(entity);
-        if (typeNameNode != null) {
-          var typeStr = _typeStr(typeNameNode.type);
-          type = 'dart:core;Type<$typeStr>';
-        } else if (entity.staticElement is ClassElement) {
-          type = 'Type';
-        } else if (entity.inDeclarationContext()) {
-          var element = entity.staticElement;
-          if (element is FunctionElement) {
-            type = _typeStr(element.type);
-          } else if (element is MethodElement) {
-            type = _typeStr(element.type);
-          } else if (element is VariableElement) {
-            type = _typeStr(element.type);
-          }
-        } else {
-          type = _typeStr(entity.staticType);
-        }
-        var kinds = <String>[];
-        if (entity.inDeclarationContext()) {
-          kinds.add('declaration');
-        } else {
-          kinds.add('reference');
-        }
-        _createDetails(entity.token, type, kinds);
-      } else if (entity is BooleanLiteral) {
-        _createDetails(entity.literal, _typeStr(entity.staticType), null);
-      } else if (entity is DoubleLiteral) {
-        _createDetails(entity.literal, _typeStr(entity.staticType), null);
-      } else if (entity is IntegerLiteral) {
-        _createDetails(entity.literal, _typeStr(entity.staticType), null);
-      } else if (entity is SimpleStringLiteral) {
-        _createDetails(entity.literal, _typeStr(entity.staticType), null);
-      } else if (entity is Comment) {
-        // Ignore comments and the references within them.
-      } else if (entity is AstNode) {
-        visitNode(entity);
-      }
-    }
-  }
-
-  /// Create the details for a single [token], using the given list of [kinds].
-  void _createDetails(Token token, String type, List<String> kinds) {
-    details.add(TokenDetails(token.lexeme, token.offset,
-        type: type, validElementKinds: kinds));
-  }
-
-  /// Return the [TypeName] with the [identifier].
-  TypeName _getTypeName(SimpleIdentifier identifier) {
-    var parent = identifier.parent;
-    if (parent is TypeName && identifier == parent.name) {
-      return parent;
-    } else if (parent is PrefixedIdentifier &&
-        parent.identifier == identifier) {
-      var parent2 = parent.parent;
-      if (parent2 is TypeName && parent == parent2.name) {
-        return parent2;
-      }
-    }
-    return null;
-  }
-
-  /// Return a unique identifier for the [type].
-  String _typeStr(DartType type) {
-    var buffer = StringBuffer();
-    _writeType(buffer, type);
-    return buffer.toString();
-  }
-
-  /// Return a unique identifier for the type of the given [expression].
-  void _writeType(StringBuffer buffer, DartType type) {
-    if (type == null) {
-      // This should never happen if the AST has been resolved.
-      buffer.write('dynamic');
-    } else if (type is FunctionType) {
-      _writeType(buffer, type.returnType);
-      buffer.write(' Function(');
-      var first = true;
-      for (var parameter in type.parameters) {
-        if (first) {
-          first = false;
-        } else {
-          buffer.write(', ');
-        }
-        _writeType(buffer, parameter.type);
-      }
-      buffer.write(')');
-    } else if (type is InterfaceType) {
-      Element element = type.element;
-      if (element == null || element.isSynthetic) {
-        assert(false, 'untested branch may print nullable types wrong');
-        // TODO: test this, use the the library's nullability (not tracked yet).
-        buffer.write(type.getDisplayString(withNullability: false));
-      } else {
-//        String uri = element.library.source.uri.toString();
-        var name = element.name;
-        if (element is ClassMemberElement) {
-          var className = element.enclosingElement.name;
-          // TODO(brianwilkerson) Figure out why the uri is a file: URI when it
-          //  ought to be a package: URI and restore the code below to include
-          //  the URI in the string.
-//          buffer.write('$uri;$className;$name');
-          buffer.write('$className;$name');
-        } else {
-//          buffer.write('$uri;$name');
-          buffer.write('$name');
-        }
-      }
-    } else {
-      // Handle `void` and `dynamic`. Nullability doesn't affect this.
-      assert(type.getDisplayString(withNullability: false) ==
-          type.getDisplayString(withNullability: true));
-      buffer.write(type.getDisplayString(withNullability: false));
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
index b477af8..8446ae0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
@@ -37,7 +37,16 @@
         transformSets.add(transformSet);
       }
     }
-    // TODO(brianwilkerson) Consider looking for a data file in the SDK.
+    var sdkRoot = library.session.analysisContext.sdkRoot;
+    if (sdkRoot != null) {
+      var file = sdkRoot.getChildAssumingFile('lib/_internal/$dataFileName');
+      if (file.exists) {
+        var transformSet = _loadTransformSet(file);
+        if (transformSet != null) {
+          transformSets.add(transformSet);
+        }
+      }
+    }
     return transformSets;
   }
 
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 9676017..25a3347 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -271,7 +271,7 @@
       enableIndex: true,
       includedPaths: collectionIncludedPaths.map(convertPath).toList(),
       resourceProvider: resourceProvider,
-      sdkPath: convertPath('/sdk'),
+      sdkPath: convertPath(sdkRoot),
     );
 
     verifyCreatedCollection();
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 2221945..4cc0967 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -7,10 +7,10 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 
-import 'domain_completion_test.dart';
+import 'domain_completion_util.dart';
 
 /// A base class for classes containing completion tests.
-class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
+class CompletionTestCase extends AbstractCompletionDomainTest {
   static const String CURSOR_MARKER = '!';
 
   List get suggestedCompletions => suggestions
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index e72baca..3d49664 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -19,7 +19,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
-    defineReflectiveTests(CompletionDomainHandlerListTokenDetailsTest);
   });
 }
 
@@ -778,419 +777,6 @@
   }
 }
 
-@reflectiveTest
-class CompletionDomainHandlerListTokenDetailsTest
-    extends AbstractCompletionDomainTest {
-  String testFileUri;
-
-  Future<void> expectTokens(String content, List<TokenDetails> expected) async {
-    newFile(testFile, content: content);
-    var request = CompletionListTokenDetailsParams(testFile).toRequest('0');
-    var response = await waitResponse(request);
-    List<Map<String, dynamic>> tokens = response.result['tokens'];
-    _compareTokens(tokens, expected);
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    testFileUri = toUriStr(testFile);
-  }
-
-  Future<void> test_classDeclaration() async {
-    await expectTokens('''
-class A {}
-class B extends A {}
-class C implements B {}
-class D with C {}
-''', [
-      token('class', 0, null, null),
-      token('A', 6, 'Type',
-          ['declaration']), //token('A', 6, 'dart:core;Type', ['declaration']),
-      token('{', 8, null, null),
-      token('}', 9, null, null),
-      token('class', 11, null, null),
-      token('B', 17, 'Type',
-          ['declaration']), //token('B', 17, 'dart:core;Type', ['declaration']),
-      token('extends', 19, null, null),
-      token('A', 27, 'dart:core;Type<A>', [
-        'reference'
-      ]), //token('A', 27, 'dart:core;Type<$testFileUri;A>', ['reference']),
-      token('{', 29, null, null),
-      token('}', 30, null, null),
-      token('class', 32, null, null),
-      token('C', 38, 'Type',
-          ['declaration']), //token('C', 38, 'dart:core;Type', ['declaration']),
-      token('implements', 40, null, null),
-      token('B', 51, 'dart:core;Type<B>', [
-        'reference'
-      ]), //token('B', 51, 'dart:core;Type<$testFileUri;B>', ['reference']),
-      token('{', 53, null, null),
-      token('}', 54, null, null),
-      token('class', 56, null, null),
-      token('D', 62, 'Type',
-          ['declaration']), //token('D', 62, 'dart:core;Type', ['declaration']),
-      token('with', 64, null, null),
-      token('C', 69, 'dart:core;Type<C>', [
-        'reference'
-      ]), //token('C', 69, 'dart:core;Type<$testFileUri;C>', ['reference']),
-      token('{', 71, null, null),
-      token('}', 72, null, null),
-    ]);
-  }
-
-  Future<void> test_genericType() async {
-    await expectTokens('''
-List<int> x = null;
-''', [
-      token('List', 0, 'dart:core;Type<List>', [
-        'reference'
-      ]), //token('List', 0, 'dart:core;Type<dart:core;List>', ['reference']),
-      token('<', 4, null, null),
-      token('int', 5, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 5, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('>', 8, null, null),
-      token('x', 10, 'List',
-          ['declaration']), //token('x', 10, 'dart:core;List', ['declaration']),
-      token('=', 12, null, null),
-      token('null', 14, null, null),
-      token(';', 18, null, null),
-    ]);
-  }
-
-  Future<void> test_getterInvocation() async {
-    await expectTokens('''
-var x = 'a'.length;
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'int',
-          ['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
-      token('=', 6, null, null),
-      token("'a'", 8, 'String',
-          null), //token("'a'", 8, 'dart:core;String', null),
-      token('.', 11, null, null),
-      token('length', 12, 'int',
-          ['reference']), //token('length', 12, 'dart:core;int', ['reference']),
-      token(';', 18, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_bool() async {
-    await expectTokens('''
-var x = true;
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'bool',
-          ['declaration']), //token('x', 4, 'dart:core;bool', ['declaration']),
-      token('=', 6, null, null),
-      token(
-          'true', 8, 'bool', null), //token('true', 8, 'dart:core;bool', null),
-      token(';', 12, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_double() async {
-    await expectTokens('''
-var x = 3.4;
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'double', [
-        'declaration'
-      ]), //token('x', 4, 'dart:core;double', ['declaration']),
-      token('=', 6, null, null),
-      token('3.4', 8, 'double',
-          null), //token('3.4', 8, 'dart:core;double', null),
-      token(';', 11, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_int() async {
-    await expectTokens('''
-var x = 7;
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'int',
-          ['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
-      token('=', 6, null, null),
-      token('7', 8, 'int', null), //token('7', 8, 'dart:core;int', null),
-      token(';', 9, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_list() async {
-    await expectTokens('''
-var x = <int>[];
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'List',
-          ['declaration']), //token('x', 4, 'dart:core;List', ['declaration']),
-      token('=', 6, null, null),
-      token('<', 8, null, null),
-      token('int', 9, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('>', 12, null, null),
-      token('[', 13, null, null),
-      token(']', 14, null, null),
-      token(';', 15, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_map() async {
-    await expectTokens('''
-var x = <int, int>{};
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'Map',
-          ['declaration']), //token('x', 4, 'dart:core;Map', ['declaration']),
-      token('=', 6, null, null),
-      token('<', 8, null, null),
-      token('int', 9, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
-//      token(',', null, null),
-      token('int', 14, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token("int", 14, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('>', 17, null, null),
-      token('{', 18, null, null),
-      token('}', 19, null, null),
-      token(';', 20, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_null() async {
-    await expectTokens('''
-var x = null;
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'dynamic', ['declaration']),
-      token('=', 6, null, null),
-      token('null', 8, null, null),
-      token(';', 12, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_set() async {
-    await expectTokens('''
-var x = <int>{};
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'Set',
-          ['declaration']), //token('x', 4, 'dart:core;Set', ['declaration']),
-      token('=', 6, null, null),
-      token('<', 8, null, null),
-      token('int', 9, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token("int", 9, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('>', 12, null, null),
-      token('{', 13, null, null),
-      token('}', 14, null, null),
-      token(';', 15, null, null),
-    ]);
-  }
-
-  Future<void> test_literal_string() async {
-    await expectTokens('''
-var x = 'a';
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'String', [
-        'declaration'
-      ]), //token('x', 4, 'dart:core;String', ['declaration']),
-      token('=', 6, null, null),
-      token("'a'", 8, 'String',
-          null), //token("'a'", 8, 'dart:core;String', null),
-      token(';', 11, null, null),
-    ]);
-  }
-
-  Future<void> test_methodDeclaration() async {
-    await expectTokens('''
-class A {
-  String c(int x, int y) {}
-}
-''', [
-      token('class', 0, null, null),
-      token('A', 6, 'Type', ['declaration']),
-      //token('A', 6, 'dart:core;Type', ['declaration']),
-      token('{', 8, null, null),
-      token('String', 12, 'dart:core;Type<String>', ['reference']),
-      //token('String', 12, 'dart:core;Type<dart:core;String>', ['reference']),
-      token('c', 19, 'String Function(int, int)',
-          //'dart:core;String Function(dart:core;int, dart:core;int)',
-          ['declaration']),
-      token('(', 20, null, null),
-      token('int', 21, 'dart:core;Type<int>', ['reference']),
-      //token('int', 21, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('x', 25, 'int', ['declaration']),
-      //token('x', 25, 'dart:core;int', ['declaration']),
-//      token(',', null, null),
-      token('int', 28, 'dart:core;Type<int>', ['reference']),
-      //token('int', 28, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('y', 32, 'int', ['declaration']),
-      //token('y', 32, 'dart:core;int', ['declaration']),
-      token(')', 33, null, null),
-      token('{', 35, null, null),
-      token('}', 36, null, null),
-      token('}', 38, null, null),
-    ]);
-  }
-
-  Future<void> test_methodInvocation() async {
-    await expectTokens('''
-var x = 'radar'.indexOf('r', 1);
-''', [
-      token('var', 0, null, null),
-      token('x', 4, 'int',
-          ['declaration']), //token('x', 4, 'dart:core;int', ['declaration']),
-      token('=', 6, null, null),
-      token("'radar'", 8, 'String',
-          null), //token("'radar'", 8, 'dart:core;String', null),
-      token('.', 15, null, null),
-      token('indexOf', 16, 'int Function(Pattern, int)',
-          //'dart:core;int Function(dart:core;Pattern, dart:core;int)',
-          ['reference']),
-      token('(', 23, null, null),
-      token("'r'", 24, 'String',
-          null), //token("'r'", 24, 'dart:core;String', null),
-//      token(',', null, null),
-      token('1', 29, 'int', null), //token('1', 29, 'dart:core;int', null),
-      token(')', 30, null, null),
-      token(';', 31, null, null),
-    ]);
-  }
-
-  Future<void> test_mixinDeclaration() async {
-    await expectTokens('''
-class A {}
-class B {}
-mixin D on A implements B {}
-''', [
-      token('class', 0, null, null),
-      token('A', 6, 'Type',
-          ['declaration']), //token('A', 6, 'dart:core;Type', ['declaration']),
-      token('{', 8, null, null),
-      token('}', 9, null, null),
-      token('class', 11, null, null),
-      token('B', 17, 'Type',
-          ['declaration']), //token('B', 17, 'dart:core;Type', ['declaration']),
-      token('{', 19, null, null),
-      token('}', 20, null, null),
-      token('mixin', 22, null, null),
-      token('D', 28, 'Type',
-          ['declaration']), //token('D', 28, 'dart:core;Type', ['declaration']),
-      token('on', 30, null, null),
-      token('A', 33, 'dart:core;Type<A>', [
-        'reference'
-      ]), //token('A', 33, 'dart:core;Type<$testFileUri;A>', ['reference']),
-      token('implements', 35, null, null),
-      token('B', 46, 'dart:core;Type<B>', [
-        'reference'
-      ]), //token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
-      token('{', 48, null, null),
-      token('}', 49, null, null),
-    ]);
-  }
-
-  Future<void> test_parameterReference() async {
-    await expectTokens('''
-int f(int p) {
-  return p;
-}
-''', [
-      token('int', 0, 'dart:core;Type<int>', ['reference']),
-      //token('int', 0, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('f', 4, 'int Function(int)', ['declaration']),
-      //token('f', 4, 'dart:core;int Function(dart:core;int)', ['declaration']),
-      token('(', 5, null, null),
-      token('int', 6, 'dart:core;Type<int>', ['reference']),
-      //token('int', 6, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('p', 10, 'int', ['declaration']),
-      //token('p', 10, 'dart:core;int', ['declaration']),
-      token(')', 11, null, null),
-      token('{', 13, null, null),
-      token('return', 17, null, null),
-      token('p', 24, 'int', ['reference']),
-      //token('p', 24, 'dart:core;int', ['reference']),
-      token(';', 25, null, null),
-      token('}', 27, null, null),
-    ]);
-  }
-
-  Future<void> test_topLevelVariable_withDocComment() async {
-    await expectTokens('''
-/// Doc comment [x] with reference.
-int x;
-''', [
-      token('int', 36, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 36, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('x', 40, 'int',
-          ['declaration']), //token('x', 40, 'dart:core;int', ['declaration']),
-      token(';', 41, null, null),
-    ]);
-  }
-
-  TokenDetails token(
-      String lexeme, int offset, String type, List<String> kinds) {
-    return TokenDetails(lexeme, offset, type: type, validElementKinds: kinds);
-  }
-
-  void _compareTokens(List<Map<String, dynamic>> actualTokens,
-      List<TokenDetails> expectedTokens) {
-    var length = expectedTokens.length;
-    expect(actualTokens, hasLength(length));
-    var errors = <String>[];
-    for (var i = 0; i < length; i++) {
-      var actual = actualTokens[i];
-      var expected = expectedTokens[i];
-      if (actual['lexeme'] != expected.lexeme) {
-        errors.add('Lexeme at $i: '
-            'expected "${expected.lexeme}", '
-            'actual "${actual['lexeme']}"');
-      }
-      if (actual['offset'] != expected.offset) {
-        errors.add('Offset at $i: ("${expected.lexeme}"): '
-            'expected "${expected.offset}", '
-            'actual "${actual['offset']}"');
-      }
-      if (actual['type'] != expected.type) {
-        errors.add('Type at $i ("${expected.lexeme}"): '
-            'expected "${expected.type}", '
-            'actual "${actual['type']}"');
-      }
-      if (_differentKinds(
-          actual['validElementKinds'], expected.validElementKinds)) {
-        errors.add('Kinds at $i ("${expected.lexeme}"): '
-            'expected "${expected.validElementKinds}", '
-            'actual "${actual['validElementKinds']}"');
-      }
-    }
-    expect(errors, isEmpty);
-  }
-
-  /// Return `true` if the two lists of kinds are different.
-  bool _differentKinds(List<String> actual, List<String> expected) {
-    if (actual == null) {
-      return expected != null;
-    } else if (expected == null) {
-      return true;
-    }
-    var expectedLength = expected.length;
-    if (actual.length != expectedLength) {
-      return true;
-    }
-    for (var i = 0; i < expectedLength; i++) {
-      if (actual[i] != expected[i]) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
 class MockRelevancySorter implements DartContributionSorter {
   bool enabled = true;
 
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 7950e43..21cf0bc 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -13,7 +13,6 @@
 import 'refactoring_test.dart' as refactoring;
 import 'sort_members_test.dart' as sort_members;
 import 'statement_completion_test.dart' as statement_completion;
-import 'token_details_test.dart' as token_details;
 
 void main() {
   defineReflectiveSuite(() {
@@ -26,6 +25,5 @@
     refactoring.main();
     sort_members.main();
     statement_completion.main();
-    token_details.main();
   }, name: 'edit');
 }
diff --git a/pkg/analysis_server/test/edit/token_details_test.dart b/pkg/analysis_server/test/edit/token_details_test.dart
deleted file mode 100644
index 0516889..0000000
--- a/pkg/analysis_server/test/edit/token_details_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/domain_completion.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CompletionListTokenDetailsTest);
-  });
-}
-
-@reflectiveTest
-class CompletionListTokenDetailsTest extends AbstractAnalysisTest {
-  CompletionDomainHandler completionHandler;
-
-  Future<CompletionListTokenDetailsResult> getTokenDetails() async {
-    var params = CompletionListTokenDetailsParams(testFile);
-    await completionHandler.listTokenDetails(params.toRequest('0'));
-    var response = await serverChannel.responseController.stream.first;
-    return CompletionListTokenDetailsResult.fromResponse(response);
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    completionHandler = CompletionDomainHandler(server);
-  }
-
-  Future<void> test_packageUri() async {
-    newFile('/project/.packages', content: '''
-project:lib/
-''');
-    newFile('/project/lib/c.dart', content: '''
-class C {}
-''');
-    addTestFile('''
-import 'package:project/c.dart';
-
-C c;
-''');
-    createProject();
-    var result = await getTokenDetails();
-    var tokens = result.tokens;
-    expect(tokens, hasLength(6));
-  }
-}
diff --git a/pkg/analysis_server/test/integration/completion/list_token_details_test.dart b/pkg/analysis_server/test/integration/completion/list_token_details_test.dart
deleted file mode 100644
index 227fc83..0000000
--- a/pkg/analysis_server/test/integration/completion/list_token_details_test.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../support/integration_tests.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ListTokenDetailsTest);
-  });
-}
-
-@reflectiveTest
-class ListTokenDetailsTest extends AbstractAnalysisServerIntegrationTest {
-  String testPackagePath;
-
-  @override
-  Future setUp() async {
-    await super.setUp();
-    testPackagePath = path.join(sourceDirectory.path, 'test_package');
-  }
-
-  @override
-  Future standardAnalysisSetup({bool subscribeStatus = true}) {
-    var futures = <Future>[];
-    if (subscribeStatus) {
-      futures.add(sendServerSetSubscriptions([ServerService.STATUS]));
-    }
-    futures.add(sendAnalysisSetAnalysisRoots([testPackagePath], []));
-    return Future.wait(futures);
-  }
-
-  Future<void> test_getSuggestions() async {
-    var aPath = path.join(sourceDirectory.path, 'a');
-    var aLibPath = path.join(aPath, 'lib');
-    writeFile(path.join(aLibPath, 'a.dart'), '''
-class A {}
-''');
-    writeFile(path.join(testPackagePath, '.packages'), '''
-a:file://${path.toUri(aLibPath)}
-test_package:lib/
-''');
-    var testFilePath = path.join(testPackagePath, 'lib', 'test.dart');
-    writeFile(testFilePath, '''
-import 'package:a/a.dart';
-class B {}
-String f(A a, B b) => a.toString() + b.toString();
-''');
-    await standardAnalysisSetup();
-    await analysisFinished;
-
-    var result = await sendCompletionListTokenDetails(testFilePath);
-    expect(result, isNotNull);
-  }
-}
diff --git a/pkg/analysis_server/test/integration/completion/test_all.dart b/pkg/analysis_server/test/integration/completion/test_all.dart
index 0462e31..857202f 100644
--- a/pkg/analysis_server/test/integration/completion/test_all.dart
+++ b/pkg/analysis_server/test/integration/completion/test_all.dart
@@ -5,11 +5,9 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'get_suggestions_test.dart' as get_suggestions;
-import 'list_token_details_test.dart' as list_token_details;
 
 void main() {
   defineReflectiveSuite(() {
     get_suggestions.main();
-    list_token_details.main();
   }, name: 'completion');
 }
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index 06b628a..38705c6 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -34,7 +34,6 @@
 - [ ] completion.existingImports
 - [ ] completion.getSuggestionDetails
 - [x] completion.getSuggestions
-- [x] completion.listTokenDetails
 - [ ] completion.registerLibraryPaths
 - [ ] completion.results
 - [ ] completion.setSubscriptions
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 0fabf44..b086276c4 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1046,30 +1046,6 @@
         decoder, 'result', result);
   }
 
-  /// Inspect analysis server's knowledge about all of a file's tokens
-  /// including their lexeme, type, and what element kinds would have been
-  /// appropriate for the token's program location.
-  ///
-  /// Parameters
-  ///
-  /// file: FilePath
-  ///
-  ///   The path to the file from which tokens should be returned.
-  ///
-  /// Returns
-  ///
-  /// tokens: List<TokenDetails>
-  ///
-  ///   A list of the file's scanned tokens including analysis information
-  ///   about them.
-  Future<CompletionListTokenDetailsResult> sendCompletionListTokenDetails(
-      String file) async {
-    var params = CompletionListTokenDetailsParams(file).toJson();
-    var result = await server.send('completion.listTokenDetails', params);
-    var decoder = ResponseDecoder(null);
-    return CompletionListTokenDetailsResult.fromJson(decoder, 'result', result);
-  }
-
   /// Reports the completion suggestions that should be presented to the user.
   /// The set of suggestions included in the notification is always a complete
   /// list that supersedes any previously reported suggestions.
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index cf6abe5..fee1c3e 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1625,23 +1625,6 @@
     'SourceFileEdit',
     {'file': isFilePath, 'fileStamp': isInt, 'edits': isListOf(isSourceEdit)}));
 
-/// TokenDetails
-///
-/// {
-///   "lexeme": String
-///   "type": optional String
-///   "validElementKinds": optional List<String>
-///   "offset": int
-/// }
-final Matcher isTokenDetails = LazyMatcher(() => MatchesJsonObject(
-        'TokenDetails', {
-      'lexeme': isString,
-      'offset': isInt
-    }, optionalFields: {
-      'type': isString,
-      'validElementKinds': isListOf(isString)
-    }));
-
 /// TypeHierarchyItem
 ///
 /// {
@@ -2134,24 +2117,6 @@
     MatchesJsonObject(
         'completion.getSuggestions result', {'id': isCompletionId}));
 
-/// completion.listTokenDetails params
-///
-/// {
-///   "file": FilePath
-/// }
-final Matcher isCompletionListTokenDetailsParams = LazyMatcher(() =>
-    MatchesJsonObject(
-        'completion.listTokenDetails params', {'file': isFilePath}));
-
-/// completion.listTokenDetails result
-///
-/// {
-///   "tokens": List<TokenDetails>
-/// }
-final Matcher isCompletionListTokenDetailsResult = LazyMatcher(() =>
-    MatchesJsonObject('completion.listTokenDetails result',
-        {'tokens': isListOf(isTokenDetails)}));
-
 /// completion.registerLibraryPaths params
 ///
 /// {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
new file mode 100644
index 0000000..a154782
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/sdk_fix_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_manager.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'data_driven_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkFixCollectionTest);
+    defineReflectiveTests(SdkFixCoreTest);
+    defineReflectiveTests(SdkNoDataFileTest);
+  });
+}
+
+class AbstractSdkFixTest extends DataDrivenFixProcessorTest {
+  void addSdkDataFile(String content) {
+    newFile('$sdkRoot/lib/_internal/${TransformSetManager.dataFileName}',
+        content: content);
+  }
+
+  @override
+  void setUp() {
+    addSdkDataFile('''
+version: 1
+transforms:
+- title: 'Rename to Bar'
+  date: 2021-01-22
+  element:
+    uris:
+      - '$importUri'
+    class: 'Foo'
+  changes:
+    - kind: 'rename'
+      newName: 'Bar'
+''');
+    super.setUp();
+  }
+}
+
+@reflectiveTest
+class SdkFixCollectionTest extends AbstractSdkFixTest {
+  @override
+  String importUri = 'dart:collection';
+
+  Future<void> test_rename() async {
+    await resolveTestCode('''
+import '$importUri';
+
+void f(Foo o) {}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(Bar o) {}
+''', errorFilter: ignoreUnusedImport);
+  }
+}
+
+@reflectiveTest
+class SdkFixCoreTest extends AbstractSdkFixTest {
+  @override
+  String importUri = 'dart:core';
+
+  Future<void> test_rename() async {
+    await resolveTestCode('''
+import '$importUri';
+
+void f(Foo o) {}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(Bar o) {}
+''');
+  }
+
+  Future<void> test_rename_noImport() async {
+    await resolveTestCode('''
+void f(Foo o) {}
+''');
+    await assertHasFix('''
+void f(Bar o) {}
+''');
+  }
+}
+
+@reflectiveTest
+class SdkNoDataFileTest extends DataDrivenFixProcessorTest {
+  Future<void> test_noExceptions() async {
+    await resolveTestCode('''
+var x = '';
+''');
+    assertNoExceptions();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
index e449a9e..a21ba3c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
@@ -14,6 +14,7 @@
 import 'modify_parameters_test.dart' as modify_parameters;
 import 'rename_parameter_test.dart' as rename_parameter;
 import 'rename_test.dart' as rename;
+import 'sdk_fix_test.dart' as sdk_fix;
 import 'transform_override_set_parser_test.dart'
     as transform_override_set_parser;
 import 'transform_set_manager_test.dart' as transform_set_manager;
@@ -31,6 +32,7 @@
     modify_parameters.main();
     rename_parameter.main();
     rename.main();
+    sdk_fix.main();
     transform_override_set_parser.main();
     transform_set_manager.main();
     transform_set_parser.main();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 473675b..5731163 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -412,16 +412,6 @@
   public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer);
 
   /**
-   * {@code completion.listTokenDetails}
-   *
-   * Inspect analysis server's knowledge about all of a file's tokens including their lexeme, type,
-   * and what element kinds would have been appropriate for the token's program location.
-   *
-   * @param file The path to the file from which tokens should be returned.
-   */
-  public void completion_listTokenDetails(String file, ListTokenDetailsConsumer consumer);
-
-  /**
    * {@code completion.registerLibraryPaths}
    *
    * The client can make this request to express interest in certain libraries to receive completion
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
deleted file mode 100644
index 71b5f70..0000000
--- a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
- * for details. All rights reserved. Use of this source code is governed by a
- * BSD-style license that can be found in the LICENSE file.
- *
- * This file has been automatically generated. Please do not edit it manually.
- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
- */
-package org.dartlang.analysis.server.protocol;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import com.google.common.collect.Lists;
-import com.google.dart.server.utilities.general.JsonUtilities;
-import com.google.dart.server.utilities.general.ObjectUtilities;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import java.util.ArrayList;
-import java.util.Iterator;
-import org.apache.commons.lang3.StringUtils;
-
-/**
- * A scanned token along with its inferred type information.
- *
- * @coverage dart.server.generated.types
- */
-@SuppressWarnings("unused")
-public class TokenDetails {
-
-  public static final TokenDetails[] EMPTY_ARRAY = new TokenDetails[0];
-
-  public static final List<TokenDetails> EMPTY_LIST = Lists.newArrayList();
-
-  /**
-   * The token's lexeme.
-   */
-  private final String lexeme;
-
-  /**
-   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
-   * reference position.
-   */
-  private final String type;
-
-  /**
-   * An indication of whether this token is in a declaration or reference position. (If no other
-   * purpose is found for this field then it should be renamed and converted to a boolean value.)
-   * Omitted if the token is not an identifier.
-   */
-  private final List<String> validElementKinds;
-
-  /**
-   * The offset of the first character of the token in the file which it originated from.
-   */
-  private final int offset;
-
-  /**
-   * Constructor for {@link TokenDetails}.
-   */
-  public TokenDetails(String lexeme, String type, List<String> validElementKinds, int offset) {
-    this.lexeme = lexeme;
-    this.type = type;
-    this.validElementKinds = validElementKinds;
-    this.offset = offset;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof TokenDetails) {
-      TokenDetails other = (TokenDetails) obj;
-      return
-        ObjectUtilities.equals(other.lexeme, lexeme) &&
-        ObjectUtilities.equals(other.type, type) &&
-        ObjectUtilities.equals(other.validElementKinds, validElementKinds) &&
-        other.offset == offset;
-    }
-    return false;
-  }
-
-  public static TokenDetails fromJson(JsonObject jsonObject) {
-    String lexeme = jsonObject.get("lexeme").getAsString();
-    String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString();
-    List<String> validElementKinds = jsonObject.get("validElementKinds") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("validElementKinds").getAsJsonArray());
-    int offset = jsonObject.get("offset").getAsInt();
-    return new TokenDetails(lexeme, type, validElementKinds, offset);
-  }
-
-  public static List<TokenDetails> fromJsonArray(JsonArray jsonArray) {
-    if (jsonArray == null) {
-      return EMPTY_LIST;
-    }
-    ArrayList<TokenDetails> list = new ArrayList<TokenDetails>(jsonArray.size());
-    Iterator<JsonElement> iterator = jsonArray.iterator();
-    while (iterator.hasNext()) {
-      list.add(fromJson(iterator.next().getAsJsonObject()));
-    }
-    return list;
-  }
-
-  /**
-   * The token's lexeme.
-   */
-  public String getLexeme() {
-    return lexeme;
-  }
-
-  /**
-   * The offset of the first character of the token in the file which it originated from.
-   */
-  public int getOffset() {
-    return offset;
-  }
-
-  /**
-   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
-   * reference position.
-   */
-  public String getType() {
-    return type;
-  }
-
-  /**
-   * An indication of whether this token is in a declaration or reference position. (If no other
-   * purpose is found for this field then it should be renamed and converted to a boolean value.)
-   * Omitted if the token is not an identifier.
-   */
-  public List<String> getValidElementKinds() {
-    return validElementKinds;
-  }
-
-  @Override
-  public int hashCode() {
-    HashCodeBuilder builder = new HashCodeBuilder();
-    builder.append(lexeme);
-    builder.append(type);
-    builder.append(validElementKinds);
-    builder.append(offset);
-    return builder.toHashCode();
-  }
-
-  public JsonObject toJson() {
-    JsonObject jsonObject = new JsonObject();
-    jsonObject.addProperty("lexeme", lexeme);
-    if (type != null) {
-      jsonObject.addProperty("type", type);
-    }
-    if (validElementKinds != null) {
-      JsonArray jsonArrayValidElementKinds = new JsonArray();
-      for (String elt : validElementKinds) {
-        jsonArrayValidElementKinds.add(new JsonPrimitive(elt));
-      }
-      jsonObject.add("validElementKinds", jsonArrayValidElementKinds);
-    }
-    jsonObject.addProperty("offset", offset);
-    return jsonObject;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("[");
-    builder.append("lexeme=");
-    builder.append(lexeme + ", ");
-    builder.append("type=");
-    builder.append(type + ", ");
-    builder.append("validElementKinds=");
-    builder.append(StringUtils.join(validElementKinds, ", ") + ", ");
-    builder.append("offset=");
-    builder.append(offset);
-    builder.append("]");
-    return builder.toString();
-  }
-
-}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 7d118ec..536cad8 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.32.2</version>
+  <version>1.32.3</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -134,13 +134,20 @@
   ignoring the item or treating it with some default/fallback handling.
 </p>
 <h3>Changelog</h3>
+<h4>1.32.3</h4>
+<ul>
+  <li>Removed the experimental <tt>completion.listTokenDetails</tt> request and
+    the associated data types.</li>
+</ul>
 <h4>1.32.2</h4>
 <ul>
-  <li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of comments.</li>
+  <li>Added <tt>FoldingKind.COMMENT</tt> for folding regions for blocks of
+    comments.</li>
 </ul>
 <h4>1.32.1</h4>
 <ul>
-  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt>.</li>
+  <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name
+    completions in <tt>pubspec.yaml</tt>.</li>
 </ul>
 <h3>Domains</h3>
 <p>
@@ -1520,32 +1527,6 @@
       </field>
     </result>
   </request>
-  <request method="listTokenDetails" experimental="true">
-    <p>
-      Inspect analysis server's knowledge about all of a file's tokens including
-      their lexeme, type, and what element kinds would have been appropriate for
-      the token's program location.
-    </p>
-    <params>
-      <field name="file">
-        <ref>FilePath</ref>
-        <p>
-          The path to the file from which tokens should be returned.
-        </p>
-      </field>
-    </params>
-    <result>
-      <field name="tokens">
-        <list>
-          <ref>TokenDetails</ref>
-        </list>
-        <p>
-          A list of the file's scanned tokens including analysis information
-          about them.
-        </p>
-      </field>
-    </result>
-  </request>
   <notification event="results">
     <p>
       Reports the completion suggestions that should be presented
@@ -4222,44 +4203,6 @@
       <value><code>INTERFACE</code></value>
     </enum>
   </type>
-  <type name="TokenDetails" experimental="true">
-    <p>
-      A scanned token along with its inferred type information.
-    </p>
-    <object>
-      <field name="lexeme">
-        <ref>String</ref>
-        <p>
-          The token's lexeme.
-        </p>
-      </field>
-      <field name="type" optional="true">
-        <ref>String</ref>
-        <p>
-          A unique id for the type of the identifier.
-          Omitted if the token is not an identifier in a reference position.
-        </p>
-      </field>
-      <field name="validElementKinds" optional="true">
-        <list>
-          <ref>String</ref>
-        </list>
-        <p>
-          An indication of whether this token is in a declaration or reference
-          position. (If no other purpose is found for this field then it should
-          be renamed and converted to a boolean value.)
-          Omitted if the token is not an identifier.
-        </p>
-      </field>
-      <field name="offset">
-        <ref>int</ref>
-        <p>
-          The offset of the first character of the token in the file which it
-          originated from.
-        </p>
-      </field>
-    </object>
-  </type>
   <type name="ExecutionService">
     <p>
       An enumeration of the services provided by the execution
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 68ea10f..ff997f0 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.32.2';
+const String PROTOCOL_VERSION = '1.32.3';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -145,9 +145,6 @@
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
-const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS =
-    'completion.listTokenDetails';
-const String COMPLETION_REQUEST_LIST_TOKEN_DETAILS_FILE = 'file';
 const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
     'completion.registerLibraryPaths';
 const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
@@ -159,7 +156,6 @@
 const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
 const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
     'completion';
-const String COMPLETION_RESPONSE_LIST_TOKEN_DETAILS_TOKENS = 'tokens';
 const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
 const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
 const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index ca40968..e5dd041 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -5886,168 +5886,6 @@
   }
 }
 
-/// completion.listTokenDetails params
-///
-/// {
-///   "file": FilePath
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class CompletionListTokenDetailsParams implements RequestParams {
-  String _file;
-
-  /// The path to the file from which tokens should be returned.
-  String get file => _file;
-
-  /// The path to the file from which tokens should be returned.
-  set file(String value) {
-    assert(value != null);
-    _file = value;
-  }
-
-  CompletionListTokenDetailsParams(String file) {
-    this.file = file;
-  }
-
-  factory CompletionListTokenDetailsParams.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      String file;
-      if (json.containsKey('file')) {
-        file = jsonDecoder.decodeString(jsonPath + '.file', json['file']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'file');
-      }
-      return CompletionListTokenDetailsParams(file);
-    } else {
-      throw jsonDecoder.mismatch(
-          jsonPath, 'completion.listTokenDetails params', json);
-    }
-  }
-
-  factory CompletionListTokenDetailsParams.fromRequest(Request request) {
-    return CompletionListTokenDetailsParams.fromJson(
-        RequestDecoder(request), 'params', request.params);
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['file'] = file;
-    return result;
-  }
-
-  @override
-  Request toRequest(String id) {
-    return Request(id, 'completion.listTokenDetails', toJson());
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is CompletionListTokenDetailsParams) {
-      return file == other.file;
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, file.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
-/// completion.listTokenDetails result
-///
-/// {
-///   "tokens": List<TokenDetails>
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class CompletionListTokenDetailsResult implements ResponseResult {
-  List<TokenDetails> _tokens;
-
-  /// A list of the file's scanned tokens including analysis information about
-  /// them.
-  List<TokenDetails> get tokens => _tokens;
-
-  /// A list of the file's scanned tokens including analysis information about
-  /// them.
-  set tokens(List<TokenDetails> value) {
-    assert(value != null);
-    _tokens = value;
-  }
-
-  CompletionListTokenDetailsResult(List<TokenDetails> tokens) {
-    this.tokens = tokens;
-  }
-
-  factory CompletionListTokenDetailsResult.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      List<TokenDetails> tokens;
-      if (json.containsKey('tokens')) {
-        tokens = jsonDecoder.decodeList(
-            jsonPath + '.tokens',
-            json['tokens'],
-            (String jsonPath, Object json) =>
-                TokenDetails.fromJson(jsonDecoder, jsonPath, json));
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'tokens');
-      }
-      return CompletionListTokenDetailsResult(tokens);
-    } else {
-      throw jsonDecoder.mismatch(
-          jsonPath, 'completion.listTokenDetails result', json);
-    }
-  }
-
-  factory CompletionListTokenDetailsResult.fromResponse(Response response) {
-    return CompletionListTokenDetailsResult.fromJson(
-        ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
-        'result',
-        response.result);
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['tokens'] =
-        tokens.map((TokenDetails value) => value.toJson()).toList();
-    return result;
-  }
-
-  @override
-  Response toResponse(String id) {
-    return Response(id, result: toJson());
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is CompletionListTokenDetailsResult) {
-      return listEqual(
-          tokens, other.tokens, (TokenDetails a, TokenDetails b) => a == b);
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, tokens.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
 /// completion.registerLibraryPaths params
 ///
 /// {
@@ -21345,151 +21183,6 @@
   }
 }
 
-/// TokenDetails
-///
-/// {
-///   "lexeme": String
-///   "type": optional String
-///   "validElementKinds": optional List<String>
-///   "offset": int
-/// }
-///
-/// Clients may not extend, implement or mix-in this class.
-class TokenDetails implements HasToJson {
-  String _lexeme;
-
-  String _type;
-
-  List<String> _validElementKinds;
-
-  int _offset;
-
-  /// The token's lexeme.
-  String get lexeme => _lexeme;
-
-  /// The token's lexeme.
-  set lexeme(String value) {
-    assert(value != null);
-    _lexeme = value;
-  }
-
-  /// A unique id for the type of the identifier. Omitted if the token is not
-  /// an identifier in a reference position.
-  String get type => _type;
-
-  /// A unique id for the type of the identifier. Omitted if the token is not
-  /// an identifier in a reference position.
-  set type(String value) {
-    _type = value;
-  }
-
-  /// An indication of whether this token is in a declaration or reference
-  /// position. (If no other purpose is found for this field then it should be
-  /// renamed and converted to a boolean value.) Omitted if the token is not an
-  /// identifier.
-  List<String> get validElementKinds => _validElementKinds;
-
-  /// An indication of whether this token is in a declaration or reference
-  /// position. (If no other purpose is found for this field then it should be
-  /// renamed and converted to a boolean value.) Omitted if the token is not an
-  /// identifier.
-  set validElementKinds(List<String> value) {
-    _validElementKinds = value;
-  }
-
-  /// The offset of the first character of the token in the file which it
-  /// originated from.
-  int get offset => _offset;
-
-  /// The offset of the first character of the token in the file which it
-  /// originated from.
-  set offset(int value) {
-    assert(value != null);
-    _offset = value;
-  }
-
-  TokenDetails(String lexeme, int offset,
-      {String type, List<String> validElementKinds}) {
-    this.lexeme = lexeme;
-    this.type = type;
-    this.validElementKinds = validElementKinds;
-    this.offset = offset;
-  }
-
-  factory TokenDetails.fromJson(
-      JsonDecoder jsonDecoder, String jsonPath, Object json) {
-    json ??= {};
-    if (json is Map) {
-      String lexeme;
-      if (json.containsKey('lexeme')) {
-        lexeme = jsonDecoder.decodeString(jsonPath + '.lexeme', json['lexeme']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'lexeme');
-      }
-      String type;
-      if (json.containsKey('type')) {
-        type = jsonDecoder.decodeString(jsonPath + '.type', json['type']);
-      }
-      List<String> validElementKinds;
-      if (json.containsKey('validElementKinds')) {
-        validElementKinds = jsonDecoder.decodeList(
-            jsonPath + '.validElementKinds',
-            json['validElementKinds'],
-            jsonDecoder.decodeString);
-      }
-      int offset;
-      if (json.containsKey('offset')) {
-        offset = jsonDecoder.decodeInt(jsonPath + '.offset', json['offset']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'offset');
-      }
-      return TokenDetails(lexeme, offset,
-          type: type, validElementKinds: validElementKinds);
-    } else {
-      throw jsonDecoder.mismatch(jsonPath, 'TokenDetails', json);
-    }
-  }
-
-  @override
-  Map<String, dynamic> toJson() {
-    var result = <String, dynamic>{};
-    result['lexeme'] = lexeme;
-    if (type != null) {
-      result['type'] = type;
-    }
-    if (validElementKinds != null) {
-      result['validElementKinds'] = validElementKinds;
-    }
-    result['offset'] = offset;
-    return result;
-  }
-
-  @override
-  String toString() => json.encode(toJson());
-
-  @override
-  bool operator ==(other) {
-    if (other is TokenDetails) {
-      return lexeme == other.lexeme &&
-          type == other.type &&
-          listEqual(validElementKinds, other.validElementKinds,
-              (String a, String b) => a == b) &&
-          offset == other.offset;
-    }
-    return false;
-  }
-
-  @override
-  int get hashCode {
-    var hash = 0;
-    hash = JenkinsSmiHash.combine(hash, lexeme.hashCode);
-    hash = JenkinsSmiHash.combine(hash, type.hashCode);
-    hash = JenkinsSmiHash.combine(hash, validElementKinds.hashCode);
-    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
-    return JenkinsSmiHash.finish(hash);
-  }
-}
-
 /// TypeHierarchyItem
 ///
 /// {
diff --git a/pkg/analysis_server_client/test/verify_sorted_test.dart b/pkg/analysis_server_client/test/verify_sorted_test.dart
index 79d7299..5a19d51 100644
--- a/pkg/analysis_server_client/test/verify_sorted_test.dart
+++ b/pkg/analysis_server_client/test/verify_sorted_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:io';
-
 import 'package:analysis_server/src/services/correction/sort_members.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/results.dart';
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index 667a28d..3d8351e 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -103,8 +103,8 @@
   _MicroAnalysisSessionImpl currentSession;
 
   final DeclaredVariables declaredVariables;
-  final SourceFactory sourceFactory;
 
+  final SourceFactory sourceFactory;
   Workspace _workspace;
 
   _MicroAnalysisContextImpl(
@@ -123,6 +123,9 @@
   }
 
   @override
+  Folder get sdkRoot => null;
+
+  @override
   Workspace get workspace {
     return _workspace ??= _buildWorkspace();
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index 0414591..92bb29d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -293,6 +293,7 @@
         );
       }
       node.staticElement = member;
+      node.staticInvokeType = member?.type;
       return;
     }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index 8df9d1c..439d445 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -91,11 +91,11 @@
 
   test_createContext_sdkRoot() {
     MockSdk(resourceProvider: resourceProvider);
-    DriverBasedAnalysisContext context = contextBuilder.createContext(
+    var context = contextBuilder.createContext(
         contextRoot: contextRoot,
         sdkPath: resourceProvider.convertPath(sdkRoot));
     expect(context.analysisOptions, isNotNull);
     expect(context.contextRoot, contextRoot);
-    expect(context.sdkRoot.path, sdkRoot);
+    expect(context.sdkRoot?.path, resourceProvider.convertPath(sdkRoot));
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
index b484064..a5be3c1 100644
--- a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
@@ -341,7 +341,6 @@
         [typeToStringWithNullability ? 'int' : 'num']);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/43114')
   test_plus_int_context_int_via_extension_explicit() async {
     await assertErrorsInCode('''
 extension E on int {
@@ -438,7 +437,6 @@
     );
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/43114')
   test_plus_int_int_via_extension_explicit() async {
     await assertNoErrorsInCode('''
 extension E on int {
@@ -511,7 +509,6 @@
     assertTypeArgumentTypes(findNode.methodInvocation('f()'), ['String']);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/43114')
   test_plus_other_context_int_via_extension_explicit() async {
     await assertErrorsInCode('''
 class A {}
@@ -568,7 +565,6 @@
     );
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/43114')
   test_plus_other_int_via_extension_explicit() async {
     await assertNoErrorsInCode('''
 class A {}
diff --git a/pkg/analyzer_plugin/doc/tutorial/assists.md b/pkg/analyzer_plugin/doc/tutorial/assists.md
index b71e33d..dd38b78 100644
--- a/pkg/analyzer_plugin/doc/tutorial/assists.md
+++ b/pkg/analyzer_plugin/doc/tutorial/assists.md
@@ -62,7 +62,7 @@
     with AssistContributorMixin
     implements AssistContributor {
   static AssistKind wrapInIf =
-      new AssistKind('wrapInIf', 100, "Wrap in an 'if' statement");
+      AssistKind('wrapInIf', 100, "Wrap in an 'if' statement");
 
   DartAssistRequest request;
 
@@ -71,21 +71,24 @@
   AnalysisSession get session => request.result.session;
 
   @override
-  void computeAssists(DartAssistRequest request, AssistCollector collector) {
+  Future<void> computeAssists(DartAssistRequest request, AssistCollector collector) async {
     this.request = request;
     this.collector = collector;
-    _wrapInIf();
-    _wrapInWhile();
+    await _wrapInIf();
+    await _wrapInWhile();
     // ...
   }
 
-  void _wrapInIf() {
-    ChangeBuilder builder = new ChangeBuilder(session: session);
-    // TODO Build the edit to wrap the selection in a 'if' statement.
+  Future<void> _wrapInIf() async {
+    ChangeBuilder builder = ChangeBuilder(session: session);
+    await changeBuilder.addDartFileEdit(path,
+        (DartFileEditBuilder fileEditBuilder) {
+      // TODO Build the edit to wrap the selection in a 'if' statement.
+    });
     addAssist(wrapInIf, builder);
   }
 
-  void _wrapInWhile() {
+  Future<void> _wrapInWhile() async {
     // ...
   }
 }
@@ -100,7 +103,7 @@
 
   @override
   List<AssistContributor> getAssistContributors(AnalysisDriver driver) {
-    return <AssistContributor>[new MyAssistContributor()];
+    return <AssistContributor>[MyAssistContributor()];
   }
 }
 ```
diff --git a/pkg/analyzer_plugin/doc/tutorial/fixes.md b/pkg/analyzer_plugin/doc/tutorial/fixes.md
index 920ed30..efe2537 100644
--- a/pkg/analyzer_plugin/doc/tutorial/fixes.md
+++ b/pkg/analyzer_plugin/doc/tutorial/fixes.md
@@ -79,28 +79,31 @@
     with FixContributorMixin
     implements FixContributor {
   static FixKind defineComponent =
-      new FixKind('defineComponent', 100, "Define a component named {0}");
+      FixKind('defineComponent', 100, "Define a component named {0}");
 
   AnalysisSession get session => request.result.session;
 
   @override
-  void computeFixesForError(AnalysisError error) {
+  Future<void> computeFixesForError(AnalysisError error) async {
     ErrorCode code = error.errorCode;
     if (code == MyErrorCode.undefinedComponent) {
-      _defineComponent(error);
-      _useExistingComponent(error);
+      await _defineComponent(error);
+      await _useExistingComponent(error);
     }
   }
 
-  void _defineComponent(AnalysisError error) {
+  Future<void> _defineComponent(AnalysisError error) async {
     // TODO Get the name from the source code.
     String componentName = null;
-    ChangeBuilder builder = new ChangeBuilder(session: session);
-    // TODO Build the edit to insert the definition of the component.
+    ChangeBuilder builder = ChangeBuilder(session: session);
+    await changeBuilder.addDartFileEdit(path,
+        (DartFileEditBuilder fileEditBuilder) {
+      // TODO Build the edit to insert the definition of the component.
+    });
     addFix(error, defineComponent, builder, args: [componentName]);
   }
 
-  void _useExistingComponent(AnalysisError error) {
+  Future<void> _useExistingComponent(AnalysisError error) async {
     // ...
   }
 }
@@ -116,7 +119,7 @@
   @override
   List<FixContributor> getFixContributors(
       AnalysisDriverGeneric driver) {
-    return <FixContributor>[new MyFixContributor()];
+    return <FixContributor>[MyFixContributor()];
   }
 }
 ```
diff --git a/pkg/analyzer_plugin/doc/tutorial/package_structure.md b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
index 9572ece..1963892 100644
--- a/pkg/analyzer_plugin/doc/tutorial/package_structure.md
+++ b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
@@ -87,7 +87,7 @@
 When a bootstrap package is to be run, the contents of the directory containing
 the bootstrap package are copied to a temporary directory, the [`pub`][pub]
 command is run in that directory to produce a `.packages` file for the bootstrap
-package, and the file `tools/analysis_plugin/bin/plugin.dart` is run in its own
+package, and the file `tools/analyzer_plugin/bin/plugin.dart` is run in its own
 isolate.
 
 [pub]:https://www.dartlang.org/tools/pub/get-started
diff --git a/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart b/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
index 3a90b0b..1def750 100644
--- a/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
@@ -31,7 +31,7 @@
     var path = parameters.file;
     var request = await getAssistRequest(parameters);
     var generator = AssistGenerator(getAssistContributors(path));
-    var result = generator.generateAssistsResponse(request);
+    var result = await generator.generateAssistsResponse(request);
     result.sendNotifications(channel);
     return result.result;
   }
diff --git a/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart b/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
index 1fde901..f20d776 100644
--- a/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
@@ -60,7 +60,7 @@
     var path = parameters.file;
     var request = await getFixesRequest(parameters);
     var generator = FixGenerator(getFixContributors(path));
-    var result = generator.generateFixesResponse(request);
+    var result = await generator.generateFixesResponse(request);
     result.sendNotifications(channel);
     return result.result;
   }
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 28ff7fe..3e6290b 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -23,7 +23,7 @@
 abstract class AssistContributor {
   /// Contribute assists for the location in the file specified by the given
   /// [request] into the given [collector].
-  void computeAssists(
+  Future<void> computeAssists(
       covariant AssistRequest request, AssistCollector collector);
 }
 
@@ -41,13 +41,13 @@
   /// Create an 'edit.getAssists' response for the location in the file specified
   /// by the given [request]. If any of the contributors throws an exception,
   /// also create a non-fatal 'plugin.error' notification.
-  GeneratorResult<EditGetAssistsResult> generateAssistsResponse(
-      AssistRequest request) {
+  Future<GeneratorResult<EditGetAssistsResult>> generateAssistsResponse(
+      AssistRequest request) async {
     var notifications = <Notification>[];
     var collector = AssistCollectorImpl();
     for (var contributor in contributors) {
       try {
-        contributor.computeAssists(request, collector);
+        await contributor.computeAssists(request, collector);
       } catch (exception, stackTrace) {
         notifications.add(PluginErrorParams(
                 false, exception.toString(), stackTrace.toString())
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
index cbd2fcc..1546f14 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist_contributor_mixin.dart
@@ -25,8 +25,9 @@
     if (change.edits.isEmpty) {
       return;
     }
+    change.id = kind.id;
     change.message = formatList(kind.message, args);
     collector.addAssist(
-        PrioritizedSourceChange(kind.priority, builder.sourceChange));
+        PrioritizedSourceChange(kind.priority, change));
   }
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
index 7f01aca..b4be5b0 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fix_contributor_mixin.dart
@@ -30,18 +30,19 @@
     if (change.edits.isEmpty) {
       return;
     }
+    change.id = kind.id;
     change.message = formatList(kind.message, args);
     collector.addFix(
-        error, PrioritizedSourceChange(kind.priority, builder.sourceChange));
+        error, PrioritizedSourceChange(kind.priority, change));
   }
 
   @override
-  void computeFixes(DartFixesRequest request, FixCollector collector) {
+  Future<void> computeFixes(DartFixesRequest request, FixCollector collector) async {
     this.request = request;
     this.collector = collector;
     try {
       for (var error in request.errorsToFix) {
-        computeFixesForError(error);
+        await computeFixesForError(error);
       }
     } finally {
       this.request = null;
@@ -51,5 +52,5 @@
 
   /// Compute the fixes that are appropriate for the given [error] and add them
   /// to the fix [collector].
-  void computeFixesForError(AnalysisError error);
+  Future<void> computeFixesForError(AnalysisError error);
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
index 46c3a7d..8455680 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
@@ -33,7 +33,7 @@
 abstract class FixContributor {
   /// Contribute fixes for the location in the file specified by the given
   /// [request] into the given [collector].
-  void computeFixes(covariant FixesRequest request, FixCollector collector);
+  Future<void> computeFixes(covariant FixesRequest request, FixCollector collector);
 }
 
 /// The information about a requested set of fixes.
@@ -64,13 +64,13 @@
   /// Create an 'edit.getFixes' response for the location in the file specified
   /// by the given [request]. If any of the contributors throws an exception,
   /// also create a non-fatal 'plugin.error' notification.
-  GeneratorResult<EditGetFixesResult> generateFixesResponse(
-      FixesRequest request) {
+  Future<GeneratorResult<EditGetFixesResult>> generateFixesResponse(
+      FixesRequest request) async {
     var notifications = <Notification>[];
     var collector = FixCollectorImpl();
     for (var contributor in contributors) {
       try {
-        contributor.computeFixes(request, collector);
+        await contributor.computeFixes(request, collector);
       } catch (exception, stackTrace) {
         notifications.add(PluginErrorParams(
                 false, exception.toString(), stackTrace.toString())
diff --git a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
index 67f2c28..955290a 100644
--- a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
@@ -55,7 +55,7 @@
   _TestAssistContributor(this.changes);
 
   @override
-  void computeAssists(AssistRequest request, AssistCollector collector) {
+  Future<void> computeAssists(AssistRequest request, AssistCollector collector) async {
     for (var change in changes) {
       collector.addAssist(change);
     }
diff --git a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
index 578c0ae..06a1c7f 100644
--- a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
@@ -61,7 +61,7 @@
   _TestFixContributor(this.changes);
 
   @override
-  void computeFixes(FixesRequest request, FixCollector collector) {
+  Future<void> computeFixes(FixesRequest request, FixCollector collector) async {
     for (var change in changes) {
       collector.addFix(request.errorsToFix[0], change);
     }
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index c67abe5..261fdd0 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 1.7.4
+- Update `package:vm_service` to 6.0.1-nullsafety.0.
+
 # 1.7.3
 - Return an RpcException error with code `kServiceDisappeared` if the VM
   service connection disappears with an outstanding forwarded request.
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 3ecf449..92dee88 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.7.3
+version: 1.7.4
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
@@ -20,7 +20,7 @@
   shelf_web_socket: ^0.2.3
   sse: ^3.5.0
   stream_channel: ^2.0.0
-  vm_service: ^5.0.0
+  vm_service: ^6.0.1-nullsafety.0
   web_socket_channel: ^1.1.0
 
 dev_dependencies:
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 5e7960f..99c4fc7 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -192,7 +192,7 @@
   bool verify = false;
 
   /// Whether to - if verifying - skip the platform.
-  bool verifySkipPlatform = false;
+  bool skipPlatformVerification = false;
 
   /// Whether to dump generated components in a text format (also mainly for
   /// debugging).
@@ -338,7 +338,9 @@
     }
     if (!ignoreVerify) {
       if (verify != other.verify) return false;
-      if (verifySkipPlatform != other.verifySkipPlatform) return false;
+      if (skipPlatformVerification != other.skipPlatformVerification) {
+        return false;
+      }
     }
     if (!ignoreDebugDump) {
       if (debugDump != other.debugDump) return false;
diff --git a/pkg/front_end/lib/src/base/command_line_options.dart b/pkg/front_end/lib/src/base/command_line_options.dart
index d2e2f84..4d8ef80 100644
--- a/pkg/front_end/lib/src/base/command_line_options.dart
+++ b/pkg/front_end/lib/src/base/command_line_options.dart
@@ -40,7 +40,7 @@
   static const String verbose = "--verbose";
   static const String verbosity = "--verbosity";
   static const String verify = "--verify";
-  static const String verifySkipPlatform = "--verify-skip-platform";
+  static const String skipPlatformVerification = "--skip-platform-verification";
   static const String warnOnReachabilityCheck = "--warn-on-reachability-check";
 
   static const String invocationModes = "--invocation-modes";
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index bc6c7ad..94a7d0d 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -167,7 +167,7 @@
 
   bool get verify => _raw.verify;
 
-  bool get verifySkipPlatform => _raw.verifySkipPlatform;
+  bool get skipPlatformVerification => _raw.skipPlatformVerification;
 
   bool get debugDump => _raw.debugDump;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 8e75d57..5135011 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1334,7 +1334,7 @@
   void verify() {
     // TODO(ahe): How to handle errors.
     verifyComponent(component,
-        skipPlatform: context.options.verifySkipPlatform);
+        skipPlatform: context.options.skipPlatformVerification);
     ClassHierarchy hierarchy =
         new ClassHierarchy(component, new CoreTypes(component),
             onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {
@@ -1342,7 +1342,7 @@
     });
     verifyGetStaticType(
         new TypeEnvironment(loader.coreTypes, hierarchy), component,
-        skipPlatform: context.options.verifySkipPlatform);
+        skipPlatform: context.options.skipPlatformVerification);
     ticker.logMs("Verified component");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 32b969f..f944fe9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -430,25 +430,15 @@
     SourceLibraryBuilder libraryBuilder = this.library;
     Library library = libraryBuilder.library;
 
-    Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssues(
-            library,
-            new InterfaceType(supertype.classNode, library.nonNullable,
-                supertype.typeArguments),
-            typeEnvironment,
-            SubtypeCheckMode.ignoringNullabilities,
-            allowSuperBounded: false) ??
-        const []);
-    if (library.isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssues(
-              library,
-              new InterfaceType(supertype.classNode, library.nonNullable,
-                  supertype.typeArguments),
-              typeEnvironment,
-              SubtypeCheckMode.withNullabilities,
-              allowSuperBounded: false) ??
-          const []);
-    }
+    List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+        library,
+        new InterfaceType(
+            supertype.classNode, library.nonNullable, supertype.typeArguments),
+        typeEnvironment,
+        libraryBuilder.isNonNullableByDefault
+            ? SubtypeCheckMode.withNullabilities
+            : SubtypeCheckMode.ignoringNullabilities,
+        allowSuperBounded: false);
     for (TypeArgumentIssue issue in issues) {
       DartType argument = issue.argument;
       TypeParameter typeParameter = issue.typeParameter;
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index c74e46a..39531a8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -3374,17 +3374,14 @@
       List<TypeParameter> typeParameters, Uri fileUri) {
     // Check in bounds of own type variables.
     for (TypeParameter parameter in typeParameters) {
-      Set<TypeArgumentIssue> issues = {};
-      issues.addAll(findTypeArgumentIssues(library, parameter.bound,
-              typeEnvironment, SubtypeCheckMode.ignoringNullabilities,
-              allowSuperBounded: true) ??
-          const []);
-      if (library.isNonNullableByDefault) {
-        issues.addAll(findTypeArgumentIssues(library, parameter.bound,
-                typeEnvironment, SubtypeCheckMode.withNullabilities,
-                allowSuperBounded: true) ??
-            const []);
-      }
+      List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+          library,
+          parameter.bound,
+          typeEnvironment,
+          isNonNullableByDefault
+              ? SubtypeCheckMode.withNullabilities
+              : SubtypeCheckMode.ignoringNullabilities,
+          allowSuperBounded: true);
       for (TypeArgumentIssue issue in issues) {
         DartType argument = issue.argument;
         TypeParameter typeParameter = issue.typeParameter;
@@ -3453,17 +3450,14 @@
       }
     }
     if (!skipReturnType && returnType != null) {
-      Set<TypeArgumentIssue> issues = {};
-      issues.addAll(findTypeArgumentIssues(library, returnType, typeEnvironment,
-              SubtypeCheckMode.ignoringNullabilities,
-              allowSuperBounded: true) ??
-          const []);
-      if (isNonNullableByDefault) {
-        issues.addAll(findTypeArgumentIssues(library, returnType,
-                typeEnvironment, SubtypeCheckMode.withNullabilities,
-                allowSuperBounded: true) ??
-            const []);
-      }
+      List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+          library,
+          returnType,
+          typeEnvironment,
+          isNonNullableByDefault
+              ? SubtypeCheckMode.withNullabilities
+              : SubtypeCheckMode.ignoringNullabilities,
+          allowSuperBounded: true);
       for (TypeArgumentIssue issue in issues) {
         DartType argument = issue.argument;
         TypeParameter typeParameter = issue.typeParameter;
@@ -3564,17 +3558,14 @@
   void checkBoundsInType(
       DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset,
       {bool inferred, bool allowSuperBounded = true}) {
-    Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
-            SubtypeCheckMode.ignoringNullabilities,
-            allowSuperBounded: allowSuperBounded) ??
-        const []);
-    if (isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
-              SubtypeCheckMode.withNullabilities,
-              allowSuperBounded: allowSuperBounded) ??
-          const []);
-    }
+    List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+        library,
+        type,
+        typeEnvironment,
+        isNonNullableByDefault
+            ? SubtypeCheckMode.withNullabilities
+            : SubtypeCheckMode.ignoringNullabilities,
+        allowSuperBounded: allowSuperBounded);
     reportTypeArgumentIssues(issues, fileUri, offset, inferred: inferred);
   }
 
@@ -3631,25 +3622,15 @@
     final DartType bottomType = isNonNullableByDefault
         ? const NeverType(Nullability.nonNullable)
         : const NullType();
-    Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssuesForInvocation(
-            library,
-            parameters,
-            arguments,
-            typeEnvironment,
-            SubtypeCheckMode.ignoringNullabilities,
-            bottomType) ??
-        const []);
-    if (isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssuesForInvocation(
-              library,
-              parameters,
-              arguments,
-              typeEnvironment,
-              SubtypeCheckMode.withNullabilities,
-              bottomType) ??
-          const []);
-    }
+    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
+        library,
+        parameters,
+        arguments,
+        typeEnvironment,
+        isNonNullableByDefault
+            ? SubtypeCheckMode.withNullabilities
+            : SubtypeCheckMode.ignoringNullabilities,
+        bottomType);
     if (issues.isNotEmpty) {
       DartType targetReceiver;
       if (klass != null) {
@@ -3718,25 +3699,15 @@
     final DartType bottomType = isNonNullableByDefault
         ? const NeverType(Nullability.nonNullable)
         : const NullType();
-    Set<TypeArgumentIssue> issues = {};
-    issues.addAll(findTypeArgumentIssuesForInvocation(
-            library,
-            instantiatedMethodParameters,
-            arguments.types,
-            typeEnvironment,
-            SubtypeCheckMode.ignoringNullabilities,
-            bottomType) ??
-        const []);
-    if (isNonNullableByDefault) {
-      issues.addAll(findTypeArgumentIssuesForInvocation(
-              library,
-              instantiatedMethodParameters,
-              arguments.types,
-              typeEnvironment,
-              SubtypeCheckMode.withNullabilities,
-              bottomType) ??
-          const []);
-    }
+    List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
+        library,
+        instantiatedMethodParameters,
+        arguments.types,
+        typeEnvironment,
+        isNonNullableByDefault
+            ? SubtypeCheckMode.withNullabilities
+            : SubtypeCheckMode.ignoringNullabilities,
+        bottomType);
     reportTypeArgumentIssues(issues, fileUri, offset,
         typeArgumentsInfo: getTypeArgumentsInfo(arguments),
         targetReceiver: receiverType,
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 19c21c2..e5a4357 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1027,7 +1027,7 @@
       ..allowedExperimentalFlagsForTesting = allowedExperimentalFlags
       ..experimentEnabledVersionForTesting = experimentEnabledVersion
       ..experimentReleasedVersionForTesting = experimentReleasedVersion
-      ..verifySkipPlatform = true
+      ..skipPlatformVerification = true
       ..target = createTarget(folderOptions, context);
     if (folderOptions.overwriteCurrentSdkVersion != null) {
       compilerOptions.currentSdkVersion =
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 09c977b..bfa8f4b 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -197,7 +197,7 @@
   Flags.verbose: const BoolValue(false),
   Flags.verbosity: const StringValue(),
   Flags.verify: const BoolValue(false),
-  Flags.verifySkipPlatform: const BoolValue(false),
+  Flags.skipPlatformVerification: const BoolValue(false),
   Flags.warnOnReachabilityCheck: const BoolValue(false),
   Flags.linkDependencies: const UriListValue(),
   Flags.noDeps: const BoolValue(false),
@@ -269,7 +269,7 @@
 
   final bool verify = options[Flags.verify];
 
-  final bool verifySkipPlatform = options[Flags.verifySkipPlatform];
+  final bool skipPlatformVerification = options[Flags.skipPlatformVerification];
 
   final bool dumpIr = options[Flags.dumpIr];
 
@@ -355,7 +355,7 @@
     ..omitPlatform = omitPlatform
     ..verbose = verbose
     ..verify = verify
-    ..verifySkipPlatform = verifySkipPlatform
+    ..skipPlatformVerification = skipPlatformVerification
     ..explicitExperimentalFlags = explicitExperimentalFlags
     ..environmentDefines = noDefines ? null : parsedArguments.defines
     ..nnbdMode = nnbdMode
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 088d0fd..3862cf5 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -287,9 +287,9 @@
 List<TypeArgumentIssue> findTypeArgumentIssues(Library library, DartType type,
     TypeEnvironment typeEnvironment, SubtypeCheckMode subtypeCheckMode,
     {bool allowSuperBounded = false}) {
-  List<TypeParameter> variables;
-  List<DartType> arguments;
-  List<TypeArgumentIssue> typedefRhsResult;
+  List<TypeParameter> variables = const <TypeParameter>[];
+  List<DartType> arguments = const <DartType>[];
+  List<TypeArgumentIssue> typedefRhsResult = const <TypeArgumentIssue>[];
 
   if (type is FunctionType && type.typedefType != null) {
     // [type] is a function type that is an application of a parametrized
@@ -316,64 +316,42 @@
     variables = type.typedefNode.typeParameters;
     arguments = type.typeArguments;
   } else if (type is FunctionType) {
-    List<TypeArgumentIssue> result = null;
+    List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
 
     for (TypeParameter parameter in type.typeParameters) {
-      List<TypeArgumentIssue> parameterResult = findTypeArgumentIssues(
+      result.addAll(findTypeArgumentIssues(
           library, parameter.bound, typeEnvironment, subtypeCheckMode,
-          allowSuperBounded: true);
-      if (result == null) {
-        result = parameterResult;
-      } else if (parameterResult != null) {
-        result.addAll(parameterResult);
-      }
+          allowSuperBounded: true));
     }
 
     for (DartType formal in type.positionalParameters) {
-      List<TypeArgumentIssue> parameterResult = findTypeArgumentIssues(
+      result.addAll(findTypeArgumentIssues(
           library, formal, typeEnvironment, subtypeCheckMode,
-          allowSuperBounded: true);
-      if (result == null) {
-        result = parameterResult;
-      } else if (parameterResult != null) {
-        result.addAll(parameterResult);
-      }
+          allowSuperBounded: true));
     }
 
     for (NamedType named in type.namedParameters) {
-      List<TypeArgumentIssue> parameterResult = findTypeArgumentIssues(
+      result.addAll(findTypeArgumentIssues(
           library, named.type, typeEnvironment, subtypeCheckMode,
-          allowSuperBounded: true);
-      if (result == null) {
-        result = parameterResult;
-      } else if (parameterResult != null) {
-        result.addAll(parameterResult);
-      }
+          allowSuperBounded: true));
     }
 
-    {
-      List<TypeArgumentIssue> returnTypeResult = findTypeArgumentIssues(
-          library, type.returnType, typeEnvironment, subtypeCheckMode,
-          allowSuperBounded: true);
-      if (result == null) {
-        result = returnTypeResult;
-      } else if (returnTypeResult != null) {
-        result.addAll(returnTypeResult);
-      }
-    }
+    result.addAll(findTypeArgumentIssues(
+        library, type.returnType, typeEnvironment, subtypeCheckMode,
+        allowSuperBounded: true));
 
     return result;
   } else if (type is FutureOrType) {
     variables = typeEnvironment.coreTypes.futureClass.typeParameters;
     arguments = <DartType>[type.typeArgument];
   } else {
-    return null;
+    return const <TypeArgumentIssue>[];
   }
 
-  if (variables == null) return null;
+  if (variables.isEmpty) return const <TypeArgumentIssue>[];
 
-  List<TypeArgumentIssue> result = null;
-  List<TypeArgumentIssue> argumentsResult = null;
+  List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
+  List<TypeArgumentIssue> argumentsResult = <TypeArgumentIssue>[];
 
   Map<TypeParameter, DartType> substitutionMap =
       new Map<TypeParameter, DartType>.fromIterables(variables, arguments);
@@ -381,7 +359,6 @@
     DartType argument = arguments[i];
     if (isGenericFunctionTypeOrAlias(argument)) {
       // Generic function types aren't allowed as type arguments either.
-      result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(i, argument, variables[i], type));
     } else if (variables[i].bound is! InvalidType) {
       DartType bound = substitute(variables[i].bound, substitutionMap);
@@ -389,7 +366,6 @@
         bound = legacyErasure(bound);
       }
       if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
-        result ??= <TypeArgumentIssue>[];
         result.add(new TypeArgumentIssue(i, argument, variables[i], type));
       }
     } else {
@@ -397,25 +373,15 @@
       // reported already at the time of the creation of InvalidType.
     }
 
-    List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+    argumentsResult.addAll(findTypeArgumentIssues(
         library, argument, typeEnvironment, subtypeCheckMode,
-        allowSuperBounded: true);
-    if (issues != null) {
-      argumentsResult ??= <TypeArgumentIssue>[];
-      argumentsResult.addAll(issues);
-    }
+        allowSuperBounded: true));
   }
-  if (argumentsResult != null) {
-    result ??= <TypeArgumentIssue>[];
-    result.addAll(argumentsResult);
-  }
-  if (typedefRhsResult != null) {
-    result ??= <TypeArgumentIssue>[];
-    result.addAll(typedefRhsResult);
-  }
+  result.addAll(argumentsResult);
+  result.addAll(typedefRhsResult);
 
   // [type] is regular-bounded.
-  if (result == null) return null;
+  if (result.isEmpty) return const <TypeArgumentIssue>[];
   if (!allowSuperBounded) return result;
 
   bool isCorrectSuperBounded = true;
@@ -450,16 +416,16 @@
       isCorrectSuperBounded = false;
     }
   }
-  if (argumentsResult != null) {
+  if (argumentsResult.isNotEmpty) {
     isCorrectSuperBounded = false;
   }
-  if (typedefRhsResult != null) {
+  if (typedefRhsResult.isNotEmpty) {
     isCorrectSuperBounded = false;
   }
 
   // The inverted type is regular-bounded, which means that [type] is
   // well-bounded.
-  if (isCorrectSuperBounded) return null;
+  if (isCorrectSuperBounded) return const <TypeArgumentIssue>[];
 
   // The inverted type isn't regular-bounded, but it's different from [type].
   // In this case we'll provide the programmer with the inverted type as a hint,
@@ -491,7 +457,7 @@
   assert(arguments.length == parameters.length);
   assert(bottomType == const NeverType(Nullability.nonNullable) ||
       bottomType is NullType);
-  List<TypeArgumentIssue> result;
+  List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
   Map<TypeParameter, DartType> substitutionMap = <TypeParameter, DartType>{};
   for (int i = 0; i < arguments.length; ++i) {
     substitutionMap[parameters[i]] = arguments[i];
@@ -499,11 +465,9 @@
   for (int i = 0; i < arguments.length; ++i) {
     DartType argument = arguments[i];
     if (argument is TypeParameterType && argument.promotedBound != null) {
-      result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
     } else if (isGenericFunctionTypeOrAlias(argument)) {
       // Generic function types aren't allowed as type arguments either.
-      result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
     } else if (parameters[i].bound is! InvalidType) {
       DartType bound = substitute(parameters[i].bound, substitutionMap);
@@ -511,18 +475,13 @@
         bound = legacyErasure(bound);
       }
       if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) {
-        result ??= <TypeArgumentIssue>[];
         result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
       }
     }
 
-    List<TypeArgumentIssue> issues = findTypeArgumentIssues(
+    result.addAll(findTypeArgumentIssues(
         library, argument, typeEnvironment, subtypeCheckMode,
-        allowSuperBounded: true);
-    if (issues != null) {
-      result ??= <TypeArgumentIssue>[];
-      result.addAll(issues);
-    }
+        allowSuperBounded: true));
   }
   return result;
 }
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 3d11cdf..e292a6f 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -959,6 +959,20 @@
         changes: {binaryExpression.rightOperand: isNullCheck});
   }
 
+  Future<void>
+      test_binaryExpression_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  void operator+(C/*!*/ other) {}
+}
+f(C/*?*/ c) => E(c) + c;
+''');
+    var binaryExpression = findNode.binary('E(c) + c');
+    visitSubexpression(binaryExpression, 'void',
+        changes: {binaryExpression.rightOperand: isNullCheck});
+  }
+
   Future<void> test_binaryExpression_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -972,6 +986,20 @@
         changes: {binaryExpression.leftOperand: isNullCheck});
   }
 
+  Future<void>
+      test_binaryExpression_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  void operator+(C/*!*/ other) {}
+}
+f(C/*?*/ c) => E(c) + c;
+''');
+    var binaryExpression = findNode.binary('E(c) + c');
+    visitSubexpression(binaryExpression, 'void',
+        changes: {findNode.simple('c) +'): isNullCheck});
+  }
+
   Future<void> test_binaryExpression_question_question() async {
     await analyze('''
 _f(int/*?*/ x, double/*?*/ y) {
@@ -1431,6 +1459,20 @@
   }
 
   Future<void>
+      test_functionExpressionInvocation_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  void call() {}
+}
+f(C/*?*/ c) => E(c)();
+''');
+    var functoinExpressionInvocation =
+        findNode.functionExpressionInvocation('E(c)()');
+    visitSubexpression(functoinExpressionInvocation, 'void');
+  }
+
+  Future<void>
       test_functionExpressionInvocation_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -1445,6 +1487,21 @@
         changes: {functionExpressionInvocation.function: isNullCheck});
   }
 
+  Future<void>
+      test_functionExpressionInvocation_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  void call() {}
+}
+f(C/*?*/ c) => E(c)();
+''');
+    var functionExpressionInvocation =
+        findNode.functionExpressionInvocation('E(c)()');
+    visitSubexpression(functionExpressionInvocation, 'void',
+        changes: {findNode.simple('c)()'): isNullCheck});
+  }
+
   Future<void> test_functionExpressionInvocation_function_checked() async {
     await analyze('''
 _f(Function/*?*/ func) => func();
@@ -1727,6 +1784,19 @@
     visitSubexpression(indexExpression, 'int');
   }
 
+  Future<void>
+      test_indexExpression_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  int operator[](int index) => 0;
+}
+f(C/*?*/ c) => E(c)[0];
+''');
+    var indexExpression = findNode.index('E(c)[0]');
+    visitSubexpression(indexExpression, 'int');
+  }
+
   Future<void> test_indexExpression_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -1740,6 +1810,20 @@
         changes: {indexExpression.target: isNullCheck});
   }
 
+  Future<void>
+      test_indexExpression_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  int operator[](int index) => 0;
+}
+f(C/*?*/ c) => E(c)[0];
+''');
+    var indexExpression = findNode.index('E(c)[0]');
+    visitSubexpression(indexExpression, 'int',
+        changes: {findNode.simple('c)[0]'): isNullCheck});
+  }
+
   Future<void> test_indexExpression_simple() async {
     await analyze('''
 class _C {
@@ -2023,6 +2107,19 @@
     visitSubexpression(methodInvocation, 'void');
   }
 
+  Future<void>
+      test_methodInvocation_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  void foo() {}
+}
+f(C/*?*/ c) => E(c).foo();
+''');
+    var methodInvocation = findNode.methodInvocation('E(c).foo');
+    visitSubexpression(methodInvocation, 'void');
+  }
+
   Future<void> test_methodInvocation_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -2036,6 +2133,20 @@
         changes: {methodInvocation.target: isNullCheck});
   }
 
+  Future<void>
+      test_methodInvocation_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  void foo() {}
+}
+f(C/*?*/ c) => E(c).foo();
+''');
+    var methodInvocation = findNode.methodInvocation('E(c).foo');
+    visitSubexpression(methodInvocation, 'void',
+        changes: {findNode.simple('c).foo'): isNullCheck});
+  }
+
   Future<void> test_methodInvocation_function_call_nullCheck() async {
     await analyze('''
 f(void Function()/*?*/ x) => x.call();
@@ -2794,6 +2905,19 @@
     visitSubexpression(prefixExpression, 'C');
   }
 
+  Future<void>
+      test_prefixExpression_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  C operator-() => C();
+}
+f(C/*?*/ c) => -E(c);
+''');
+    var prefixExpression = findNode.prefix('-E(c)');
+    visitSubexpression(prefixExpression, 'C');
+  }
+
   Future<void> test_prefixExpression_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -2807,6 +2931,20 @@
         changes: {prefixExpression.operand: isNullCheck});
   }
 
+  Future<void>
+      test_prefixExpression_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  C operator-() => C();
+}
+f(C/*?*/ c) => -E(c);
+''');
+    var prefixExpression = findNode.prefix('-E(c)');
+    visitSubexpression(prefixExpression, 'C',
+        changes: {findNode.simple('c);'): isNullCheck});
+  }
+
   Future<void> test_prefixExpression_increment_undoes_promotion() async {
     await analyze('''
 abstract class _C {
@@ -2944,6 +3082,18 @@
     visitSubexpression(propertyAccess, 'int');
   }
 
+  Future<void> test_propertyAccess_extensionMember_allowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*?*/ {
+  int get foo => 0;
+}
+f(C/*?*/ Function() g) => E(g()).foo;
+''');
+    var propertyAccess = findNode.propertyAccess('E(g()).foo');
+    visitSubexpression(propertyAccess, 'int');
+  }
+
   Future<void> test_propertyAccess_extensionMember_disallowsNull() async {
     await analyze('''
 class C {}
@@ -2957,6 +3107,21 @@
         changes: {propertyAccess.target: isNullCheck});
   }
 
+  Future<void>
+      test_propertyAccess_extensionMember_disallowsNull_explicit() async {
+    await analyze('''
+class C {}
+extension E on C/*!*/ {
+  int get foo => 0;
+}
+f(C/*?*/ Function() g) => E(g()).foo;
+''');
+    var propertyAccess = findNode.propertyAccess('E(g()).foo');
+    visitSubexpression(propertyAccess, 'int', changes: {
+      findNode.functionExpressionInvocation('g()).foo'): isNullCheck
+    });
+  }
+
   Future<void> test_propertyAccess_field_nonNullable() async {
     await analyze('''
 class _C {
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index b6e07e5..0ec7acd 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -1258,7 +1258,7 @@
 
     var compilerArguments = [
       '--verify',
-      '--verify-skip-platform',
+      '--skip-platform-verification',
       "-o",
       outputFileName,
       "--platform",
diff --git a/pkg/wasm/README.md b/pkg/wasm/README.md
index 8bf6c4b..ce842cd 100644
--- a/pkg/wasm/README.md
+++ b/pkg/wasm/README.md
@@ -2,3 +2,7 @@
 
 This package provides utilities for loading and running WASM modules. It is
 built on top of the [Wasmer](https://github.com/wasmerio/wasmer) runtime.
+
+## Setup
+
+Run `dart bin/setup.dart` to build the Wasmer runtime.
diff --git a/pkg/wasm/bin/.gitignore b/pkg/wasm/bin/.gitignore
new file mode 100644
index 0000000..8b44e90
--- /dev/null
+++ b/pkg/wasm/bin/.gitignore
@@ -0,0 +1,2 @@
+Cargo.lock
+/out
diff --git a/pkg/wasm/bin/Cargo.toml b/pkg/wasm/bin/Cargo.toml
new file mode 100644
index 0000000..a476549
--- /dev/null
+++ b/pkg/wasm/bin/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "wasmer"
+version = "1.0.0-alpha5"
+
+[lib]
+name = "wasmer"
+crate-type = ["staticlib"]
+path = "wasmer.rs"
+
+[dependencies.wasmer-c-api]
+version = "1.0.0-alpha5"
+default-features = false
+features = ["jit", "cranelift", "wasi"]
diff --git a/pkg/wasm/bin/finalizers.cc b/pkg/wasm/bin/finalizers.cc
new file mode 100644
index 0000000..192277e
--- /dev/null
+++ b/pkg/wasm/bin/finalizers.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "include/dart_api.h"
+#include "include/dart_api_dl.h"
+
+#define FINALIZER(type)                                                        \
+  extern "C" void wasm_##type##_delete(void*);                                 \
+  extern "C" void wasm_##type##_finalizer(void*, void* native_object) {        \
+    wasm_##type##_delete(native_object);                                       \
+  }                                                                            \
+  DART_EXPORT void set_finalizer_for_##type(Dart_Handle dart_object,           \
+                                            void* native_object) {             \
+    Dart_NewFinalizableHandle_DL(dart_object, native_object, 0,                \
+                                 wasm_##type##_finalizer);                     \
+  }
+
+FINALIZER(engine);
+FINALIZER(store);
+FINALIZER(module);
+FINALIZER(instance);
+FINALIZER(trap);
+FINALIZER(memorytype);
+FINALIZER(memory);
+FINALIZER(func);
diff --git a/pkg/wasm/bin/setup.dart b/pkg/wasm/bin/setup.dart
new file mode 100644
index 0000000..2e8fcad
--- /dev/null
+++ b/pkg/wasm/bin/setup.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Builds the wasmer runtime library, to by used by package:wasm. Requires
+// rustc, cargo, clang, and clang++. If a target triple is not specified, it
+// will default to the host target.
+// Usage: dart setup.dart [target-triple]
+
+import 'dart:convert';
+import 'dart:io';
+
+Uri getSdkDir() {
+  // The common case, and how cli_util.dart computes the Dart SDK directory,
+  // path.dirname called twice on Platform.resolvedExecutable.
+  final exe = Uri.file(Platform.resolvedExecutable);
+  final commonSdkDir = exe.resolve('../..');
+  if (Directory(commonSdkDir.path).existsSync()) {
+    return commonSdkDir;
+  }
+
+  // This is the less common case where the user is in the checked out Dart
+  // SDK, and is executing dart via:
+  // ./out/ReleaseX64/dart ...
+  final checkedOutSdkDir = exe.resolve('../dart-sdk');
+  if (Directory(checkedOutSdkDir.path).existsSync()) {
+    return checkedOutSdkDir;
+  }
+
+  // If neither returned above, we return the common case:
+  return commonSdkDir;
+}
+
+String getOutLib(String target) {
+  final os = RegExp(r'^.*-.*-(.*)').firstMatch(target)?.group(1) ?? '';
+  if (os == 'darwin' || os == 'ios') {
+    return 'libwasmer.dylib';
+  } else if (os == 'windows') {
+    return 'wasmer.dll';
+  }
+  return 'libwasmer.so';
+}
+
+getTargetTriple() async {
+  final process = await Process.start('rustc', ['--print', 'cfg']);
+  process.stderr
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen((line) => stderr.writeln(line));
+  final cfg = {};
+  await process.stdout
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen((line) {
+    final match = RegExp(r'^([^=]+)="(.*)"$').firstMatch(line);
+    if (match != null) cfg[match.group(1)] = match.group(2);
+  }).asFuture();
+  String arch = cfg['target_arch'] ?? 'unknown';
+  String vendor = cfg['target_vendor'] ?? 'unknown';
+  String os = cfg['target_os'] ?? 'unknown';
+  String env = cfg['target_env'] ?? 'unknown';
+  return '$arch-$vendor-$os-$env';
+}
+
+run(String exe, List<String> args) async {
+  print('\n$exe ${args.join(' ')}\n');
+  final process = await Process.start(exe, args);
+  process.stdout
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen((line) => print(line));
+  process.stderr
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen((line) => stderr.writeln(line));
+  final exitCode = await process.exitCode;
+  if (exitCode != 0) {
+    print('Command failed with exit code ${exitCode}');
+    exit(exitCode);
+  }
+}
+
+main(List<String> args) async {
+  if (args.length > 1) {
+    print('Usage: dart setup.dart [target-triple]');
+    exit(1);
+  }
+
+  final target = args.length >= 1 ? args[0] : await getTargetTriple();
+  final sdkDir = getSdkDir();
+  final binDir = Platform.script;
+  final outLib = binDir.resolve('out/' + getOutLib(target)).path;
+
+  print('Dart SDK directory: ${sdkDir.path}');
+  print('Script directory: ${binDir.path}');
+  print('Target: $target');
+  print('Output library: $outLib');
+
+  // Build wasmer crate.
+  await run('cargo', [
+    'build',
+    '--target',
+    target,
+    '--target-dir',
+    binDir.resolve('out').path,
+    '--manifest-path',
+    binDir.resolve('Cargo.toml').path,
+    '--release'
+  ]);
+
+  // Build dart_api_dl.o.
+  await run('clang', [
+    '-DDART_SHARED_LIB',
+    '-DNDEBUG',
+    '-fno-exceptions',
+    '-fPIC',
+    '-O3',
+    '-target',
+    target,
+    '-c',
+    sdkDir.resolve('runtime/include/dart_api_dl.c').path,
+    '-o',
+    binDir.resolve('out/dart_api_dl.o').path
+  ]);
+
+  // Build finalizers.o.
+  await run('clang++', [
+    '-DDART_SHARED_LIB',
+    '-DNDEBUG',
+    '-fno-exceptions',
+    '-fno-rtti',
+    '-fPIC',
+    '-O3',
+    '-std=c++11',
+    '-target',
+    target,
+    '-I',
+    sdkDir.resolve('runtime').path,
+    '-c',
+    binDir.resolve('finalizers.cc').path,
+    '-o',
+    binDir.resolve('out/finalizers.o').path
+  ]);
+
+  // Link wasmer, dart_api_dl, and finalizers to create the output library.
+  await run('clang++', [
+    '-shared',
+    '-Wl,--no-as-needed',
+    '-Wl,--fatal-warnings',
+    '-Wl,-z,now',
+    '-Wl,-z,noexecstack',
+    '-Wl,-z,relro',
+    '-Wl,--build-id=none',
+    '-fPIC',
+    '-Wl,-O1',
+    '-Wl,--gc-sections',
+    '-target',
+    target,
+    binDir.resolve('out/dart_api_dl.o').path,
+    binDir.resolve('out/finalizers.o').path,
+    binDir.resolve('out/' + target + '/release/libwasmer.a').path,
+    '-o',
+    outLib
+  ]);
+}
diff --git a/pkg/wasm/bin/wasmer.rs b/pkg/wasm/bin/wasmer.rs
new file mode 100644
index 0000000..c4bd6e5
--- /dev/null
+++ b/pkg/wasm/bin/wasmer.rs
@@ -0,0 +1 @@
+pub extern crate wasmer_c_api;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index fc4d13a..a9fd5ba 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4564,7 +4564,6 @@
 }
 
 TEST_CASE(DartAPI_TypeGetParameterizedTypes) {
-  // TODO(dartbug.com/40176): Clean up this test once the API supports NNBD.
   const char* kScriptChars =
       "class MyClass0<A, B> {\n"
       "}\n"
@@ -4638,7 +4637,10 @@
 
   // Now create objects of the type and validate the object type matches
   // the one returned above. Also get the runtime type of the object and
-  // verify that it matches the type returned above.
+  // verify that it matches the type returned above. Note: we use
+  // Dart_ObjectEquals instead of Dart_IdentityEquals since we are comparing
+  // type literals with non-literals which would fail in unsound null safety
+  // mode.
   // MyClass0<int, double> type.
   Dart_Handle type0_obj = Dart_Invoke(lib, NewString("getMyClass0"), 0, NULL);
   EXPECT_VALID(type0_obj);
@@ -4647,7 +4649,10 @@
   EXPECT(instanceOf);
   type0_obj = Dart_Invoke(lib, NewString("getMyClass0Type"), 0, NULL);
   EXPECT_VALID(type0_obj);
-  EXPECT(Dart_IdentityEquals(type0_obj, myclass0_type));
+
+  bool equal = false;
+  EXPECT_VALID(Dart_ObjectEquals(type0_obj, myclass0_type, &equal));
+  EXPECT(equal);
 
   // MyClass1<List<int>, List> type.
   Dart_Handle type1_obj = Dart_Invoke(lib, NewString("getMyClass1"), 0, NULL);
@@ -4656,7 +4661,9 @@
   EXPECT(instanceOf);
   type1_obj = Dart_Invoke(lib, NewString("getMyClass1Type"), 0, NULL);
   EXPECT_VALID(type1_obj);
-  EXPECT(Dart_IdentityEquals(type1_obj, myclass1_type));
+
+  EXPECT_VALID(Dart_ObjectEquals(type1_obj, myclass1_type, &equal));
+  EXPECT(equal);
 
   // MyClass0<double, int> type.
   type0_obj = Dart_Invoke(lib, NewString("getMyClass0_1"), 0, NULL);
@@ -4665,7 +4672,8 @@
   EXPECT(!instanceOf);
   type0_obj = Dart_Invoke(lib, NewString("getMyClass0_1Type"), 0, NULL);
   EXPECT_VALID(type0_obj);
-  EXPECT(!Dart_IdentityEquals(type0_obj, myclass0_type));
+  EXPECT_VALID(Dart_ObjectEquals(type0_obj, myclass0_type, &equal));
+  EXPECT(!equal);
 
   // MyClass1<List<int>, List<double>> type.
   type1_obj = Dart_Invoke(lib, NewString("getMyClass1_1"), 0, NULL);
@@ -4674,7 +4682,8 @@
   EXPECT(instanceOf);
   type1_obj = Dart_Invoke(lib, NewString("getMyClass1_1Type"), 0, NULL);
   EXPECT_VALID(type1_obj);
-  EXPECT(!Dart_IdentityEquals(type1_obj, myclass1_type));
+  EXPECT_VALID(Dart_ObjectEquals(type1_obj, myclass1_type, &equal));
+  EXPECT(!equal);
 }
 
 static void TestFieldOk(Dart_Handle container,
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 95a8aff..8363b4a 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -49,9 +49,8 @@
  * ## Status: Unstable
  *
  * The dart:mirrors library is unstable and its API might change slightly as a
- * result of user feedback. This library is platform dependent and therefore it
- * has implementations for both dart2js and the Dart VM. Both are under
- * development and may not support all operations yet.
+ * result of user feedback. This library is only supported by the Dart VM and
+ * only available on some platforms.
  *
  * {@category VM}
  */
diff --git a/tests/language/extension_methods/static_extension_operator_override_error_test.dart b/tests/language/extension_methods/static_extension_operator_override_error_test.dart
new file mode 100644
index 0000000..acd3ab5
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_operator_override_error_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for https://github.com/dart-lang/sdk/issues/43114.
+
+class A {}
+
+extension E on A {
+  String operator +(int other) => '';
+}
+
+f(A a, int b) {
+  int i = E(a) + b;
+  //      ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //           ^
+  // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
+}
+
+main() {
+  f(A(), 0);
+}
diff --git a/tests/language_2/extension_methods/static_extension_operator_override_error_test.dart b/tests/language_2/extension_methods/static_extension_operator_override_error_test.dart
new file mode 100644
index 0000000..acd3ab5
--- /dev/null
+++ b/tests/language_2/extension_methods/static_extension_operator_override_error_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for https://github.com/dart-lang/sdk/issues/43114.
+
+class A {}
+
+extension E on A {
+  String operator +(int other) => '';
+}
+
+f(A a, int b) {
+  int i = E(a) + b;
+  //      ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  //           ^
+  // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
+}
+
+main() {
+  f(A(), 0);
+}
diff --git a/tests/standalone/io/http_parser_connect_method.dart b/tests/standalone/io/http_parser_connect_method.dart
deleted file mode 100644
index f543bcd..0000000
--- a/tests/standalone/io/http_parser_connect_method.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import "dart:io";
-import "package:expect/expect.dart";
-
-test(String header, value) async {
-  final connect = "CONNECT";
-  var server = await HttpServer.bind("127.0.0.1", 0);
-  server.listen((HttpRequest request) {
-    Expect.equals(connect, request.method);
-    request.response.statusCode = 200;
-    request.response.headers.add(header, value);
-    request.response.close();
-  });
-
-  var completer = Completer();
-  HttpClient client = HttpClient();
-  client
-      .open(connect, "127.0.0.1", server.port, "/")
-      .then((HttpClientRequest request) {
-    return request.close();
-  }).then((HttpClientResponse response) {
-    Expect.isTrue(response.statusCode == 200);
-    Expect.isNull(response.headers[header]);
-    client.close();
-    server.close();
-    completer.complete();
-  });
-
-  await completer.future;
-}
-
-main() async {
-  await test(HttpHeaders.contentLengthHeader, 0);
-  await test(HttpHeaders.transferEncodingHeader, 'chunked');
-}
diff --git a/tests/standalone/io/http_parser_connect_method_test.dart b/tests/standalone/io/http_parser_connect_method_test.dart
new file mode 100644
index 0000000..7a11fd9
--- /dev/null
+++ b/tests/standalone/io/http_parser_connect_method_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+Future<void> test(String header, value) async {
+  final connect = "CONNECT";
+  final server = await HttpServer.bind("127.0.0.1", 0);
+  server.listen((HttpRequest request) {
+    Expect.equals(connect, request.method);
+    request.response.statusCode = 200;
+    request.response.headers.add(header, value);
+    request.response.close();
+  });
+
+  final completer = Completer<void>();
+  HttpClient client = HttpClient();
+  client
+      .open(connect, "127.0.0.1", server.port, "/")
+      .then((HttpClientRequest request) {
+    return request.close();
+  }).then((HttpClientResponse response) {
+    Expect.equals(200, response.statusCode);
+    // Headers except Content-Length and Transfer-Encoding header will be read.
+    if (header == HttpHeaders.contentLengthHeader ||
+        header == HttpHeaders.transferEncodingHeader) {
+      Expect.isNull(response.headers[header]);
+    } else {
+      final list = response.headers[header];
+      Expect.isNotNull(list);
+      Expect.equals(1, list!.length);
+      Expect.equals(value, list[0]);
+    }
+
+    client.close(force: true);
+    server.close();
+    completer.complete();
+  });
+
+  await completer.future;
+}
+
+Future<void> runTests() async {
+  await test(HttpHeaders.contentLengthHeader, 0);
+  await test(HttpHeaders.transferEncodingHeader, 'chunked');
+  await test('testHeader', 'testValue');
+}
+
+main() {
+  asyncTest(runTests);
+}
diff --git a/tests/standalone/io/http_parser_header_add_test.dart b/tests/standalone/io/http_parser_header_add_test.dart
new file mode 100644
index 0000000..4421733
--- /dev/null
+++ b/tests/standalone/io/http_parser_header_add_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Verify that FormatException is thrown when HttpClient userAgent has
+// invalid value.
+
+import "dart:async";
+import "dart:io";
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+Future<void> testFormatException() async {
+  final server = await HttpServer.bind("127.0.0.1", 0);
+  server.listen((HttpRequest request) {
+    request.response.statusCode = 200;
+    request.response.close();
+  });
+
+  final completer = Completer<void>();
+  // The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
+  final client = HttpClient()..userAgent = 'Bob’s browser';
+  asyncExpectThrows<FormatException>(() async {
+    try {
+      await client.open("CONNECT", "127.0.0.1", server.port, "/");
+    } finally {
+      client.close(force: true);
+      server.close();
+      completer.complete();
+    }
+  });
+  await completer.future;
+}
+
+main() {
+  asyncTest(testFormatException);
+}
diff --git a/tests/standalone/io/socket_hang_test.dart b/tests/standalone/io/socket_hang_test.dart
index 2231844..810d2a1 100644
--- a/tests/standalone/io/socket_hang_test.dart
+++ b/tests/standalone/io/socket_hang_test.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert';
-import 'dart:io' as io;
+import 'dart:io';
 
-void main(List<String> args) async {
+import 'package:expect/expect.dart';
+
+// A regression test for: https://github.com/dart-lang/sdk/issues/40589
+Future<void> main(List<String> args) async {
   if (args.length != 0) {
     for (int i = 0; i < 100000; i++) {
       print('line $i');
@@ -14,11 +16,14 @@
     return;
   } else {
     // Create child process and keeps writing into stdout.
-    final p = await io.Process.start(
-        io.Platform.executable, [io.Platform.script.toFilePath(), 'child']);
-    p.stdout.transform(utf8.decoder).listen((x) => print('stdout: $x'));
-    p.stderr.transform(utf8.decoder).listen((x) => print('stderr: $x'));
+    final p = await Process.start(
+        Platform.executable, [Platform.script.toFilePath(), 'child']);
+    p.stdout.drain();
+    p.stderr.drain();
     final exitCode = await p.exitCode;
-    print('process exited with ${exitCode}');
+    if (exitCode != 0) {
+      Expect.fail('process failed with ${exitCode}');
+    }
+    return;
   }
 }
diff --git a/tests/standalone_2/io/http_parser_connect_method.dart b/tests/standalone_2/io/http_parser_connect_method.dart
deleted file mode 100644
index f543bcd..0000000
--- a/tests/standalone_2/io/http_parser_connect_method.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:async";
-import "dart:io";
-import "package:expect/expect.dart";
-
-test(String header, value) async {
-  final connect = "CONNECT";
-  var server = await HttpServer.bind("127.0.0.1", 0);
-  server.listen((HttpRequest request) {
-    Expect.equals(connect, request.method);
-    request.response.statusCode = 200;
-    request.response.headers.add(header, value);
-    request.response.close();
-  });
-
-  var completer = Completer();
-  HttpClient client = HttpClient();
-  client
-      .open(connect, "127.0.0.1", server.port, "/")
-      .then((HttpClientRequest request) {
-    return request.close();
-  }).then((HttpClientResponse response) {
-    Expect.isTrue(response.statusCode == 200);
-    Expect.isNull(response.headers[header]);
-    client.close();
-    server.close();
-    completer.complete();
-  });
-
-  await completer.future;
-}
-
-main() async {
-  await test(HttpHeaders.contentLengthHeader, 0);
-  await test(HttpHeaders.transferEncodingHeader, 'chunked');
-}
diff --git a/tests/standalone_2/io/http_parser_connect_method_test.dart b/tests/standalone_2/io/http_parser_connect_method_test.dart
new file mode 100644
index 0000000..03bda12
--- /dev/null
+++ b/tests/standalone_2/io/http_parser_connect_method_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+Future<void> test(String header, value) async {
+  final connect = "CONNECT";
+  final server = await HttpServer.bind("127.0.0.1", 0);
+  server.listen((HttpRequest request) {
+    Expect.equals(connect, request.method);
+    request.response.statusCode = 200;
+    request.response.headers.add(header, value);
+    request.response.close();
+  });
+
+  final completer = Completer<void>();
+  HttpClient client = HttpClient();
+  client
+      .open(connect, "127.0.0.1", server.port, "/")
+      .then((HttpClientRequest request) {
+    return request.close();
+  }).then((HttpClientResponse response) {
+    Expect.equals(200, response.statusCode);
+    // Headers except Content-Length and Transfer-Encoding header will be read.
+    if (header == HttpHeaders.contentLengthHeader ||
+        header == HttpHeaders.transferEncodingHeader) {
+      Expect.isNull(response.headers[header]);
+    } else {
+      Expect.isNotNull(response.headers[header]);
+      Expect.equals(1, response.headers[header].length);
+      Expect.equals(value, response.headers[header][0]);
+    }
+
+    client.close(force: true);
+    server.close();
+    completer.complete();
+  });
+
+  await completer.future;
+}
+
+Future<void> runTests() async {
+  await test(HttpHeaders.contentLengthHeader, 0);
+  await test(HttpHeaders.transferEncodingHeader, 'chunked');
+  await test('testHeader', 'testValue');
+}
+
+main() {
+  asyncTest(runTests);
+}
diff --git a/tests/standalone_2/io/http_parser_header_add_test.dart b/tests/standalone_2/io/http_parser_header_add_test.dart
new file mode 100644
index 0000000..4421733
--- /dev/null
+++ b/tests/standalone_2/io/http_parser_header_add_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Verify that FormatException is thrown when HttpClient userAgent has
+// invalid value.
+
+import "dart:async";
+import "dart:io";
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+Future<void> testFormatException() async {
+  final server = await HttpServer.bind("127.0.0.1", 0);
+  server.listen((HttpRequest request) {
+    request.response.statusCode = 200;
+    request.response.close();
+  });
+
+  final completer = Completer<void>();
+  // The ’ character is U+2019 RIGHT SINGLE QUOTATION MARK.
+  final client = HttpClient()..userAgent = 'Bob’s browser';
+  asyncExpectThrows<FormatException>(() async {
+    try {
+      await client.open("CONNECT", "127.0.0.1", server.port, "/");
+    } finally {
+      client.close(force: true);
+      server.close();
+      completer.complete();
+    }
+  });
+  await completer.future;
+}
+
+main() {
+  asyncTest(testFormatException);
+}
diff --git a/tests/standalone_2/io/socket_hang_test.dart b/tests/standalone_2/io/socket_hang_test.dart
index 2231844..810d2a1 100644
--- a/tests/standalone_2/io/socket_hang_test.dart
+++ b/tests/standalone_2/io/socket_hang_test.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:convert';
-import 'dart:io' as io;
+import 'dart:io';
 
-void main(List<String> args) async {
+import 'package:expect/expect.dart';
+
+// A regression test for: https://github.com/dart-lang/sdk/issues/40589
+Future<void> main(List<String> args) async {
   if (args.length != 0) {
     for (int i = 0; i < 100000; i++) {
       print('line $i');
@@ -14,11 +16,14 @@
     return;
   } else {
     // Create child process and keeps writing into stdout.
-    final p = await io.Process.start(
-        io.Platform.executable, [io.Platform.script.toFilePath(), 'child']);
-    p.stdout.transform(utf8.decoder).listen((x) => print('stdout: $x'));
-    p.stderr.transform(utf8.decoder).listen((x) => print('stderr: $x'));
+    final p = await Process.start(
+        Platform.executable, [Platform.script.toFilePath(), 'child']);
+    p.stdout.drain();
+    p.stderr.drain();
     final exitCode = await p.exitCode;
-    print('process exited with ${exitCode}');
+    if (exitCode != 0) {
+      Expect.fail('process failed with ${exitCode}');
+    }
+    return;
   }
 }
diff --git a/tools/VERSION b/tools/VERSION
index 4aae745..e3cb26f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 255
+PRERELEASE 256
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/gn.py b/tools/gn.py
index 2af3931..0fd17d8 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -434,6 +434,10 @@
                         help='Generate an IDE file.',
                         default=os_has_ide(HOST_OS),
                         action='store_true')
+    parser.add_argument('--export-compile-commands',
+                        help='Export compile_commands.json database file.',
+                        default=False,
+                        action='store_true')
     parser.add_argument(
         '--target-sysroot',
         '-s',
@@ -513,6 +517,8 @@
     gn_args += GetGNArgs(args)
     if args.ide:
         command.append(ide_switch(HOST_OS))
+    if args.export_compile_commands:
+        command.append('--export-compile-commands')
     command.append('--args=%s' % ' '.join(gn_args))
 
     return command