Version 2.12.0-37.0.dev

Merge commit '2f9cb8e81b02fcf6a0cfb0d6e722f4a6e2bd6341' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 37b095d9..b5db21c 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.30.0
+  1.31.0
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -4239,152 +4239,47 @@
     
   <dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FIELD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">METHOD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">PARAMETER</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">SETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
     <p>
       The hover information associated with a specific location.
     </p>
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 25f5a64..61ada08 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.30.0';
+const String PROTOCOL_VERSION = '1.31.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index ce3c063..adbfc57 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -15,7 +15,6 @@
     hide AnalysisOptions;
 import 'package:analysis_server/src/analysis_server_abstract.dart';
 import 'package:analysis_server/src/channel/channel.dart';
-import 'package:analysis_server/src/computer/computer_highlights.dart';
 import 'package:analysis_server/src/computer/computer_highlights2.dart';
 import 'package:analysis_server/src/computer/new_notifications.dart';
 import 'package:analysis_server/src/context_manager.dart';
@@ -601,8 +600,6 @@
 
 /// Various IDE options.
 class AnalysisServerOptions {
-  bool useAnalysisHighlight2 = false;
-
   String fileReadMode = 'as-is';
   String newAnalysisDriverLog;
 
@@ -829,11 +826,7 @@
   }
 
   List<HighlightRegion> _computeHighlightRegions(CompilationUnit unit) {
-    if (analysisServer.options.useAnalysisHighlight2) {
-      return DartUnitHighlightsComputer2(unit).compute();
-    } else {
-      return DartUnitHighlightsComputer(unit).compute();
-    }
+    return DartUnitHighlightsComputer2(unit).compute();
   }
 
   server.AnalysisNavigationParams _computeNavigationParams(
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
deleted file mode 100644
index 3c280ff..0000000
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
-
-/// A computer for [HighlightRegion]s in a Dart [CompilationUnit].
-class DartUnitHighlightsComputer {
-  final CompilationUnit _unit;
-
-  final List<HighlightRegion> _regions = <HighlightRegion>[];
-
-  DartUnitHighlightsComputer(this._unit);
-
-  /// Returns the computed highlight regions, not `null`.
-  List<HighlightRegion> compute() {
-    _unit.accept(_DartUnitHighlightsComputerVisitor(this));
-    _addCommentRanges();
-    return _regions;
-  }
-
-  void _addCommentRanges() {
-    var token = _unit.beginToken;
-    while (token != null) {
-      Token commentToken = token.precedingComments;
-      while (commentToken != null) {
-        HighlightRegionType highlightType;
-        if (commentToken.type == TokenType.MULTI_LINE_COMMENT) {
-          if (commentToken.lexeme.startsWith('/**')) {
-            highlightType = HighlightRegionType.COMMENT_DOCUMENTATION;
-          } else {
-            highlightType = HighlightRegionType.COMMENT_BLOCK;
-          }
-        }
-        if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
-          highlightType = HighlightRegionType.COMMENT_END_OF_LINE;
-        }
-        if (highlightType != null) {
-          _addRegion_token(commentToken, highlightType);
-        }
-        commentToken = commentToken.next;
-      }
-      if (token.type == TokenType.EOF) {
-        // Only exit the loop *after* processing the EOF token as it may
-        // have preceeding comments.
-        break;
-      }
-      token = token.next;
-    }
-  }
-
-  void _addIdentifierRegion(SimpleIdentifier node) {
-    if (_addIdentifierRegion_keyword(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_class(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_constructor(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_dynamicType(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_getterSetterDeclaration(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_field(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_function(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_functionTypeAlias(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_importPrefix(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_label(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_localVariable(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_method(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_parameter(node)) {
-      return;
-    }
-    if (_addIdentifierRegion_typeParameter(node)) {
-      return;
-    }
-    _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT);
-  }
-
-  void _addIdentifierRegion_annotation(Annotation node) {
-    var arguments = node.arguments;
-    if (arguments == null) {
-      _addRegion_node(node, HighlightRegionType.ANNOTATION);
-    } else {
-      _addRegion_nodeStart_tokenEnd(
-          node, arguments.beginToken, HighlightRegionType.ANNOTATION);
-      _addRegion_token(arguments.endToken, HighlightRegionType.ANNOTATION);
-    }
-  }
-
-  bool _addIdentifierRegion_class(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ClassElement) {
-      return false;
-    }
-    ClassElement classElement = element;
-    // prepare type
-    HighlightRegionType type;
-    if (node.parent is TypeName &&
-        node.parent.parent is ConstructorName &&
-        node.parent.parent.parent is InstanceCreationExpression) {
-      // new Class()
-      type = HighlightRegionType.CONSTRUCTOR;
-    } else if (classElement.isEnum) {
-      type = HighlightRegionType.ENUM;
-    } else {
-      type = HighlightRegionType.CLASS;
-    }
-    // add region
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_constructor(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ConstructorElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR);
-  }
-
-  bool _addIdentifierRegion_dynamicType(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is VariableElement) {
-      var staticType = element.type;
-      if (staticType == null || !staticType.isDynamic) {
-        return false;
-      }
-      return _addRegion_node(node, HighlightRegionType.DYNAMIC_TYPE);
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_field(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is FieldFormalParameterElement) {
-      element = (element as FieldFormalParameterElement).field;
-    }
-    if (element is PropertyAccessorElement) {
-      element = (element as PropertyAccessorElement).variable;
-    }
-    // prepare type
-    HighlightRegionType type;
-    if (element is FieldElement) {
-      var enclosingElement = element.enclosingElement;
-      if (enclosingElement is ClassElement && enclosingElement.isEnum) {
-        type = HighlightRegionType.ENUM_CONSTANT;
-      } else if (element.isStatic) {
-        type = HighlightRegionType.FIELD_STATIC;
-      } else {
-        type = HighlightRegionType.FIELD;
-      }
-    } else if (element is TopLevelVariableElement) {
-      type = HighlightRegionType.TOP_LEVEL_VARIABLE;
-    }
-    // add region
-    if (type != null) {
-      return _addRegion_node(node, type);
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_function(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! FunctionElement) {
-      return false;
-    }
-    HighlightRegionType type;
-    if (node.inDeclarationContext()) {
-      type = HighlightRegionType.FUNCTION_DECLARATION;
-    } else {
-      type = HighlightRegionType.FUNCTION;
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! FunctionTypeAliasElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS);
-  }
-
-  bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) {
-    // should be declaration
-    var parent = node.parent;
-    if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) {
-      return false;
-    }
-    // should be property accessor
-    var element = node.writeOrReadElement;
-    if (element is! PropertyAccessorElement) {
-      return false;
-    }
-    // getter or setter
-    var propertyAccessorElement = element as PropertyAccessorElement;
-    if (propertyAccessorElement.isGetter) {
-      return _addRegion_node(node, HighlightRegionType.GETTER_DECLARATION);
-    } else {
-      return _addRegion_node(node, HighlightRegionType.SETTER_DECLARATION);
-    }
-  }
-
-  bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! PrefixElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX);
-  }
-
-  bool _addIdentifierRegion_keyword(SimpleIdentifier node) {
-    var name = node.name;
-    if (name == 'void') {
-      return _addRegion_node(node, HighlightRegionType.KEYWORD);
-    }
-    return false;
-  }
-
-  bool _addIdentifierRegion_label(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! LabelElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.LABEL);
-  }
-
-  bool _addIdentifierRegion_localVariable(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! LocalVariableElement) {
-      return false;
-    }
-    // OK
-    HighlightRegionType type;
-    if (node.inDeclarationContext()) {
-      type = HighlightRegionType.LOCAL_VARIABLE_DECLARATION;
-    } else {
-      type = HighlightRegionType.LOCAL_VARIABLE;
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_method(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! MethodElement) {
-      return false;
-    }
-    var methodElement = element as MethodElement;
-    var isStatic = methodElement.isStatic;
-    // OK
-    HighlightRegionType type;
-    if (node.inDeclarationContext()) {
-      if (isStatic) {
-        type = HighlightRegionType.METHOD_DECLARATION_STATIC;
-      } else {
-        type = HighlightRegionType.METHOD_DECLARATION;
-      }
-    } else {
-      if (isStatic) {
-        type = HighlightRegionType.METHOD_STATIC;
-      } else {
-        type = HighlightRegionType.METHOD;
-      }
-    }
-    return _addRegion_node(node, type);
-  }
-
-  bool _addIdentifierRegion_parameter(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! ParameterElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.PARAMETER);
-  }
-
-  bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! TypeParameterElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER);
-  }
-
-  void _addRegion(int offset, int length, HighlightRegionType type) {
-    _regions.add(HighlightRegion(type, offset, length));
-  }
-
-  bool _addRegion_node(AstNode node, HighlightRegionType type) {
-    var offset = node.offset;
-    var length = node.length;
-    _addRegion(offset, length, type);
-    return true;
-  }
-
-  void _addRegion_nodeStart_tokenEnd(
-      AstNode a, Token b, HighlightRegionType type) {
-    var offset = a.offset;
-    var end = b.end;
-    _addRegion(offset, end - offset, type);
-  }
-
-  void _addRegion_token(Token token, HighlightRegionType type) {
-    if (token != null) {
-      var offset = token.offset;
-      var length = token.length;
-      _addRegion(offset, length, type);
-    }
-  }
-
-  void _addRegion_tokenStart_tokenEnd(
-      Token a, Token b, HighlightRegionType type) {
-    var offset = a.offset;
-    var end = b.end;
-    _addRegion(offset, end - offset, type);
-  }
-}
-
-/// An AST visitor for [DartUnitHighlightsComputer].
-class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
-  final DartUnitHighlightsComputer computer;
-
-  _DartUnitHighlightsComputerVisitor(this.computer);
-
-  @override
-  void visitAnnotation(Annotation node) {
-    computer._addIdentifierRegion_annotation(node);
-    super.visitAnnotation(node);
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN);
-    super.visitAsExpression(node);
-  }
-
-  @override
-  void visitAssertStatement(AssertStatement node) {
-    computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD);
-    super.visitAssertStatement(node);
-  }
-
-  @override
-  void visitAwaitExpression(AwaitExpression node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    super.visitAwaitExpression(node);
-  }
-
-  @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    _addRegions_functionBody(node);
-    super.visitBlockFunctionBody(node);
-  }
-
-  @override
-  void visitBooleanLiteral(BooleanLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.KEYWORD);
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN);
-    super.visitBooleanLiteral(node);
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD);
-    super.visitBreakStatement(node);
-  }
-
-  @override
-  void visitCatchClause(CatchClause node) {
-    computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitCatchClause(node);
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    super.visitClassDeclaration(node);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    super.visitClassTypeAlias(node);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.factoryKeyword, HighlightRegionType.BUILT_IN);
-    super.visitConstructorDeclaration(node);
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    computer._addRegion_token(
-        node.continueKeyword, HighlightRegionType.KEYWORD);
-    super.visitContinueStatement(node);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitDefaultFormalParameter(node);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
-    super.visitDoStatement(node);
-  }
-
-  @override
-  void visitDoubleLiteral(DoubleLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE);
-    super.visitDoubleLiteral(node);
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
-    super.visitEnumDeclaration(node);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitExportDirective(node);
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _addRegions_functionBody(node);
-    super.visitExpressionFunctionBody(node);
-  }
-
-  @override
-  void visitExtendsClause(ExtendsClause node) {
-    computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
-    super.visitExtendsClause(node);
-  }
-
-  @override
-  void visitExtensionDeclaration(ExtensionDeclaration node) {
-    computer._addRegion_token(
-        node.extensionKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitExtensionDeclaration(node);
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    computer._addRegion_token(
-        node.abstractKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFieldDeclaration(node);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitFieldFormalParameter(node);
-  }
-
-  @override
-  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
-    super.visitForEachPartsWithDeclaration(node);
-  }
-
-  @override
-  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
-    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
-    super.visitForEachPartsWithIdentifier(node);
-  }
-
-  @override
-  void visitForElement(ForElement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitForElement(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
-    super.visitForStatement(node);
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.propertyKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFunctionDeclaration(node);
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    computer._addRegion_token(
-        node.typedefKeyword, HighlightRegionType.BUILT_IN);
-    super.visitFunctionTypeAlias(node);
-  }
-
-  @override
-  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitFunctionTypedFormalParameter(node);
-  }
-
-  @override
-  void visitGenericFunctionType(GenericFunctionType node) {
-    computer._addRegion_token(
-        node.functionKeyword, HighlightRegionType.KEYWORD);
-    super.visitGenericFunctionType(node);
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
-    super.visitGenericTypeAlias(node);
-  }
-
-  @override
-  void visitHideCombinator(HideCombinator node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitHideCombinator(node);
-  }
-
-  @override
-  void visitIfElement(IfElement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitIfElement(node);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
-    super.visitIfStatement(node);
-  }
-
-  @override
-  void visitImplementsClause(ImplementsClause node) {
-    computer._addRegion_token(
-        node.implementsKeyword, HighlightRegionType.BUILT_IN);
-    super.visitImplementsClause(node);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.deferredKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN);
-    super.visitImportDirective(node);
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    if (node.keyword != null) {
-      computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    }
-    super.visitInstanceCreationExpression(node);
-  }
-
-  @override
-  void visitIntegerLiteral(IntegerLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER);
-    super.visitIntegerLiteral(node);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD);
-    super.visitIsExpression(node);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitLibraryDirective(node);
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
-    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
-    super.visitListLiteral(node);
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.modifierKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.operatorKeyword, HighlightRegionType.BUILT_IN);
-    computer._addRegion_token(
-        node.propertyKeyword, HighlightRegionType.BUILT_IN);
-    super.visitMethodDeclaration(node);
-  }
-
-  @override
-  void visitMixinDeclaration(MixinDeclaration node) {
-    computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
-    super.visitMixinDeclaration(node);
-  }
-
-  @override
-  void visitNativeClause(NativeClause node) {
-    computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
-    super.visitNativeClause(node);
-  }
-
-  @override
-  void visitNativeFunctionBody(NativeFunctionBody node) {
-    computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
-    super.visitNativeFunctionBody(node);
-  }
-
-  @override
-  void visitOnClause(OnClause node) {
-    computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
-    super.visitOnClause(node);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitPartDirective(node);
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
-    computer._addRegion_tokenStart_tokenEnd(
-        node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN);
-    super.visitPartOfDirective(node);
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression node) {
-    computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD);
-    super.visitRethrowExpression(node);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD);
-    super.visitReturnStatement(node);
-  }
-
-  @override
-  void visitSetOrMapLiteral(SetOrMapLiteral node) {
-    if (node.isMap) {
-      computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
-      // TODO(brianwilkerson) Add a highlight region for set literals. This
-      //  would be a breaking change, but would be consistent with list and map
-      //  literals.
-//    } else if (node.isSet) {
-//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
-    }
-    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
-    super.visitSetOrMapLiteral(node);
-  }
-
-  @override
-  void visitShowCombinator(ShowCombinator node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
-    super.visitShowCombinator(node);
-  }
-
-  @override
-  void visitSimpleFormalParameter(SimpleFormalParameter node) {
-    computer._addRegion_token(
-        node.requiredKeyword, HighlightRegionType.KEYWORD);
-    super.visitSimpleFormalParameter(node);
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    computer._addIdentifierRegion(node);
-    super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING);
-    super.visitSimpleStringLiteral(node);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD);
-    super.visitSuperConstructorInvocation(node);
-  }
-
-  @override
-  void visitSwitchCase(SwitchCase node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchCase(node);
-  }
-
-  @override
-  void visitSwitchDefault(SwitchDefault node) {
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchDefault(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD);
-    super.visitSwitchStatement(node);
-  }
-
-  @override
-  void visitThisExpression(ThisExpression node) {
-    computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD);
-    super.visitThisExpression(node);
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    computer._addRegion_token(
-        node.externalKeyword, HighlightRegionType.BUILT_IN);
-    super.visitTopLevelVariableDeclaration(node);
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD);
-    super.visitTryStatement(node);
-  }
-
-  @override
-  void visitTypeName(TypeName node) {
-    var type = node.type;
-    if (type != null) {
-      if (type.isDynamic && node.name.name == 'dynamic') {
-        computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC);
-        return null;
-      }
-    }
-    super.visitTypeName(node);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    computer._addRegion_token(node.lateKeyword, HighlightRegionType.KEYWORD);
-    computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
-    super.visitVariableDeclarationList(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
-    super.visitWhileStatement(node);
-  }
-
-  @override
-  void visitWithClause(WithClause node) {
-    computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD);
-    super.visitWithClause(node);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    var keyword = node.yieldKeyword;
-    var star = node.star;
-    var offset = keyword.offset;
-    var end = star != null ? star.end : keyword.end;
-    computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
-    super.visitYieldStatement(node);
-  }
-
-  void _addRegions_functionBody(FunctionBody node) {
-    var keyword = node.keyword;
-    if (keyword != null) {
-      var star = node.star;
-      var offset = keyword.offset;
-      var end = star != null ? star.end : keyword.end;
-      computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
index ad0869e..d34bcea 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 
 class FormatOnTypeHandler
     extends MessageHandler<DocumentOnTypeFormattingParams, List<TextEdit>> {
@@ -26,9 +27,13 @@
       return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
     }
 
-    final unformattedSource = file.readAsStringSync();
-    return success(generateEditsForFormatting(
-        unformattedSource, server.clientConfiguration.lineLength));
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
new file mode 100644
index 0000000..3c6183d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+class FormatRangeHandler
+    extends MessageHandler<DocumentRangeFormattingParams, List<TextEdit>> {
+  FormatRangeHandler(LspAnalysisServer server) : super(server);
+  @override
+  Method get handlesMessage => Method.textDocument_rangeFormatting;
+
+  @override
+  LspJsonHandler<DocumentRangeFormattingParams> get jsonHandler =>
+      DocumentRangeFormattingParams.jsonHandler;
+
+  ErrorOr<List<TextEdit>> formatRange(String path, Range range) {
+    final file = server.resourceProvider.getFile(path);
+    if (!file.exists) {
+      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+    }
+
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength,
+        range: range);
+  }
+
+  @override
+  Future<ErrorOr<List<TextEdit>>> handle(
+      DocumentRangeFormattingParams params, CancellationToken token) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(null);
+    }
+
+    if (!server.clientConfiguration.enableSdkFormatter) {
+      return error(ServerErrorCodes.FeatureDisabled,
+          'Formatter was disabled by client settings');
+    }
+
+    final path = pathOfDoc(params.textDocument);
+    return path.mapResult((path) => formatRange(path, params.range));
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index 031d5a9..554ed01 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 
 class FormattingHandler
     extends MessageHandler<DocumentFormattingParams, List<TextEdit>> {
@@ -26,9 +27,13 @@
       return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
     }
 
-    final unformattedSource = file.readAsStringSync();
-    return success(generateEditsForFormatting(
-        unformattedSource, server.clientConfiguration.lineLength));
+    final result = server.getParsedUnit(path);
+    if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+      return success();
+    }
+
+    return generateEditsForFormatting(
+        result, server.clientConfiguration.lineLength);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index 949777a..be00dc9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -21,6 +21,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_exit.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_folding.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_format_range.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_hover.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_implementation.dart';
@@ -81,6 +82,7 @@
     registerHandler(ImplementationHandler(server));
     registerHandler(FormattingHandler(server));
     registerHandler(FormatOnTypeHandler(server));
+    registerHandler(FormatRangeHandler(server));
     registerHandler(DocumentHighlightsHandler(server));
     registerHandler(DocumentSymbolHandler(server));
     registerHandler(CodeActionHandler(server));
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
index 2a7a501e..fe82284 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -30,6 +30,7 @@
     Method.textDocument_documentHighlight,
     Method.textDocument_formatting,
     Method.textDocument_onTypeFormatting,
+    Method.textDocument_rangeFormatting,
     Method.textDocument_definition,
     Method.textDocument_codeAction,
     Method.textDocument_rename,
@@ -71,6 +72,9 @@
   bool get implementation =>
       _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
 
+  bool get rangeFormatting =>
+      _capabilities.textDocument?.rangeFormatting?.dynamicRegistration ?? false;
+
   bool get references =>
       _capabilities.textDocument?.references?.dynamicRegistration ?? false;
 
@@ -187,6 +191,9 @@
                   moreTriggerCharacter:
                       dartTypeFormattingCharacters.skip(1).toList())
               : null,
+      documentRangeFormattingProvider: dynamicRegistrations.typeFormatting
+          ? null
+          : Either2<bool, DocumentRangeFormattingOptions>.t1(enableFormatter),
       renameProvider: dynamicRegistrations.rename
           ? null
           : renameOptionsSupport
@@ -340,6 +347,13 @@
       ),
     );
     register(
+      enableFormatter && dynamicRegistrations.rangeFormatting,
+      Method.textDocument_rangeFormatting,
+      DocumentRangeFormattingRegistrationOptions(
+        documentSelector: [dartFiles], // This one is currently Dart-specific
+      ),
+    );
+    register(
       dynamicRegistrations.definition,
       Method.textDocument_definition,
       TextDocumentRegistrationOptions(documentSelector: allTypes),
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index 2105c85..b98a101 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -7,7 +7,13 @@
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/protocol_server.dart' as server
     show SourceEdit;
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/utilities/pair.dart';
 import 'package:dart_style/dart_style.dart';
@@ -70,9 +76,13 @@
   return ErrorOr.success(Pair(newContent, serverEdits));
 }
 
-List<TextEdit> generateEditsForFormatting(
-    String unformattedSource, int lineLength) {
-  final lineInfo = LineInfo.fromContent(unformattedSource);
+ErrorOr<List<TextEdit>> generateEditsForFormatting(
+  ParsedUnitResult result,
+  int lineLength, {
+  Range range,
+}) {
+  final unformattedSource = result.content;
+
   final code =
       SourceCode(unformattedSource, uri: null, isCompilationUnit: true);
   SourceCode formattedResult;
@@ -87,16 +97,19 @@
     // use seeing edits on every save with invalid code (if LSP gains the
     // ability to pass a context to know if the format was manually invoked
     // we may wish to change this to return an error for that case).
-    return null;
+    return success();
   }
   final formattedSource = formattedResult.text;
 
   if (formattedSource == unformattedSource) {
-    return null;
+    return success();
   }
 
-  // We don't currently support returning "minimal" edits, we just replace
-  // entire document.
+  return _generateMinimalEdits(result, formattedSource, range: range);
+}
+
+List<TextEdit> _generateFullEdit(
+    LineInfo lineInfo, String unformattedSource, String formattedSource) {
   final end = lineInfo.getLocation(unformattedSource.length);
   return [
     TextEdit(
@@ -107,6 +120,185 @@
   ];
 }
 
+/// Generates edits that modify the minimum amount of code (only whitespace) to
+/// change [unformatted] to [formatted].
+///
+/// This allows editors to more easily track important locations (such as
+/// breakpoints) without needing to do their own diffing.
+///
+/// If [range] is supplied, only whitespace edits that fall entirely inside this
+/// range will be included in the results.
+ErrorOr<List<TextEdit>> _generateMinimalEdits(
+  ParsedUnitResult result,
+  String formatted, {
+  Range range,
+}) {
+  final unformatted = result.content;
+  final lineInfo = result.lineInfo;
+  final rangeStart = range != null ? toOffset(lineInfo, range.start) : null;
+  final rangeEnd = range != null ? toOffset(lineInfo, range.end) : null;
+
+  if (rangeStart?.isError ?? false) {
+    return failure(rangeStart);
+  }
+  if (rangeEnd?.isError ?? false) {
+    return failure(rangeEnd);
+  }
+
+  // It shouldn't be the case that we can't parse the code but if it happens
+  // fall back to a full replacement rather than fail.
+  final parsedFormatted = _parse(formatted, result.unit.featureSet);
+  final parsedUnformatted = _parse(unformatted, result.unit.featureSet);
+  if (parsedFormatted == null || parsedUnformatted == null) {
+    return success(_generateFullEdit(lineInfo, unformatted, formatted));
+  }
+
+  final unformattedTokens = _iterateAllTokens(parsedUnformatted).iterator;
+  final formattedTokens = _iterateAllTokens(parsedFormatted).iterator;
+
+  var unformattedOffset = 0;
+  var formattedOffset = 0;
+  final edits = <TextEdit>[];
+
+  /// Helper for comparing whitespace and appending an edit.
+  void addEditFor(
+    int unformattedStart,
+    int unformattedEnd,
+    int formattedStart,
+    int formattedEnd,
+  ) {
+    if (rangeStart != null && rangeEnd != null) {
+      // If we're formatting only a range, skip over any segments that don't fall
+      // entirely within that range.
+      if (unformattedStart < rangeStart.result ||
+          unformattedEnd > rangeEnd.result) {
+        return;
+      }
+    }
+
+    final unformattedWhitespace =
+        unformatted.substring(unformattedStart, unformattedEnd);
+    final formattedWhitespace =
+        formatted.substring(formattedStart, formattedEnd);
+
+    if (unformattedWhitespace == formattedWhitespace) {
+      return;
+    }
+
+    // Validate we didn't find more than whitespace. If this occurs, it's likely
+    // the token offsets used were incorrect. In this case it's better to not
+    // modify the code than potentially remove something important.
+    if (unformattedWhitespace.trim().isNotEmpty ||
+        formattedWhitespace.trim().isNotEmpty) {
+      return;
+    }
+
+    var startOffset = unformattedStart;
+    var endOffset = unformattedEnd;
+    var newText = formattedWhitespace;
+
+    // Simplify some common cases where the new whitespace is a subset of
+    // the old.
+    if (formattedWhitespace.isNotEmpty) {
+      if (unformattedWhitespace.startsWith(formattedWhitespace)) {
+        startOffset = unformattedStart + formattedWhitespace.length;
+        newText = '';
+      } else if (unformattedWhitespace.endsWith(formattedWhitespace)) {
+        endOffset = unformattedEnd - formattedWhitespace.length;
+        newText = '';
+      }
+    }
+
+    // Finally, append the edit for this whitespace.
+    // Note: As with all LSP edits, offsets are based on the original location
+    // as they are applied in one shot. They should not account for the previous
+    // edits in the same set.
+    edits.add(TextEdit(
+      range: Range(
+        start: toPosition(lineInfo.getLocation(startOffset)),
+        end: toPosition(lineInfo.getLocation(endOffset)),
+      ),
+      newText: newText,
+    ));
+  }
+
+  // Process the whitespace before each token.
+  bool unformattedHasMore, formattedHasMore;
+  while ((unformattedHasMore =
+          unformattedTokens.moveNext()) & // Don't short-circuit
+      (formattedHasMore = formattedTokens.moveNext())) {
+    final unformattedToken = unformattedTokens.current;
+    final formattedToken = formattedTokens.current;
+
+    if (unformattedToken.lexeme != formattedToken.lexeme) {
+      // If the token lexems do not match, there is a difference in the parsed
+      // token streams (this should not ordinarily happen) so fall back to a
+      // full edit.
+      return success(_generateFullEdit(lineInfo, unformatted, formatted));
+    }
+
+    addEditFor(
+      unformattedOffset,
+      unformattedToken.offset,
+      formattedOffset,
+      formattedToken.offset,
+    );
+
+    // When range formatting, if we've processed a token that ends after the
+    // range then there can't be any more relevant edits and we can return early.
+    if (rangeEnd != null && unformattedToken.end > rangeEnd.result) {
+      return success(edits);
+    }
+
+    unformattedOffset = unformattedToken.end;
+    formattedOffset = formattedToken.end;
+  }
+
+  // If we got here and either of the streams still have tokens, something
+  // did not match so fall back to a full edit.
+  if (unformattedHasMore || formattedHasMore) {
+    return success(_generateFullEdit(lineInfo, unformatted, formatted));
+  }
+
+  // Finally, handle any whitespace that was after the last token.
+  addEditFor(
+    unformattedOffset,
+    unformatted.length,
+    formattedOffset,
+    formatted.length,
+  );
+
+  return success(edits);
+}
+
+/// Iterates over a token stream returning all tokens including comments.
+Iterable<Token> _iterateAllTokens(Token token) sync* {
+  while (token.type != TokenType.EOF) {
+    var commentToken = token.precedingComments;
+    while (commentToken != null) {
+      yield commentToken;
+      commentToken = commentToken.next;
+    }
+    yield token;
+    token = token.next;
+  }
+}
+
+/// Parse and return the first of the given Dart source, `null` if code cannot
+/// be parsed.
+Token _parse(String s, FeatureSet featureSet) {
+  try {
+    var scanner = Scanner(null, CharSequenceReader(s), null)
+      ..configureFeatures(
+        featureSetForOverriding: featureSet,
+        featureSet: featureSet,
+      );
+    return scanner.tokenize();
+  } catch (e) {
+    return null;
+  }
+}
+
 /// Helper class that bundles up all information required when converting server
 /// SourceEdits into LSP-compatible WorkspaceEdits.
 class FileEditInformation {
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index c26fd4a..1f2391e 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -5,7 +5,6 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/computer/computer_closingLabels.dart';
 import 'package:analysis_server/src/computer/computer_folding.dart';
-import 'package:analysis_server/src/computer/computer_highlights.dart';
 import 'package:analysis_server/src/computer/computer_highlights2.dart';
 import 'package:analysis_server/src/computer/computer_outline.dart';
 import 'package:analysis_server/src/computer/computer_overrides.dart';
@@ -100,12 +99,7 @@
 void sendAnalysisNotificationHighlights(
     AnalysisServer server, String file, CompilationUnit dartUnit) {
   _sendNotification(server, () {
-    List<protocol.HighlightRegion> regions;
-    if (server.options.useAnalysisHighlight2) {
-      regions = DartUnitHighlightsComputer2(dartUnit).compute();
-    } else {
-      regions = DartUnitHighlightsComputer(dartUnit).compute();
-    }
+    var regions = DartUnitHighlightsComputer2(dartUnit).compute();
     var params = protocol.AnalysisHighlightsParams(file, regions);
     server.sendNotification(params.toNotification());
   });
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 8e7af39..36cd808 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -252,10 +252,6 @@
   /// The name of the option used to describe the new analysis driver logger.
   static const String NEW_ANALYSIS_DRIVER_LOG = 'new-analysis-driver-log';
 
-  /// The name of the flag used to enable version 2 of semantic highlight
-  /// notification.
-  static const String USE_ANALYSIS_HIGHLIGHT2 = 'useAnalysisHighlight2';
-
   /// The option for specifying the http diagnostic port.
   /// If specified, users can review server status and performance information
   /// by opening a web browser on http://localhost:<port>
@@ -309,8 +305,6 @@
     var results = parser.parse(arguments, <String, String>{});
 
     var analysisServerOptions = AnalysisServerOptions();
-    analysisServerOptions.useAnalysisHighlight2 =
-        results[USE_ANALYSIS_HIGHLIGHT2];
     analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
     analysisServerOptions.newAnalysisDriverLog =
         results[NEW_ANALYSIS_DRIVER_LOG];
@@ -769,10 +763,6 @@
             ' status and performance information');
     parser.addOption(SDK_OPTION,
         valueHelp: 'path', help: 'Path to the Dart sdk');
-    parser.addFlag(USE_ANALYSIS_HIGHLIGHT2,
-        help: 'enable version 2 of semantic highlight',
-        defaultsTo: false,
-        negatable: false);
     parser.addOption(FILE_READ_MODE,
         help: 'an option for reading files (some clients normalize eol '
             'characters, which make the file offset and range information '
@@ -820,6 +810,8 @@
     parser.addFlag('enable-instrumentation', hide: true);
     // Removed 11/8/2020.
     parser.addFlag('preview-dart-2', hide: true);
+    // Removed 11/11/2020.
+    parser.addFlag('useAnalysisHighlight2', hide: true);
     // Removed 9/23/2020.
     parser.addFlag('use-fasta-parser', hide: true);
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index 403a6c4..feb830d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -86,7 +86,7 @@
       } else {
         return;
       }
-      if (operator.type != TokenType.PERIOD) {
+      if (operator == null || operator.type != TokenType.PERIOD) {
         return;
       }
       if (!(target is SimpleIdentifier &&
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 411e163..8d9c2bb 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -1142,7 +1142,6 @@
   @override
   void setUp() {
     super.setUp();
-    server.options.useAnalysisHighlight2 = true;
     createProject();
   }
 
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
deleted file mode 100644
index 9432795..0000000
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ /dev/null
@@ -1,1194 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_abstract.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisNotificationHighlightsTest);
-    defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
-    defineReflectiveTests(HighlightsWithNullSafetyTest);
-    defineReflectiveTests(HighlightTypeTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
-  Future<void> test_ANNOTATION_hasArguments() async {
-    addTestFile('''
-class AAA {
-  const AAA(a, b, c);
-}
-@AAA(1, 2, 3) main() {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
-    assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
-  }
-
-  Future<void> test_ANNOTATION_noArguments() async {
-    addTestFile('''
-const AAA = 42;
-@AAA main() {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
-  }
-
-  Future<void> test_BUILT_IN_abstract() async {
-    addTestFile('''
-abstract class A {};
-abstract class B = Object with A;
-main() {
-  var abstract = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
-  }
-
-  Future<void> test_BUILT_IN_as() async {
-    addTestFile('''
-import 'dart:math' as math;
-main() {
-  p as int;
-  var as = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
-  }
-
-  Future<void> test_BUILT_IN_async() async {
-    addTestFile('''
-fa() async {}
-fb() async* {}
-main() {
-  bool async = false;
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
-  }
-
-  Future<void> test_BUILT_IN_await() async {
-    addTestFile('''
-main() async {
-  await 42;
-  await for (var item in []) {
-    print(item);
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
-  }
-
-  Future<void> test_BUILT_IN_deferred() async {
-    addTestFile('''
-import 'dart:math' deferred as math;
-main() {
-  var deferred = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
-  }
-
-  Future<void> test_BUILT_IN_export() async {
-    addTestFile('''
-export "dart:math";
-main() {
-  var export = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
-  }
-
-  Future<void> test_BUILT_IN_external() async {
-    addTestFile('''
-class A {
-  external A();
-  external aaa();
-}
-external main() {
-  var external = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
-  }
-
-  Future<void> test_BUILT_IN_factory() async {
-    addTestFile('''
-class A {
-  A.named();
-  factory A() => A();
-}
-main() {
-  var factory = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
-  }
-
-  Future<void> test_BUILT_IN_get() async {
-    addTestFile('''
-get aaa => 1;
-class A {
-  get bbb => 2;
-}
-main() {
-  var get = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
-  }
-
-  Future<void> test_BUILT_IN_hide() async {
-    addTestFile('''
-import 'foo.dart' hide Foo;
-main() {
-  var hide = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
-  }
-
-  Future<void> test_BUILT_IN_implements() async {
-    addTestFile('''
-class A {}
-class B implements A {}
-main() {
-  var implements = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
-  }
-
-  Future<void> test_BUILT_IN_import() async {
-    addTestFile('''
-import "foo.dart";
-main() {
-  var import = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
-  }
-
-  Future<void> test_BUILT_IN_library() async {
-    addTestFile('''
-library lib;
-main() {
-  var library = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
-  }
-
-  Future<void> test_BUILT_IN_native() async {
-    addTestFile('''
-class A native "A_native" {}
-class B {
-  bbb() native "bbb_native";
-}
-main() {
-  var native = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
-  }
-
-  Future<void> test_BUILT_IN_on_inMixin() async {
-    addTestFile('''
-mixin M on N {}
-class N {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'on N');
-  }
-
-  Future<void> test_BUILT_IN_on_inTry() async {
-    addTestFile('''
-main() {
-  try {
-  } on int catch (e) {
-  }
-  var on = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
-  }
-
-  Future<void> test_BUILT_IN_operator() async {
-    addTestFile('''
-class A {
-  operator +(x) => null;
-}
-main() {
-  var operator = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
-  }
-
-  Future<void> test_BUILT_IN_part() async {
-    addTestFile('''
-part "my_part.dart";
-main() {
-  var part = 42;
-}''');
-    newFile('/project/bin/my_part.dart', content: 'part of lib;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
-  }
-
-  Future<void> test_BUILT_IN_partOf() async {
-    addTestFile('''
-part of lib;
-main() {
-  var part = 1;
-  var of = 2;
-}''');
-    _addLibraryForTestPart();
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
-  }
-
-  Future<void> test_BUILT_IN_set() async {
-    addTestFile('''
-set aaa(x) {}
-class A
-  set bbb(x) {}
-}
-main() {
-  var set = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
-  }
-
-  Future<void> test_BUILT_IN_show() async {
-    addTestFile('''
-import 'foo.dart' show Foo;
-main() {
-  var show = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
-  }
-
-  Future<void> test_BUILT_IN_static() async {
-    addTestFile('''
-class A {
-  static aaa;
-  static bbb() {}
-}
-main() {
-  var static = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
-  }
-
-  Future<void> test_BUILT_IN_sync() async {
-    addTestFile('''
-fa() sync {}
-fb() sync* {}
-main() {
-  bool sync = false;
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
-  }
-
-  Future<void> test_BUILT_IN_typedef() async {
-    addTestFile('''
-typedef A();
-main() {
-  var typedef = 42;
-}''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
-    assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
-  }
-
-  Future<void> test_BUILT_IN_yield() async {
-    addTestFile('''
-main() async* {
-  yield 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
-  }
-
-  Future<void> test_BUILT_IN_yieldStar() async {
-    addTestFile('''
-main() async* {
-  yield* [];
-}
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
-  }
-
-  Future<void> test_CLASS() async {
-    addTestFile('''
-class AAA {}
-AAA aaa;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
-    assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
-  }
-
-  Future<void> test_CLASS_notDynamic() async {
-    addTestFile('''
-dynamic f() {}
-''');
-    await prepareHighlights();
-    assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
-  }
-
-  Future<void> test_CLASS_notVoid() async {
-    addTestFile('''
-void f() {}
-''');
-    await prepareHighlights();
-    assertNoRegion(HighlightRegionType.CLASS, 'void f()');
-  }
-
-  Future<void> test_COMMENT() async {
-    addTestFile('''
-/**
- * documentation comment
- */
-void main() {
-  // end-of-line comment
-  my_function(1);
-}
-
-void my_function(String a) {
- /* block comment */
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
-    assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
-    assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
-  }
-
-  Future<void> test_CONSTRUCTOR_explicitNew() async {
-    addTestFile('''
-class AAA<T> {
-  AAA() {}
-  AAA.name(p) {}
-}
-main() {
-  new AAA<int>();
-  new AAA<int>.name(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-  }
-
-  Future<void> test_CONSTRUCTOR_implicitNew() async {
-    addTestFile('''
-class AAA<T> {
-  AAA() {}
-  AAA.name(p) {}
-}
-main() {
-  AAA<int>();
-  AAA<int>.name(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>(');
-    assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
-    assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
-  }
-
-  Future<void> test_DIRECTIVE() async {
-    addTestFile('''
-library lib;
-import 'dart:math';
-export 'dart:math';
-part 'part.dart';
-''');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'library lib;');
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';");
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';");
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
-  }
-
-  Future<void> test_DIRECTIVE_partOf() async {
-    addTestFile('''
-part of lib;
-''');
-    _addLibraryForTestPart();
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'part of lib;');
-  }
-
-  Future<void> test_DYNAMIC_TYPE() async {
-    addTestFile('''
-f() {}
-main(p) {
-  print(p);
-  var v1 = f();
-  int v2;
-  var v3 = v2;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)');
-    assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 =');
-    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;');
-    assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 =');
-  }
-
-  Future<void> test_ENUM() async {
-    addTestFile('''
-enum MyEnum {A, B, C}
-MyEnum value;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
-    assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
-  }
-
-  Future<void> test_ENUM_CONSTANT() async {
-    addTestFile('''
-enum MyEnum {AAA, BBB}
-main() {
-  print(MyEnum.AAA);
-  print(MyEnum.BBB);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
-    assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
-  }
-
-  Future<void> test_FIELD() async {
-    addTestFile('''
-class A {
-  int aaa = 1;
-  int bbb = 2;
-  A([this.bbb = 3]);
-}
-main(A a) {
-  a.aaa = 4;
-  a.bbb = 5;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3');
-    assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5');
-  }
-
-  Future<void> test_FIELD_STATIC() async {
-    addTestFile('''
-class A {
-  static aaa = 1;
-  static get bbb => null;
-  static set ccc(x) {}
-}
-main() {
-  A.aaa = 2;
-  A.bbb;
-  A.ccc = 3;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;');
-    assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3');
-  }
-
-  Future<void> test_FUNCTION() async {
-    addTestFile('''
-fff(p) {}
-main() {
-  fff(42);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}');
-    assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)');
-  }
-
-  Future<void> test_FUNCTION_TYPE_ALIAS() async {
-    addTestFile('''
-typedef FFF(p);
-main(FFF fff) {
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
-  }
-
-  Future<void> test_GETTER_DECLARATION() async {
-    addTestFile('''
-get aaa => null;
-class A {
-  get bbb => null;
-}
-main(A a) {
-  aaa;
-  a.bbb;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null');
-    assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb;');
-  }
-
-  Future<void> test_IDENTIFIER_DEFAULT() async {
-    addTestFile('''
-main() {
-  aaa = 42;
-  bbb(84);
-  CCC ccc;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
-    assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
-  }
-
-  Future<void> test_IMPORT_PREFIX() async {
-    addTestFile('''
-import 'dart:math' as ma;
-main() {
-  ma.max(1, 2);
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
-    assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
-  }
-
-  Future<void> test_KEYWORD() async {
-    addTestFile('''
-main() {
-  assert(true);
-  for (;;) break;
-  switch (0) {
-    case 0: break;
-    default: break;
-  }
-  try {} catch (e) {}
-  const v1 = 0;
-  for (;;) continue;
-  do {} while (true);
-  if (true) {} else {}
-  var v2 = false;
-  final v3 = 1;
-  try {} finally {}
-  for (var v4 in []) {}
-  v3 is int;
-  new A();
-  try {} catch (e) {rethrow;}
-  var v5 = true;
-  while (true) {}
-}
-class A {}
-class B extends A {
-  B() : super();
-  m() {
-    return this;
-  }
-}
-class C = Object with A;
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
-  }
-
-  Future<void> test_KEYWORD_ifElse_statement() async {
-    addTestFile('''
-f(a, b) {
-  if (a < b) {} else {}
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_mixin() async {
-    addTestFile('''
-mixin M {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
-  }
-
-  Future<void> test_KEYWORD_void() async {
-    addTestFile('''
-void main() {
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
-  }
-
-  Future<void> test_LABEL() async {
-    addTestFile('''
-main() {
-myLabel:
-  while (true) {
-    break myLabel;
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
-    assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
-  }
-
-  Future<void> test_LITERAL_BOOLEAN() async {
-    addTestFile('var V = true;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
-  }
-
-  Future<void> test_LITERAL_DOUBLE() async {
-    addTestFile('var V = 4.2;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
-  }
-
-  Future<void> test_LITERAL_INTEGER() async {
-    addTestFile('var V = 42;');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
-  }
-
-  Future<void> test_LITERAL_LIST() async {
-    addTestFile('var V = <int>[1, 2, 3];');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-  }
-
-  Future<void> test_LITERAL_MAP() async {
-    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-  }
-
-  Future<void> test_LITERAL_STRING() async {
-    addTestFile('var V = "abc";');
-    await prepareHighlights();
-    assertHasRegion(
-        HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
-  }
-
-  Future<void> test_LOCAL_VARIABLE() async {
-    addTestFile('''
-main() {
-  int vvv = 0;
-  vvv;
-  vvv = 1;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;');
-    assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;');
-  }
-
-  Future<void> test_METHOD() async {
-    addTestFile('''
-class A {
-  aaa() {}
-  static bbb() {}
-}
-main(A a) {
-  a.aaa();
-  a.aaa;
-  A.bbb();
-  A.bbb;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}');
-    assertHasRegion(HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}');
-    assertHasRegion(HighlightRegionType.METHOD, 'aaa();');
-    assertHasRegion(HighlightRegionType.METHOD, 'aaa;');
-    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();');
-    assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;');
-  }
-
-  Future<void> test_METHOD_bestType() async {
-    addTestFile('''
-main(p) {
-  if (p is List) {
-    p.add(null);
-  }
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.METHOD, 'add(null)');
-  }
-
-  Future<void> test_PARAMETER() async {
-    addTestFile('''
-main(int p) {
-  p;
-  p = 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p) {');
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p;');
-    assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42');
-  }
-
-  Future<void> test_SETTER_DECLARATION() async {
-    addTestFile('''
-set aaa(x) {}
-class A {
-  set bbb(x) {}
-}
-main(A a) {
-  aaa = 1;
-  a.bbb = 2;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)');
-    assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1');
-    assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
-  }
-
-  Future<void> test_TOP_LEVEL_VARIABLE() async {
-    addTestFile('''
-const VVV = 0;
-@VVV // annotation
-main() {
-  print(VVV);
-  VVV = 1;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0');
-    assertHasRegion(
-        HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);');
-    assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1');
-  }
-
-  Future<void> test_TYPE_NAME_DYNAMIC() async {
-    addTestFile('''
-dynamic main() {
-  dynamic = 42;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
-    assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
-    assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
-  }
-
-  Future<void> test_TYPE_PARAMETER() async {
-    addTestFile('''
-class A<T> {
-  T fff;
-  T mmm(T p) => null;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
-    assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
-  }
-}
-
-class HighlightsTestSupport extends AbstractAnalysisTest {
-  List<HighlightRegion> regions;
-
-  final Completer<void> _resultsAvailable = Completer();
-
-  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
-    for (var region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        return;
-      }
-    }
-    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
-        '${regions.join('\n')}');
-  }
-
-  void assertHasRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    var offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertHasStringRegion(HighlightRegionType type, String str) {
-    var offset = findOffset(str);
-    var length = str.length;
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
-    for (var region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        fail(
-            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
-            '${regions.join('\n')}');
-      }
-    }
-  }
-
-  void assertNoRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    var offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertNoRawRegion(type, offset, length);
-  }
-
-  int findRegionLength(String search, int length) {
-    if (length == -1) {
-      length = 0;
-      while (length < search.length) {
-        var c = search.codeUnitAt(length);
-        if (length == 0 && c == '@'.codeUnitAt(0)) {
-          length++;
-          continue;
-        }
-        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
-            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
-            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
-          break;
-        }
-        length++;
-      }
-    }
-    return length;
-  }
-
-  Future prepareHighlights() {
-    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
-    return _resultsAvailable.future;
-  }
-
-  @override
-  void processNotification(Notification notification) {
-    if (notification.event == SERVER_NOTIFICATION_ERROR) {
-      print('SERVER_NOTIFICATION_ERROR: ${notification.toJson()}');
-      _resultsAvailable.complete();
-      fail('SERVER_NOTIFICATION_ERROR');
-    }
-    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
-      var params = AnalysisHighlightsParams.fromNotification(notification);
-      if (params.file == testFile) {
-        regions = params.regions;
-        _resultsAvailable.complete();
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-  }
-
-  void _addLibraryForTestPart() {
-    newFile(join(testFolder, 'my_lib.dart'), content: '''
-library lib;
-part 'test.dart';
-    ''');
-  }
-}
-
-@reflectiveTest
-class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_list() async {
-    addTestFile('''
-f(a) async {
-  return [await for(var b in a) b];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_map() async {
-    addTestFile('''
-f(a) async {
-  return {await for(var b in a) b : 0};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  @failingTest
-  Future<void> test_KEYWORD_awaitForIn_set() async {
-    addTestFile('''
-f(a) async {
-  return {await for(var b in a) b};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
-  }
-
-  Future<void> test_KEYWORD_const_list() async {
-    addTestFile('''
-var v = const [];
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_const_map() async {
-    addTestFile('''
-var v = const {0 : 1};
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_const_set() async {
-    addTestFile('''
-var v = const {0};
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
-  }
-
-  Future<void> test_KEYWORD_if_list() async {
-    addTestFile('''
-f(a, b) {
-  return [if (a < b) 'a'];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_if_map() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' : 1};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_if_set() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a'};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-  }
-
-  Future<void> test_KEYWORD_ifElse_list() async {
-    addTestFile('''
-f(a, b) {
-  return [if (a < b) 'a' else 'b'];
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_ifElse_map() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' : 1 else 'b' : 2};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_KEYWORD_ifElse_set() async {
-    addTestFile('''
-f(a, b) {
-  return {if (a < b) 'a' else 'b'};
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
-    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
-  }
-
-  Future<void> test_LITERAL_LIST_withControlFlow() async {
-    addTestFile('var V = <int>[1, 2, 3];');
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
-  }
-
-  Future<void> test_LITERAL_MAP_withControlFlow() async {
-    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
-    await prepareHighlights();
-    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
-        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
-  }
-}
-
-@reflectiveTest
-class HighlightsWithNullSafetyTest extends HighlightsTestSupport {
-  @override
-  void createProject({Map<String, String> packageRoots}) {
-    addAnalysisOptionsFile('''
-analyzer:
-  enable-experiment:
-    - non-nullable
-''');
-    super.createProject(packageRoots: packageRoots);
-  }
-
-  Future<void> test_KEYWORD_late() async {
-    addTestFile('''
-class C {
-  late int x;
-}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'late');
-  }
-
-  Future<void> test_KEYWORD_required() async {
-    addTestFile('''
-void f({required int x}) {}
-''');
-    await prepareHighlights();
-    assertHasRegion(HighlightRegionType.KEYWORD, 'required');
-  }
-}
-
-@reflectiveTest
-class HighlightTypeTest {
-  void test_constructor() {
-    expect(HighlightRegionType.CLASS,
-        HighlightRegionType(HighlightRegionType.CLASS.name));
-  }
-
-  void test_toString() {
-    expect(HighlightRegionType.CLASS.toString(), 'HighlightRegionType.CLASS');
-  }
-
-  void test_valueOf_unknown() {
-    expect(() {
-      HighlightRegionType('no-such-type');
-    }, throwsException);
-  }
-}
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 702a96c..1187065 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -15,7 +15,6 @@
 import 'notification_errors_test.dart' as notification_errors;
 import 'notification_folding_test.dart' as notification_folding;
 import 'notification_highlights2_test.dart' as notification_highlights2;
-import 'notification_highlights_test.dart' as notification_highlights;
 import 'notification_implemented_test.dart' as notification_implemented;
 import 'notification_navigation_test.dart' as notification_navigation;
 import 'notification_occurrences_test.dart' as notification_occurrences;
@@ -37,7 +36,6 @@
     notification_folding.main();
     notification_errors.main();
     notification_highlights2.main();
-    notification_highlights.main();
     notification_implemented.main();
     notification_navigation.main();
     notification_occurrences.main();
diff --git a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart b/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
deleted file mode 100644
index 9dfcaf7..0000000
--- a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../support/integration_tests.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisHighlightsTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Map<HighlightRegionType, Set<String>> highlights;
-
-  void check(HighlightRegionType type, List<String> expected) {
-    expect(highlights[type], equals(expected.toSet()));
-    highlights.remove(type);
-  }
-
-  Future<void> computeHighlights(String pathname, String text) async {
-    writeFile(pathname, text);
-    standardAnalysisSetup();
-    sendAnalysisSetSubscriptions({
-      AnalysisService.HIGHLIGHTS: [pathname]
-    });
-    // Map from highlight type to highlighted text
-    onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
-      expect(params.file, equals(pathname));
-      highlights = <HighlightRegionType, Set<String>>{};
-      for (var region in params.regions) {
-        var startIndex = region.offset;
-        var endIndex = startIndex + region.length;
-        var highlightedText = text.substring(startIndex, endIndex);
-        var type = region.type;
-        if (!highlights.containsKey(type)) {
-          highlights[type] = <String>{};
-        }
-        highlights[type].add(highlightedText);
-      }
-    });
-    await analysisFinished;
-  }
-
-  @override
-  Future startServer({
-    int diagnosticPort,
-    int servicesPort,
-  }) {
-    return server.start(
-        diagnosticPort: diagnosticPort,
-        servicesPort: servicesPort,
-        useAnalysisHighlight2: true);
-  }
-
-  Future<void> test_highlights() async {
-    var pathname = sourcePath('test.dart');
-    var text = r'''
-import 'dart:async' as async;
-
-/**
- * Doc comment
- */
-class Class<TypeParameter> {
-  Class() {
-    field = {1.0: [].toList()};
-  }
-
-  Class.constructor() {
-    dynamic local = true;
-    field = {2: local};
-  }
-
-  Map field = {3: 4};
-  static int staticField = 0;
-
-  method() {
-    // End of line comment
-    /* Block comment */
-  }
-
-  static staticMethod() {
-  }
-
-  get getter {
-  }
-
-  set setter(int parameter) {
-    print(parameter);
-  }
-}
-
-class Class2<TypeParameter> extends Class<TypeParameter> {
-  @override
-  method() {
-  }
-}
-
-typedef functionType();
-
-function(dynamicType) {
-  print('string');
-  unresolvedIdentifier = 42;
-  return async.Future.wait([]);
-}
-
-int topLevelVariable = 0;
-''';
-    await computeHighlights(pathname, text);
-    // There should be 1 error due to the fact that unresolvedIdentifier is
-    // unresolved.
-    expect(currentAnalysisErrors[pathname], hasLength(1));
-
-    check(HighlightRegionType.ANNOTATION, ['@override']);
-    check(HighlightRegionType.BUILT_IN,
-        ['as', 'get', 'import', 'set', 'static', 'typedef']);
-    check(
-        HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
-    check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
-    check(HighlightRegionType.COMMENT_DOCUMENTATION,
-        ['/**\n * Doc comment\n */']);
-    check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
-    check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
-    check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
-    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
-    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
-    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
-    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
-    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
-    check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
-    check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
-    check(HighlightRegionType.IMPORT_PREFIX, ['async']);
-    check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
-    check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
-    check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
-    check(HighlightRegionType.LITERAL_INTEGER, ['2', '3', '4', '0', '42']);
-    check(HighlightRegionType.LITERAL_LIST, ['[]']);
-    check(HighlightRegionType.LITERAL_MAP,
-        ['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
-    check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
-    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
-    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
-    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
-    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
-    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
-    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
-    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
-    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
-    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
-    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
-        ['topLevelVariable']);
-    check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
-    check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
-    expect(highlights, isEmpty);
-  }
-
-  Future<void> test_highlights_mixin() async {
-    var pathname = sourcePath('test.dart');
-    var text = r'''
-mixin M on A implements B {}
-class A {}
-class B {}
-''';
-    await computeHighlights(pathname, text);
-    expect(currentAnalysisErrors[pathname], hasLength(0));
-
-    check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
-    check(HighlightRegionType.KEYWORD, ['class']);
-  }
-}
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 63f668b..9dfcaf7 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -48,6 +48,17 @@
     await analysisFinished;
   }
 
+  @override
+  Future startServer({
+    int diagnosticPort,
+    int servicesPort,
+  }) {
+    return server.start(
+        diagnosticPort: diagnosticPort,
+        servicesPort: servicesPort,
+        useAnalysisHighlight2: true);
+  }
+
   Future<void> test_highlights() async {
     var pathname = sourcePath('test.dart');
     var text = r'''
@@ -81,6 +92,7 @@
   }
 
   set setter(int parameter) {
+    print(parameter);
   }
 }
 
@@ -116,13 +128,14 @@
     check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
     check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
     check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
-    check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType', 'local']);
-    check(HighlightRegionType.FIELD, ['field']);
-    check(HighlightRegionType.FIELD_STATIC, ['staticField']);
-    check(HighlightRegionType.FUNCTION, ['print']);
-    check(HighlightRegionType.FUNCTION_DECLARATION, ['function']);
+    check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
+    check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
+    check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
+    check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
+    check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
     check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
-    check(HighlightRegionType.GETTER_DECLARATION, ['getter']);
+    check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
     check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
     check(HighlightRegionType.IMPORT_PREFIX, ['async']);
     check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
@@ -133,16 +146,18 @@
     check(HighlightRegionType.LITERAL_MAP,
         ['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
     check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
-    //check(HighlightRegionType.LOCAL_VARIABLE, ['local']);
-    //check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']);
-    check(HighlightRegionType.METHOD, ['toList']);
-    check(HighlightRegionType.METHOD_DECLARATION, ['method']);
-    check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']);
-    check(HighlightRegionType.METHOD_STATIC, ['wait']);
-    check(HighlightRegionType.PARAMETER, ['parameter']);
-    check(HighlightRegionType.SETTER_DECLARATION, ['setter']);
-    check(HighlightRegionType.TOP_LEVEL_VARIABLE,
-        ['override', 'topLevelVariable']);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
+    check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
+    check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
+    check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
+    check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
+    check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
+    check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
+    check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
+    check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
+    check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
+    check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
+        ['topLevelVariable']);
     check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
     check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
     expect(highlights, isEmpty);
@@ -157,6 +172,7 @@
 ''';
     await computeHighlights(pathname, text);
     expect(currentAnalysisErrors[pathname], hasLength(0));
+
     check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
     check(HighlightRegionType.KEYWORD, ['class']);
   }
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index 2a760bf..2e463f0 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -13,7 +13,6 @@
 import 'get_library_dependencies_test.dart' as get_library_dependencies_test;
 import 'get_navigation_test.dart' as get_navigation_test;
 import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
-import 'highlights2_test.dart' as highlights2_test;
 import 'highlights_test.dart' as highlights_test;
 import 'hint_sdk_version_async_exported_from_core_test.dart'
     as hint_sdk_version_async_exported_from_core_test;
@@ -44,7 +43,6 @@
     get_imported_elements_test.main();
     get_navigation_test.main();
     get_reachable_sources_test.main();
-    highlights2_test.main();
     highlights_test.main();
     hint_sdk_version_async_exported_from_core_test.main();
     lint_test.main();
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 5a51229..e629a4d 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -18,11 +18,22 @@
 
 @reflectiveTest
 class FormatTest extends AbstractLspAnalysisServerTest {
-  Future<void> expectFormattedContents(
+  Future<List<TextEdit>> expectFormattedContents(
       Uri uri, String original, String expected) async {
     final formatEdits = await formatDocument(uri.toString());
     final formattedContents = applyTextEdits(original, formatEdits);
     expect(formattedContents, equals(expected));
+    return formatEdits;
+  }
+
+  Future<List<TextEdit>> expectRangeFormattedContents(
+      Uri uri, String original, String expected) async {
+    final formatEdits =
+        await formatRange(uri.toString(), rangeFromMarkers(original));
+    final formattedContents =
+        applyTextEdits(withoutMarkers(original), formatEdits);
+    expect(formattedContents, equals(expected));
+    return formatEdits;
   }
 
   Future<void> test_alreadyFormatted() async {
@@ -37,6 +48,32 @@
     expect(formatEdits, isNull);
   }
 
+  Future<void> test_complex() async {
+    const contents = '''
+ErrorOr<Pair<A, List<B>>> c(
+  String d,
+  List<
+          Either2<E,
+              F>>
+      g, {
+  h = false,
+}) {
+}
+
+
+    ''';
+    final expected = '''
+ErrorOr<Pair<A, List<B>>> c(
+  String d,
+  List<Either2<E, F>> g, {
+  h = false,
+}) {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    await expectFormattedContents(mainFileUri, contents, expected);
+  }
+
   /// Ensures we use the same registration ID when unregistering even if the
   /// server has regenerated registrations multiple times.
   Future<void> test_dynamicRegistration_correctIdAfterMultipleChanges() async {
@@ -63,6 +100,7 @@
     // By default, the formatters should have been registered.
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
 
     // Sending config updates causes the server to rebuild its list of registrations
     // which exposes a previous bug where we'd retain newly-built registrations
@@ -78,6 +116,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNull);
   }
 
   Future<void> test_dynamicRegistration_forConfiguration() async {
@@ -104,6 +143,7 @@
     // By default, the formatters should have been registered.
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
 
     // They should be unregistered if we change the config to disabled.
     await monitorDynamicUnregistrations(
@@ -112,6 +152,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNull);
 
     // They should be reregistered if we change the config to enabled.
     await monitorDynamicRegistrations(
@@ -120,6 +161,7 @@
     );
     expect(registration(Method.textDocument_formatting), isNotNull);
     expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+    expect(registration(Method.textDocument_rangeFormatting), isNotNull);
   }
 
   Future<void> test_formatOnType_simple() async {
@@ -140,10 +182,96 @@
     final formatEdits = await formatOnType(
         mainFileUri.toString(), positionFromMarker(contents), '}');
     expect(formatEdits, isNotNull);
-    final formattedContents = applyTextEdits(contents, formatEdits);
+    final formattedContents =
+        applyTextEdits(withoutMarkers(contents), formatEdits);
     expect(formattedContents, equals(expected));
   }
 
+  Future<void> test_formatRange_editsOverlapRange() async {
+    // Only ranges that are fully contained by the range should be applied,
+    // not those that intersect the start/end.
+    const contents = '''
+main()
+{
+    [[    print('test');
+        print('test');
+    ]]    print('test');
+}
+''';
+    final expected = '''
+main()
+{
+        print('test');
+  print('test');
+        print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    await expectRangeFormattedContents(mainFileUri, contents, expected);
+  }
+
+  Future<void> test_formatRange_invalidRange() async {
+    const contents = '''
+main()
+{
+        print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final formatRangeRequest = formatRange(
+      mainFileUri.toString(),
+      Range(
+          start: Position(line: 0, character: 0),
+          end: Position(line: 10000, character: 0)),
+    );
+    await expectLater(formatRangeRequest,
+        throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)));
+  }
+
+  Future<void> test_formatRange_simple() async {
+    const contents = '''
+main  ()
+{
+
+    print('test');
+}
+
+[[main2  ()
+{
+
+    print('test');
+}]]
+
+main3  ()
+{
+
+    print('test');
+}
+''';
+    final expected = '''
+main  ()
+{
+
+    print('test');
+}
+
+main2() {
+  print('test');
+}
+
+main3  ()
+{
+
+    print('test');
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    await expectRangeFormattedContents(mainFileUri, contents, expected);
+  }
+
   Future<void> test_invalidSyntax() async {
     const contents = '''main(((( {
   print('test');
@@ -182,6 +310,186 @@
     await expectFormattedContents(mainFileUri, contents, expectedLongLines);
   }
 
+  Future<void> test_minimalEdits_addWhitespace() async {
+    // Check we only get one edit to add the required whitespace and not
+    // an entire document replacement.
+    const contents = '''
+main(){}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, ' ');
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 6)));
+  }
+
+  Future<void> test_minimalEdits_removeFileLeadingWhitespace() async {
+    // Check whitespace before the first token is handled.
+    const contents = '''
+
+
+
+main() {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, '');
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 0)));
+    expect(formatEdits[0].range.end, equals(Position(line: 3, character: 0)));
+  }
+
+  Future<void> test_minimalEdits_removeFileTrailingWhitespace() async {
+    // Check whitespace after the last token is handled.
+    const contents = '''
+main() {}
+
+
+
+
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(formatEdits[0].newText, '');
+    expect(formatEdits[0].range.start, equals(Position(line: 1, character: 0)));
+    expect(formatEdits[0].range.end, equals(Position(line: 5, character: 0)));
+  }
+
+  Future<void> test_minimalEdits_removePartialWhitespaceAfter() async {
+    // Check we get an edit only to remove the unnecessary trailing whitespace
+    // and not to replace the whole whitespace with a single space.
+    const contents = '''
+main()       {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 0, character: 7),
+              end: Position(line: 0, character: 13)),
+          newText: '',
+        )));
+  }
+
+  Future<void> test_minimalEdits_removePartialWhitespaceBefore() async {
+    // Check we get an edit only to remove the unnecessary leading whitespace
+    // and not to replace the whole whitespace with a single space.
+    const contents = '''
+main()
+
+
+ {}
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(1));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 0, character: 6),
+              end: Position(line: 3, character: 0)),
+          newText: '',
+        )));
+  }
+
+  Future<void> test_minimalEdits_removeWhitespace() async {
+    // Check we only get two edits to remove the unwanted whitespace and not
+    // an entire document replacement.
+    const contents = '''
+main( ) { }
+''';
+    const expected = '''
+main() {}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(2));
+    expect(formatEdits[0].newText, isEmpty);
+    expect(formatEdits[0].range.start, equals(Position(line: 0, character: 5)));
+    expect(formatEdits[1].newText, isEmpty);
+    expect(formatEdits[1].range.start, equals(Position(line: 0, character: 9)));
+  }
+
+  Future<void> test_minimalEdits_withComments() async {
+    // Check we can get edits that span a comment (which does not appear in the
+    // main token list).
+    const contents = '''
+main() {
+        var a = 1;
+        // Comment
+        print(a);
+}
+''';
+    const expected = '''
+main() {
+  var a = 1;
+  // Comment
+  print(a);
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+    final formatEdits =
+        await expectFormattedContents(mainFileUri, contents, expected);
+    expect(formatEdits, hasLength(3));
+    expect(
+        formatEdits[0],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 1, character: 2),
+              end: Position(line: 1, character: 8)),
+          newText: '',
+        )));
+    expect(
+        formatEdits[1],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 2, character: 2),
+              end: Position(line: 2, character: 8)),
+          newText: '',
+        )));
+    expect(
+        formatEdits[2],
+        equals(TextEdit(
+          range: Range(
+              start: Position(line: 3, character: 2),
+              end: Position(line: 3, character: 8)),
+          newText: '',
+        )));
+  }
+
   Future<void> test_nonDartFile() async {
     await initialize();
     await openFile(pubspecFileUri, simplePubspecContent);
@@ -253,4 +561,21 @@
     await initialize();
     await expectFormattedContents(mainFileUri, contents, expected);
   }
+
+  Future<void> test_validSyntax_withErrors() async {
+    // We should still be able to format syntactically valid code even if it has analysis
+    // errors.
+    const contents = '''main() {
+       print(a);
+}
+''';
+    const expected = '''main() {
+  print(a);
+}
+''';
+    await initialize();
+    await openFile(mainFileUri, contents);
+
+    await expectFormattedContents(mainFileUri, contents, expected);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 4caaecc..50bcc58 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -115,6 +115,7 @@
     expect(initResult.capabilities.documentHighlightProvider, isNotNull);
     expect(initResult.capabilities.documentFormattingProvider, isNotNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNotNull);
+    expect(initResult.capabilities.documentRangeFormattingProvider, isNotNull);
     expect(initResult.capabilities.definitionProvider, isNotNull);
     expect(initResult.capabilities.codeActionProvider, isNotNull);
     expect(initResult.capabilities.renameProvider, isNotNull);
@@ -164,6 +165,7 @@
     expect(initResult.capabilities.documentHighlightProvider, isNull);
     expect(initResult.capabilities.documentFormattingProvider, isNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNull);
+    expect(initResult.capabilities.documentRangeFormattingProvider, isNull);
     expect(initResult.capabilities.definitionProvider, isNull);
     expect(initResult.capabilities.codeActionProvider, isNull);
     expect(initResult.capabilities.renameProvider, isNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 342e9f1..64e8480 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -217,6 +217,7 @@
       'documentSymbol': {'dynamicRegistration': true},
       'formatting': {'dynamicRegistration': true},
       'onTypeFormatting': {'dynamicRegistration': true},
+      'rangeFormatting': {'dynamicRegistration': true},
       'declaration': {'dynamicRegistration': true},
       'definition': {'dynamicRegistration': true},
       'implementation': {'dynamicRegistration': true},
@@ -330,6 +331,7 @@
     return extendTextDocumentCapabilities(source, {
       'formatting': {'dynamicRegistration': true},
       'onTypeFormatting': {'dynamicRegistration': true},
+      'rangeFormatting': {'dynamicRegistration': true},
     });
   }
 
@@ -615,12 +617,13 @@
     }
 
     validateChangesCanBeApplied();
-    changes.sort(
-      (c1, c2) =>
-          positionCompare(c1.range.start, c2.range.start) *
-          -1, // Multiply by -1 to get descending sort.
-    );
-    for (final change in changes) {
+    final sortedChanges = changes.toList() // Don't mutate the original list.
+      ..sort(
+        // Multiply by -1 to get descending sort.
+        (c1, c2) => positionCompare(c1.range.start, c2.range.start) * -1,
+      );
+
+    for (final change in sortedChanges) {
       newContent = applyTextEdit(newContent, change);
     }
 
@@ -806,6 +809,21 @@
         request, _fromJsonList(TextEdit.fromJson));
   }
 
+  Future<List<TextEdit>> formatRange(String fileUri, Range range) {
+    final request = makeRequest(
+      Method.textDocument_rangeFormatting,
+      DocumentRangeFormattingParams(
+        options: FormattingOptions(
+            tabSize: 2,
+            insertSpaces: true), // These currently don't do anything
+        textDocument: TextDocumentIdentifier(uri: fileUri),
+        range: range,
+      ),
+    );
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(TextEdit.fromJson));
+  }
+
   Future<List<Either2<Command, CodeAction>>> getCodeActions(
     String fileUri, {
     Range range,
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
deleted file mode 100644
index b9d1af4..0000000
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ /dev/null
@@ -1,95 +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/src/computer/computer_highlights.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../abstract_context.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(HighlightsComputerTest);
-  });
-}
-
-@reflectiveTest
-class HighlightsComputerTest extends AbstractContextTest {
-  String sourcePath;
-  String content;
-  List<HighlightRegion> highlights;
-
-  @override
-  void setUp() {
-    super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
-  }
-
-  Future<void> test_comment() async {
-    await _computeHighlights('''
-// A trailing comment
-''');
-    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
-  }
-
-  Future<void> test_comment_trailing() async {
-    await _computeHighlights('''
-class A {}
-// A trailing comment
-''');
-    _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
-  }
-
-  Future<void> test_extension() async {
-    await _computeHighlights('''
-extension E on String {}
-''');
-    _check(HighlightRegionType.KEYWORD, 'extension');
-    _check(HighlightRegionType.BUILT_IN, 'on');
-  }
-
-  Future<void> test_methodInvocation_ofExtensionOverride_unresolved() async {
-    await _computeHighlights('''
-extension E on int {}
-
-main() {
-  E(0).foo();
-}
-''', hasErrors: true);
-    _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
-  }
-
-  void _check(HighlightRegionType expectedType, String expectedText) {
-    for (var region in highlights) {
-      if (region.type == expectedType) {
-        var startIndex = region.offset;
-        var endIndex = startIndex + region.length;
-        var highlightedText = content.substring(startIndex, endIndex);
-        if (highlightedText == expectedText) {
-          return;
-        }
-      }
-    }
-    fail('Expected region of type $expectedType with text "$expectedText"');
-  }
-
-  Future<void> _computeHighlights(
-    String content, {
-    bool hasErrors = false,
-  }) async {
-    this.content = content;
-    newFile(sourcePath, content: content);
-    var result = await session.getResolvedUnit(sourcePath);
-
-    if (hasErrors) {
-      expect(result.errors, isNotEmpty);
-    } else {
-      expect(result.errors, isEmpty);
-    }
-
-    var computer = DartUnitHighlightsComputer(result.unit);
-    highlights = computer.compute();
-  }
-}
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 8d7653e..b35ad77 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -7,7 +7,6 @@
 import 'closing_labels_computer_test.dart' as closing_labels_computer;
 import 'folding_computer_test.dart' as folding_computer;
 import 'highlights2_computer_test.dart' as highlights2_computer;
-import 'highlights_computer_test.dart' as highlights_computer;
 import 'import_elements_computer_test.dart' as import_elements_computer;
 import 'imported_elements_computer_test.dart' as imported_elements_computer;
 import 'outline_computer_test.dart' as outline_computer;
@@ -17,7 +16,6 @@
     closing_labels_computer.main();
     folding_computer.main();
     highlights2_computer.main();
-    highlights_computer.main();
     import_elements_computer.main();
     imported_elements_computer.main();
     outline_computer.main();
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
index d12dd4c..7d6b659 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
@@ -11,12 +11,12 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConvertToNormalParameterTest);
+    defineReflectiveTests(ConvertToNullAwareTest);
   });
 }
 
 @reflectiveTest
-class ConvertToNormalParameterTest extends AssistProcessorTest {
+class ConvertToNullAwareTest extends AssistProcessorTest {
   @override
   AssistKind get kind => DartAssistKind.CONVERT_TO_NULL_AWARE;
 
@@ -138,6 +138,18 @@
 ''');
   }
 
+  Future<void> test_notEqual_noTarget() async {
+    // https://github.com/dart-lang/sdk/issues/44173
+    verifyNoTestUnitErrors = false;
+    await resolveTestCode('''
+foo() {
+  var range = 1;
+  var rangeStart = range != null ? toOffset() : null;
+}
+''');
+    await assertNoAssistAt(' null;');
+  }
+
   Future<void> test_notEqual_notNullPreserving() async {
     await resolveTestCode('''
 abstract class A {
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index e95c70a..20b35d8 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -94,7 +94,7 @@
 | textDocument/documentColor | | | | | |
 | textDocument/colorPresentation | | | | | |
 | textDocument/formatting | ✅ | ✅ | | ✅ | ✅ |
-| textDocument/rangeFormatting | | | | | | requires support from dart_style?
+| textDocument/rangeFormatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/onTypeFormatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/rename | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/prepareRename | ✅ | ✅ | | ✅ | ✅ |
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 21d7fbc..2b1e1d2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -32,28 +32,16 @@
   public static final String DIRECTIVE = "DIRECTIVE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String DYNAMIC_TYPE = "DYNAMIC_TYPE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_LOCAL_VARIABLE_DECLARATION = "DYNAMIC_LOCAL_VARIABLE_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_LOCAL_VARIABLE_REFERENCE = "DYNAMIC_LOCAL_VARIABLE_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_PARAMETER_DECLARATION = "DYNAMIC_PARAMETER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String DYNAMIC_PARAMETER_REFERENCE = "DYNAMIC_PARAMETER_REFERENCE";
 
   public static final String ENUM = "ENUM";
@@ -61,29 +49,29 @@
   public static final String ENUM_CONSTANT = "ENUM_CONSTANT";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FIELD = "FIELD";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FIELD_STATIC = "FIELD_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FUNCTION = "FUNCTION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String FUNCTION_DECLARATION = "FUNCTION_DECLARATION";
 
   public static final String FUNCTION_TYPE_ALIAS = "FUNCTION_TYPE_ALIAS";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String GETTER_DECLARATION = "GETTER_DECLARATION";
 
@@ -91,58 +79,28 @@
 
   public static final String IMPORT_PREFIX = "IMPORT_PREFIX";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_FIELD_DECLARATION = "INSTANCE_FIELD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_FIELD_REFERENCE = "INSTANCE_FIELD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_GETTER_DECLARATION = "INSTANCE_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_GETTER_REFERENCE = "INSTANCE_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_METHOD_DECLARATION = "INSTANCE_METHOD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_METHOD_REFERENCE = "INSTANCE_METHOD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_SETTER_DECLARATION = "INSTANCE_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INSTANCE_SETTER_REFERENCE = "INSTANCE_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String INVALID_STRING_ESCAPE = "INVALID_STRING_ESCAPE";
 
   public static final String KEYWORD = "KEYWORD";
 
   public static final String LABEL = "LABEL";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LIBRARY_NAME = "LIBRARY_NAME";
 
   public static final String LITERAL_BOOLEAN = "LITERAL_BOOLEAN";
@@ -157,155 +115,92 @@
 
   public static final String LITERAL_STRING = "LITERAL_STRING";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_FUNCTION_DECLARATION = "LOCAL_FUNCTION_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_FUNCTION_REFERENCE = "LOCAL_FUNCTION_REFERENCE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String LOCAL_VARIABLE = "LOCAL_VARIABLE";
 
   public static final String LOCAL_VARIABLE_DECLARATION = "LOCAL_VARIABLE_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String LOCAL_VARIABLE_REFERENCE = "LOCAL_VARIABLE_REFERENCE";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD = "METHOD";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_DECLARATION = "METHOD_DECLARATION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_DECLARATION_STATIC = "METHOD_DECLARATION_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String METHOD_STATIC = "METHOD_STATIC";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String PARAMETER = "PARAMETER";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String SETTER_DECLARATION = "SETTER_DECLARATION";
 
   /**
-   * Only for version 1 of highlight.
+   * Deprecated - no longer sent.
    */
   public static final String TOP_LEVEL_VARIABLE = "TOP_LEVEL_VARIABLE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String PARAMETER_DECLARATION = "PARAMETER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String PARAMETER_REFERENCE = "PARAMETER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_FIELD_DECLARATION = "STATIC_FIELD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_GETTER_DECLARATION = "STATIC_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_GETTER_REFERENCE = "STATIC_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_METHOD_DECLARATION = "STATIC_METHOD_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_METHOD_REFERENCE = "STATIC_METHOD_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_SETTER_DECLARATION = "STATIC_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String STATIC_SETTER_REFERENCE = "STATIC_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_FUNCTION_DECLARATION = "TOP_LEVEL_FUNCTION_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_FUNCTION_REFERENCE = "TOP_LEVEL_FUNCTION_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_GETTER_DECLARATION = "TOP_LEVEL_GETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_GETTER_REFERENCE = "TOP_LEVEL_GETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_SETTER_DECLARATION = "TOP_LEVEL_SETTER_DECLARATION";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_SETTER_REFERENCE = "TOP_LEVEL_SETTER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String TOP_LEVEL_VARIABLE_DECLARATION = "TOP_LEVEL_VARIABLE_DECLARATION";
 
   public static final String TYPE_NAME_DYNAMIC = "TYPE_NAME_DYNAMIC";
 
   public static final String TYPE_PARAMETER = "TYPE_PARAMETER";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String UNRESOLVED_INSTANCE_MEMBER_REFERENCE = "UNRESOLVED_INSTANCE_MEMBER_REFERENCE";
 
-  /**
-   * Only for version 2 of highlight.
-   */
   public static final String VALID_STRING_ESCAPE = "VALID_STRING_ESCAPE";
 
 }
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index eb8cf23..262ca7c 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.30.0</version>
+  <version>1.31.0</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
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 25f5a64..61ada08 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.30.0';
+const String PROTOCOL_VERSION = '1.31.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 76ba245..777a128 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1354,152 +1354,47 @@
     
   <dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FIELD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
         
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">METHOD</dt><dd>
-        
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">METHOD_STATIC</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">PARAMETER</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">SETTER_DECLARATION</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
-        <p>Only for version 1 of highlight.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-        
-        <p>Only for version 2 of highlight.</p>
-      </dd></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
+        <p>Deprecated - no longer sent.</p>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
     <p>
       This object matches the format and documentation of the Entry object
       documented in the
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 6e2aeae..2d0391d 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -2307,23 +2307,19 @@
   static const HighlightRegionType DIRECTIVE =
       HighlightRegionType._('DIRECTIVE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType DYNAMIC_TYPE =
       HighlightRegionType._('DYNAMIC_TYPE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_DECLARATION =
       HighlightRegionType._('DYNAMIC_PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType DYNAMIC_PARAMETER_REFERENCE =
       HighlightRegionType._('DYNAMIC_PARAMETER_REFERENCE');
 
@@ -2332,24 +2328,24 @@
   static const HighlightRegionType ENUM_CONSTANT =
       HighlightRegionType._('ENUM_CONSTANT');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD = HighlightRegionType._('FIELD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FIELD_STATIC =
       HighlightRegionType._('FIELD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION = HighlightRegionType._('FUNCTION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType FUNCTION_DECLARATION =
       HighlightRegionType._('FUNCTION_DECLARATION');
 
   static const HighlightRegionType FUNCTION_TYPE_ALIAS =
       HighlightRegionType._('FUNCTION_TYPE_ALIAS');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType GETTER_DECLARATION =
       HighlightRegionType._('GETTER_DECLARATION');
 
@@ -2359,39 +2355,30 @@
   static const HighlightRegionType IMPORT_PREFIX =
       HighlightRegionType._('IMPORT_PREFIX');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_DECLARATION =
       HighlightRegionType._('INSTANCE_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_FIELD_REFERENCE =
       HighlightRegionType._('INSTANCE_FIELD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_GETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_DECLARATION =
       HighlightRegionType._('INSTANCE_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
       HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INSTANCE_SETTER_REFERENCE =
       HighlightRegionType._('INSTANCE_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType INVALID_STRING_ESCAPE =
       HighlightRegionType._('INVALID_STRING_ESCAPE');
 
@@ -2399,7 +2386,6 @@
 
   static const HighlightRegionType LABEL = HighlightRegionType._('LABEL');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LIBRARY_NAME =
       HighlightRegionType._('LIBRARY_NAME');
 
@@ -2421,113 +2407,94 @@
   static const HighlightRegionType LITERAL_STRING =
       HighlightRegionType._('LITERAL_STRING');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_DECLARATION =
       HighlightRegionType._('LOCAL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
       HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType LOCAL_VARIABLE =
       HighlightRegionType._('LOCAL_VARIABLE');
 
   static const HighlightRegionType LOCAL_VARIABLE_DECLARATION =
       HighlightRegionType._('LOCAL_VARIABLE_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType LOCAL_VARIABLE_REFERENCE =
       HighlightRegionType._('LOCAL_VARIABLE_REFERENCE');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD = HighlightRegionType._('METHOD');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION =
       HighlightRegionType._('METHOD_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_DECLARATION_STATIC =
       HighlightRegionType._('METHOD_DECLARATION_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType METHOD_STATIC =
       HighlightRegionType._('METHOD_STATIC');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType PARAMETER =
       HighlightRegionType._('PARAMETER');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType SETTER_DECLARATION =
       HighlightRegionType._('SETTER_DECLARATION');
 
-  /// Only for version 1 of highlight.
+  /// Deprecated - no longer sent.
   static const HighlightRegionType TOP_LEVEL_VARIABLE =
       HighlightRegionType._('TOP_LEVEL_VARIABLE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_DECLARATION =
       HighlightRegionType._('PARAMETER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType PARAMETER_REFERENCE =
       HighlightRegionType._('PARAMETER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_FIELD_DECLARATION =
       HighlightRegionType._('STATIC_FIELD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_DECLARATION =
       HighlightRegionType._('STATIC_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_GETTER_REFERENCE =
       HighlightRegionType._('STATIC_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_DECLARATION =
       HighlightRegionType._('STATIC_METHOD_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_METHOD_REFERENCE =
       HighlightRegionType._('STATIC_METHOD_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_DECLARATION =
       HighlightRegionType._('STATIC_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType STATIC_SETTER_REFERENCE =
       HighlightRegionType._('STATIC_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_GETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_GETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_SETTER_DECLARATION');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_SETTER_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_SETTER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType TOP_LEVEL_VARIABLE_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_VARIABLE_DECLARATION');
 
@@ -2537,11 +2504,9 @@
   static const HighlightRegionType TYPE_PARAMETER =
       HighlightRegionType._('TYPE_PARAMETER');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType UNRESOLVED_INSTANCE_MEMBER_REFERENCE =
       HighlightRegionType._('UNRESOLVED_INSTANCE_MEMBER_REFERENCE');
 
-  /// Only for version 2 of highlight.
   static const HighlightRegionType VALID_STRING_ESCAPE =
       HighlightRegionType._('VALID_STRING_ESCAPE');
 
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index f4acea4..b14bca8 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
 </head>
 <body>
 <h1>Common Types</h1>
-<version>1.3.0</version>
+<version>1.4.0</version>
 <p>
   This document contains a specification of the types that are common between
   the analysis server wire protocol and the analysis server plugin wire
@@ -645,90 +645,76 @@
       <value><code>DIRECTIVE</code></value>
       <value>
         <code>DYNAMIC_TYPE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>DYNAMIC_LOCAL_VARIABLE_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_LOCAL_VARIABLE_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_PARAMETER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>DYNAMIC_PARAMETER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>ENUM</code></value>
       <value><code>ENUM_CONSTANT</code></value>
       <value>
         <code>FIELD</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FIELD_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FUNCTION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>FUNCTION_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>FUNCTION_TYPE_ALIAS</code></value>
       <value>
         <code>GETTER_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>IDENTIFIER_DEFAULT</code></value>
       <value><code>IMPORT_PREFIX</code></value>
       <value>
         <code>INSTANCE_FIELD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_FIELD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_METHOD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_METHOD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INSTANCE_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>INVALID_STRING_ESCAPE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>KEYWORD</code></value>
       <value><code>LABEL</code></value>
       <value>
         <code>LIBRARY_NAME</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>LITERAL_BOOLEAN</code></value>
       <value><code>LITERAL_DOUBLE</code></value>
@@ -738,122 +724,101 @@
       <value><code>LITERAL_STRING</code></value>
       <value>
         <code>LOCAL_FUNCTION_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>LOCAL_FUNCTION_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>LOCAL_VARIABLE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value><code>LOCAL_VARIABLE_DECLARATION</code></value>
       <value>
         <code>LOCAL_VARIABLE_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>METHOD</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_DECLARATION_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>METHOD_STATIC</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>PARAMETER</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>SETTER_DECLARATION</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>TOP_LEVEL_VARIABLE</code>
-        <p>Only for version 1 of highlight.</p>
+        <p>Deprecated - no longer sent.</p>
       </value>
       <value>
         <code>PARAMETER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>PARAMETER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_FIELD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_METHOD_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_METHOD_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>STATIC_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_FUNCTION_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_FUNCTION_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_GETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_GETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_SETTER_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_SETTER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>TOP_LEVEL_VARIABLE_DECLARATION</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value><code>TYPE_NAME_DYNAMIC</code></value>
       <value><code>TYPE_PARAMETER</code></value>
       <value>
         <code>UNRESOLVED_INSTANCE_MEMBER_REFERENCE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
       <value>
         <code>VALID_STRING_ESCAPE</code>
-        <p>Only for version 2 of highlight.</p>
       </value>
     </enum>
   </type>
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 307c85a..8101640 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -12,7 +12,8 @@
 }
 
 void defineMigrateTests() {
-  final didYouForgetToRunPubGet = contains('Did you forget to run "pub get"?');
+  final runPubGet = contains('Run `dart pub get`');
+  final setLowerSdkConstraint = contains('Set the lower SDK constraint');
 
   TestProject p;
 
@@ -60,7 +61,8 @@
     var result = p.runSync('migrate', [p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
-    expect(result.stdout, didYouForgetToRunPubGet);
+    expect(result.stdout, runPubGet);
+    expect(result.stdout, isNot(setLowerSdkConstraint));
   });
 
   test('non-pub-related error', () {
@@ -68,6 +70,7 @@
     var result = p.runSync('migrate', [p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
-    expect(result.stdout, isNot(didYouForgetToRunPubGet));
+    expect(result.stdout, runPubGet);
+    expect(result.stdout, setLowerSdkConstraint);
   });
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
index d070369..9bc5b5d 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,352 +20,365 @@
 
 @reflectiveTest
 class TypeConstraintGathererTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env env;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    'UNKNOWN': () => new UnknownType()
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
 
-  final testLib =
-      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib')
-        ..isNonNullableByDefault = true;
+  Library _testLibrary;
 
-  Component component;
+  TypeConstraintGathererTest();
 
-  CoreTypes coreTypes;
+  Component get component => env.component;
 
-  TypeParameterType T1;
-  TypeParameterType T2;
-  TypeParameterType S1;
-  TypeParameterType S2;
-  TypeParameterType R1;
-  TypeParameterType R2;
+  CoreTypes get coreTypes => env.coreTypes;
 
-  Class classP;
+  Library get coreLibrary => _coreLibrary;
 
-  Class classQ;
+  Library get testLibrary => _testLibrary;
 
-  TypeConstraintGathererTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
-    T1 = new TypeParameterType(
-        new TypeParameter('T1', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    T2 = new TypeParameterType(
-        new TypeParameter('T2', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    S1 = new TypeParameterType(
-        new TypeParameter('S1', coreTypes.objectNullableRawType),
-        Nullability.undetermined);
-    S2 = new TypeParameterType(
-        new TypeParameter('S2', coreTypes.objectNullableRawType),
-        Nullability.undetermined);
-    R1 = new TypeParameterType(
-        new TypeParameter('R1', coreTypes.objectNonNullableRawType),
-        Nullability.nonNullable);
-    R2 = new TypeParameterType(
-        new TypeParameter('R2', coreTypes.objectNonNullableRawType),
-        Nullability.nonNullable);
-    classP = _addClass(_class('P'));
-    classQ = _addClass(_class('Q'));
+  void parseTestLibrary(String testLibraryText) {
+    env = new Env(testLibraryText, isNonNullableByDefault: true);
+    assert(
+        env.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = env.component.libraries.first;
+    Library secondLibrary = env.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  Class get functionClass => coreTypes.functionClass;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get P => coreTypes.legacyRawType(classP);
-
-  InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
   void test_any_subtype_parameter() {
-    DartType nullableQ = Q.withDeclaredNullability(Nullability.nullable);
-    DartType nonNullableQ = Q.withDeclaredNullability(Nullability.nonNullable);
+    parseTestLibrary('class P; class Q;');
 
-    _checkConstraintsLower(T1, nullableQ, testLib, ['lib::Q? <: T1']);
-    _checkConstraintsLower(T1, nonNullableQ, testLib, ['lib::Q <: T1']);
-    _checkConstraintsUpper(T1, nullableQ, testLib, ['T1 <: lib::Q?']);
-    _checkConstraintsUpper(T1, nonNullableQ, testLib, ['T1 <: lib::Q']);
+    checkConstraintsLower('T1*', 'Q?', ['lib::Q? <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsLower('T1*', 'Q', ['lib::Q <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('T1*', 'Q?', ['T1 <: lib::Q?'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('T1*', 'Q', ['T1 <: lib::Q'],
+        typeParameters: 'T1 extends Object*');
 
-    DartType nullableS1 = S1.withDeclaredNullability(Nullability.nullable);
-    _checkConstraintsLower(S1, nonNullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsLower(S1, nullableQ, testLib, ['lib::Q? <: S1']);
-    _checkConstraintsLower(nullableS1, nonNullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsLower(nullableS1, nullableQ, testLib, ['lib::Q <: S1']);
-    _checkConstraintsUpper(S1, nonNullableQ, testLib, ['S1 <: lib::Q']);
-    _checkConstraintsUpper(S1, nullableQ, testLib, ['S1 <: lib::Q?']);
-    _checkConstraintsUpper(nullableS1, nonNullableQ, testLib, null);
-    _checkConstraintsUpper(nullableS1, nullableQ, testLib, ['S1 <: lib::Q']);
+    checkConstraintsLower('S1', 'Q', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1', 'Q?', ['lib::Q? <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1?', 'Q', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1?', 'Q?', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1', 'Q', ['S1 <: lib::Q'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1', 'Q?', ['S1 <: lib::Q?'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1?', 'Q', null,
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1?', 'Q?', ['S1 <: lib::Q'],
+        typeParameters: 'S1 extends Object?');
   }
 
   void test_any_subtype_top() {
-    _checkConstraintsUpper(P, dynamicType, testLib, []);
-    _checkConstraintsUpper(P, coreTypes.objectLegacyRawType, testLib, []);
-    _checkConstraintsUpper(P, voidType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'dynamic', []);
+    checkConstraintsUpper('P*', 'Object*', []);
+    checkConstraintsUpper('P*', 'void', []);
   }
 
   void test_any_subtype_unknown() {
-    _checkConstraintsUpper(P, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
-    _checkConstraintsUpper(S1, unknownType, testLib, []);
-    _checkConstraintsUpper(R1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('S1', 'UNKNOWN', [],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('R1', 'UNKNOWN', [],
+        typeParameters: 'R1 extends Object');
   }
 
   void test_different_classes() {
-    _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
-    _checkConstraintsUpper(_list(S1), _iterable(Q), testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(S1), _list(Q), testLib, null);
-    _checkConstraintsUpper(_list(R1), _iterable(Q), testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(R1), _list(Q), testLib, null);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('List<S1>*', 'Iterable<Q*>*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('Iterable<S1>*', 'List<Q*>*', null,
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('List<R1>*', 'Iterable<Q*>*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsUpper('Iterable<R1>*', 'List<Q*>*', null,
+        typeParameters: 'R1 extends Object');
   }
 
   void test_equal_types() {
-    _checkConstraintsUpper(P, P, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'P*', []);
   }
 
   void test_function_generic() {
-    var T = new TypeParameterType(
-        new TypeParameter('T', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
-    var U = new TypeParameterType(
-        new TypeParameter('U', coreTypes.objectLegacyRawType),
-        Nullability.legacy);
+    parseTestLibrary('');
+
     // <T>() -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: <T>() -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
     // <T>(T) -> T <: <U>(U) -> U, always
-    _checkConstraintsUpper(
-        new FunctionType([T], T, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([U], U, Nullability.legacy,
-            typeParameters: [U.parameter]),
-        testLib,
-        []);
+    checkConstraintsUpper(
+        '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
   }
 
   void test_function_parameter_mismatch() {
+    parseTestLibrary('class P; class Q;');
+
     // (P) -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: (P) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
     // ([P]) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic <: ([P]) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
     // ({x: P}) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic !<: ({x: P}) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
   }
 
   void test_function_parameter_types() {
+    parseTestLibrary('class P; class Q;');
+
     // (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([T1], dynamicType, Nullability.legacy),
-        new FunctionType([Q], dynamicType, Nullability.legacy),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', T1)]),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', Q)]),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // (S1) -> S1? <: (P) -> P?
-    _checkConstraintsUpper(
-        new FunctionType([S1], S1.withDeclaredNullability(Nullability.nullable),
-            Nullability.nonNullable),
-        new FunctionType(
-            [P.withDeclaredNullability(Nullability.nonNullable)],
-            P.withDeclaredNullability(Nullability.nullable),
-            Nullability.nonNullable),
-        testLib,
-        ['lib::P <: S1 <: lib::P']);
+    checkConstraintsUpper(
+        '(S1) -> S1?', '(P) -> P?', ['lib::P <: S1 <: lib::P'],
+        typeParameters: 'S1 extends Object?');
     // (S1, List<S1?>) -> void <: (P, List<P?>) -> void
-    _checkConstraintsUpper(
-        new FunctionType(
-            [S1, _list(S1.withDeclaredNullability(Nullability.nullable))],
-            voidType,
-            Nullability.nonNullable),
-        new FunctionType([
-          P.withDeclaredNullability(Nullability.nonNullable),
-          _list(P.withDeclaredNullability(Nullability.nullable))
-        ], voidType, Nullability.nonNullable),
-        testLib,
-        ['lib::P <: S1']);
+    checkConstraintsUpper(
+        '(S1, List<S1?>*) -> void', '(P, List<P?>*) -> void', ['lib::P <: S1'],
+        typeParameters: 'S1 extends Object?');
   }
 
   void test_function_return_type() {
+    parseTestLibrary('class P; class Q;');
+
     // () -> T1 <: () -> Q, under constraint T1 <: Q
-    _checkConstraintsUpper(
-        new FunctionType([], T1, Nullability.legacy),
-        new FunctionType([], Q, Nullability.legacy),
-        testLib,
-        ['T1 <: lib::Q*']);
+    checkConstraintsUpper('() ->* T1', '() ->* Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
     // () -> P <: () -> void, always
-    _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
-        new FunctionType([], voidType, Nullability.legacy), testLib, []);
+    checkConstraintsUpper('() ->* P*', '() ->* void', []);
     // () -> void <: () -> P, never
-    _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
-        new FunctionType([], P, Nullability.legacy), testLib, null);
+    checkConstraintsUpper('() ->* void', '() ->* P*', null);
   }
 
   void test_function_trivial_cases() {
-    var F = new FunctionType([], dynamicType, Nullability.legacy);
+    parseTestLibrary('');
+
     // () -> dynamic <: dynamic, always
-    _checkConstraintsUpper(F, dynamicType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
     // () -> dynamic <: Function, always
-    _checkConstraintsUpper(F, functionType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Function*', []);
     // () -> dynamic <: Object, always
-    _checkConstraintsUpper(F, coreTypes.objectLegacyRawType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Object*', []);
   }
 
   void test_nonInferredParameter_subtype_any() {
-    var U = new TypeParameterType(
-        new TypeParameter('U', _list(P)), Nullability.legacy);
-    _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+        typeParameters: 'T1 extends Object*, U extends List<P*>*',
+        typeParametersToConstrain: 'T1');
   }
 
   void test_null_subtype_any() {
-    _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
-    _checkConstraintsUpper(new NullType(), Q, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Null', 'Q*', []);
   }
 
   void test_parameter_subtype_any() {
-    _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+    parseTestLibrary('class P; class Q;');
 
-    _checkConstraintsUpper(S1, Q, testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsLower(S1, Q, testLib, ['lib::Q* <: S1']);
-    _checkConstraintsUpper(S1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['S1 <: lib::Q*']);
-    _checkConstraintsLower(S1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['lib::Q <: S1']);
+    checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
 
-    _checkConstraintsUpper(R1, Q, testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsLower(R1, Q, testLib, ['lib::Q* <: R1']);
-    _checkConstraintsUpper(R1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['R1 <: lib::Q*']);
-    _checkConstraintsLower(R1.withDeclaredNullability(Nullability.legacy), Q,
-        testLib, ['lib::Q <: R1']);
+    checkConstraintsUpper('S1', 'Q*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1', 'Q*', ['lib::Q* <: S1'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsUpper('S1*', 'Q*', ['S1 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?');
+    checkConstraintsLower('S1*', 'Q*', ['lib::Q <: S1'],
+        typeParameters: 'S1 extends Object?');
+
+    checkConstraintsUpper('R1', 'Q*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsLower('R1', 'Q*', ['lib::Q* <: R1'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsUpper('R1*', 'Q*', ['R1 <: lib::Q*'],
+        typeParameters: 'R1 extends Object');
+    checkConstraintsLower('R1*', 'Q*', ['lib::Q <: R1'],
+        typeParameters: 'R1 extends Object');
   }
 
   void test_same_classes() {
-    _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_typeParameters() {
-    _checkConstraintsUpper(
-        _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(T1, T2), _map(P, Q), testLib, ['lib::P* <: T1', 'lib::Q* <: T2']);
+    parseTestLibrary('class P; class Q; class Map<X, Y>;');
 
-    _checkConstraintsUpper(
-        _map(S1, S2), _map(P, Q), testLib, ['S1 <: lib::P*', 'S2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(S1, S2), _map(P, Q), testLib, ['lib::P* <: S1', 'lib::Q* <: S2']);
-    _checkConstraintsUpper(
-        _map(S1.withDeclaredNullability(Nullability.legacy),
-            S2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['S1 <: lib::P*', 'S2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(S1.withDeclaredNullability(Nullability.legacy),
-            S2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['lib::P <: S1', 'lib::Q <: S2']);
+    checkConstraintsUpper(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
+    checkConstraintsLower(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['lib::P* <: T1', 'lib::Q* <: T2'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
 
-    _checkConstraintsUpper(
-        _map(R1, R2), _map(P, Q), testLib, ['R1 <: lib::P*', 'R2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(R1, R2), _map(P, Q), testLib, ['lib::P* <: R1', 'lib::Q* <: R2']);
-    _checkConstraintsUpper(
-        _map(R1.withDeclaredNullability(Nullability.legacy),
-            R2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['R1 <: lib::P*', 'R2 <: lib::Q*']);
-    _checkConstraintsLower(
-        _map(R1.withDeclaredNullability(Nullability.legacy),
-            R2.withDeclaredNullability(Nullability.legacy)),
-        _map(P, Q),
-        testLib,
-        ['lib::P <: R1', 'lib::Q <: R2']);
+    checkConstraintsUpper(
+        'Map<S1, S2>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsLower(
+        'Map<S1, S2>*', 'Map<P*, Q*>*', ['lib::P* <: S1', 'lib::Q* <: S2'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsUpper(
+        'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+    checkConstraintsLower(
+        'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['lib::P <: S1', 'lib::Q <: S2'],
+        typeParameters: 'S1 extends Object?, S2 extends Object?');
+
+    checkConstraintsUpper(
+        'Map<R1, R2>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsLower(
+        'Map<R1, R2>*', 'Map<P*, Q*>*', ['lib::P* <: R1', 'lib::Q* <: R2'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsUpper(
+        'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
+    checkConstraintsLower(
+        'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['lib::P <: R1', 'lib::Q <: R2'],
+        typeParameters: 'R1 extends Object, R2 extends Object');
   }
 
   void test_unknown_subtype_any() {
-    _checkConstraintsLower(Q, unknownType, testLib, []);
-    _checkConstraintsLower(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('Q*', 'UNKNOWN', []);
+    checkConstraintsLower('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkConstraintsLower(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsLowerTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
   }
 
-  void _checkConstraintsLower(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+  void _checkConstraintsLowerTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+        typeParameterNodesToConstrain);
   }
 
-  void _checkConstraintsUpper(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+  void checkConstraintsUpper(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsUpperTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
+  }
+
+  void _checkConstraintsUpperTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+        typeParameterNodesToConstrain);
   }
 
   void _checkConstraintsHelper(
@@ -373,20 +386,12 @@
       DartType b,
       Library clientLibrary,
       List<String> expectedConstraints,
-      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+      List<TypeParameter> typeParameterNodesToConstrain) {
     var typeSchemaEnvironment = new TypeSchemaEnvironment(
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
-        typeSchemaEnvironment,
-        [
-          T1.parameter,
-          T2.parameter,
-          S1.parameter,
-          S2.parameter,
-          R1.parameter,
-          R2.parameter
-        ],
-        testLib);
+        typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(clientLibrary)
         : null;
@@ -411,24 +416,4 @@
     });
     expect(constraintStrings, unorderedEquals(expectedConstraints));
   }
-
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
-  }
-
-  DartType _iterable(DartType element) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
-  DartType _list(DartType element) =>
-      new InterfaceType(listClass, Nullability.legacy, [element]);
-
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index ebdb227..d690cba 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -20,239 +20,273 @@
 
 @reflectiveTest
 class TypeConstraintGathererTest {
-  static const UnknownType unknownType = const UnknownType();
+  Env env;
 
-  static const DynamicType dynamicType = const DynamicType();
+  final Map<String, DartType Function()> additionalTypes = {
+    'UNKNOWN': () => UnknownType()
+  };
 
-  static const VoidType voidType = const VoidType();
+  Library _coreLibrary;
 
-  final testLib =
-      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
+  Library _testLibrary;
 
-  Component component;
+  TypeConstraintGathererTest();
 
-  CoreTypes coreTypes;
+  Component get component => env.component;
 
-  TypeParameterType T1;
+  CoreTypes get coreTypes => env.coreTypes;
 
-  TypeParameterType T2;
+  Library get coreLibrary => _coreLibrary;
 
-  Class classP;
+  Library get testLibrary => _testLibrary;
 
-  Class classQ;
-
-  TypeConstraintGathererTest() {
-    component = createMockSdkComponent();
-    component.libraries.add(testLib..parent = component);
-    coreTypes = new CoreTypes(component);
-    T1 = new TypeParameterType(
-        new TypeParameter('T1', objectType), Nullability.legacy);
-    T2 = new TypeParameterType(
-        new TypeParameter('T2', objectType), Nullability.legacy);
-    classP = _addClass(_class('P'));
-    classQ = _addClass(_class('Q'));
+  void parseTestLibrary(String testLibraryText) {
+    env = new Env(testLibraryText, isNonNullableByDefault: false);
+    assert(
+        env.component.libraries.length == 2,
+        "The tests are supposed to have exactly two libraries: "
+        "the core library and the test library.");
+    Library firstLibrary = env.component.libraries.first;
+    Library secondLibrary = env.component.libraries.last;
+    if (firstLibrary.importUri.scheme == "dart" &&
+        firstLibrary.importUri.path == "core") {
+      _coreLibrary = firstLibrary;
+      _testLibrary = secondLibrary;
+    } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
+      _coreLibrary == secondLibrary;
+      _testLibrary = firstLibrary;
+    }
   }
 
-  Class get functionClass => coreTypes.functionClass;
-
-  InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
-  Class get iterableClass => coreTypes.iterableClass;
-
-  Class get listClass => coreTypes.listClass;
-
-  Class get mapClass => coreTypes.mapClass;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => coreTypes.objectLegacyRawType;
-
-  InterfaceType get P => coreTypes.legacyRawType(classP);
-
-  InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
   void test_any_subtype_parameter() {
-    _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_any_subtype_top() {
-    _checkConstraintsUpper(P, dynamicType, testLib, []);
-    _checkConstraintsUpper(P, objectType, testLib, []);
-    _checkConstraintsUpper(P, voidType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'dynamic', []);
+    checkConstraintsUpper('P*', 'Object*', []);
+    checkConstraintsUpper('P*', 'void', []);
   }
 
   void test_any_subtype_unknown() {
-    _checkConstraintsUpper(P, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_different_classes() {
-    _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
-    _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_equal_types() {
-    _checkConstraintsUpper(P, P, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('P*', 'P*', []);
   }
 
   void test_function_generic() {
-    var T = new TypeParameterType(
-        new TypeParameter('T', objectType), Nullability.legacy);
-    var U = new TypeParameterType(
-        new TypeParameter('U', objectType), Nullability.legacy);
+    parseTestLibrary('');
+
     // <T>() -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: <T>() -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        testLib,
-        null);
+    checkConstraintsUpper(
+        '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
     // <T>(T) -> T <: <U>(U) -> U, always
-    _checkConstraintsUpper(
-        new FunctionType([T], T, Nullability.legacy,
-            typeParameters: [T.parameter]),
-        new FunctionType([U], U, Nullability.legacy,
-            typeParameters: [U.parameter]),
-        testLib,
-        []);
+    checkConstraintsUpper(
+        '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
   }
 
   void test_function_parameter_mismatch() {
+    parseTestLibrary('class P; class Q;');
+
     // (P) -> dynamic <: () -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
     // () -> dynamic <: (P) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
     // ([P]) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic <: ([P]) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([P], dynamicType, Nullability.legacy,
-            requiredParameterCount: 0),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
     // ({x: P}) -> dynamic <: () -> dynamic, always
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        new FunctionType([], dynamicType, Nullability.legacy),
-        testLib,
-        []);
+    checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
     // () -> dynamic !<: ({x: P}) -> dynamic, never
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', P)]),
-        testLib,
-        null);
+    checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
   }
 
   void test_function_parameter_types() {
+    parseTestLibrary('class P; class Q;');
+
     // (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([T1], dynamicType, Nullability.legacy),
-        new FunctionType([Q], dynamicType, Nullability.legacy),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
     // ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
-    _checkConstraintsUpper(
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', T1)]),
-        new FunctionType([], dynamicType, Nullability.legacy,
-            namedParameters: [new NamedType('x', Q)]),
-        testLib,
-        ['lib::Q* <: T1']);
+    checkConstraintsUpper(
+        '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_function_return_type() {
+    parseTestLibrary('class P; class Q;');
+
     // () -> T1 <: () -> Q, under constraint T1 <: Q
-    _checkConstraintsUpper(
-        new FunctionType([], T1, Nullability.legacy),
-        new FunctionType([], Q, Nullability.legacy),
-        testLib,
-        ['T1 <: lib::Q*']);
+    checkConstraintsUpper('() ->* T1*', '() ->* Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
     // () -> P <: () -> void, always
-    _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
-        new FunctionType([], voidType, Nullability.legacy), testLib, []);
+    checkConstraintsUpper('() ->* P*', '() ->* void', []);
     // () -> void <: () -> P, never
-    _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
-        new FunctionType([], P, Nullability.legacy), testLib, null);
+    checkConstraintsUpper('() ->* void', '() ->* P*', null);
   }
 
   void test_function_trivial_cases() {
-    var F = new FunctionType([], dynamicType, Nullability.legacy);
+    parseTestLibrary('');
+
     // () -> dynamic <: dynamic, always
-    _checkConstraintsUpper(F, dynamicType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
     // () -> dynamic <: Function, always
-    _checkConstraintsUpper(F, functionType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', "Function*", []);
     // () -> dynamic <: Object, always
-    _checkConstraintsUpper(F, objectType, testLib, []);
+    checkConstraintsUpper('() ->* dynamic', 'Object*', []);
   }
 
   void test_nonInferredParameter_subtype_any() {
-    var U = new TypeParameterType(
-        new TypeParameter('U', _list(P)), Nullability.legacy);
-    _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+        typeParameters: 'T1 extends Object*, U extends List<P*>*',
+        typeParametersToConstrain: 'T1');
   }
 
   void test_null_subtype_any() {
-    _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
-    _checkConstraintsUpper(new NullType(), Q, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+        typeParameters: 'T1 extends Object*');
+    checkConstraintsUpper('Null', 'Q*', []);
   }
 
   void test_parameter_subtype_any() {
-    _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_same_classes() {
-    _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*');
   }
 
   void test_typeParameters() {
-    _checkConstraintsUpper(
-        _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
+    parseTestLibrary('class P; class Q; class Map<X, Y>;');
+
+    checkConstraintsUpper(
+        'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+        typeParameters: 'T1 extends Object*, T2 extends Object*');
   }
 
   void test_unknown_subtype_any() {
-    _checkConstraintsUpper(Q, unknownType, testLib, []);
-    _checkConstraintsUpper(T1, unknownType, testLib, []);
+    parseTestLibrary('class P; class Q;');
+
+    checkConstraintsUpper('Q*', 'UNKNOWN', []);
+    checkConstraintsUpper('T1*', 'UNKNOWN', [],
+        typeParameters: 'T1 extends Object*');
   }
 
-  Class _addClass(Class c) {
-    testLib.addClass(c);
-    return c;
+  void checkConstraintsLower(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsLowerTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
   }
 
-  void _checkConstraintsLower(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+  void _checkConstraintsLowerTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+        typeParameterNodesToConstrain);
   }
 
-  void _checkConstraintsUpper(DartType type, DartType bound,
-      Library clientLibrary, List<String> expectedConstraints) {
-    _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
-        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+  void checkConstraintsUpper(String type, String bound, List<String> expected,
+      {String typeParameters, String typeParametersToConstrain}) {
+    env.withTypeParameters(typeParameters ?? '',
+        (List<TypeParameter> typeParameterNodes) {
+      List<TypeParameter> typeParameterNodesToConstrain;
+      if (typeParametersToConstrain != null) {
+        Set<String> namesToConstrain =
+            typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+        typeParameterNodesToConstrain = typeParameterNodes
+            .where((p) => namesToConstrain.contains(p.name))
+            .toList();
+      } else {
+        typeParameterNodesToConstrain = typeParameterNodes;
+      }
+      _checkConstraintsUpperTypes(
+          env.parseType(type, additionalTypes: additionalTypes),
+          env.parseType(bound, additionalTypes: additionalTypes),
+          testLibrary,
+          expected,
+          typeParameterNodesToConstrain);
+    });
+  }
+
+  void _checkConstraintsUpperTypes(
+      DartType type,
+      DartType bound,
+      Library clientLibrary,
+      List<String> expectedConstraints,
+      List<TypeParameter> typeParameterNodesToConstrain) {
+    _checkConstraintsHelper(
+        type,
+        bound,
+        clientLibrary,
+        expectedConstraints,
+        (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+        typeParameterNodesToConstrain);
   }
 
   void _checkConstraintsHelper(
@@ -260,11 +294,12 @@
       DartType b,
       Library clientLibrary,
       List<String> expectedConstraints,
-      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+      bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+      List<TypeParameter> typeParameterNodesToConstrain) {
     var typeSchemaEnvironment = new TypeSchemaEnvironment(
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
-        typeSchemaEnvironment, [T1.parameter, T2.parameter], testLib);
+        typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(clientLibrary)
         : null;
@@ -289,24 +324,4 @@
     });
     expect(constraintStrings, unorderedEquals(expectedConstraints));
   }
-
-  Class _class(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
-  }
-
-  DartType _iterable(DartType element) =>
-      new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
-  DartType _list(DartType element) =>
-      new InterfaceType(listClass, Nullability.legacy, [element]);
-
-  DartType _map(DartType key, DartType value) =>
-      new InterfaceType(mapClass, Nullability.legacy, [key, value]);
 }
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
index d32c54a..aa491cc 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -18,7 +18,7 @@
 
 @reflectiveTest
 class TypeSchemaEliminationTest {
-  final Env env = new Env("");
+  final Env env = new Env("", isNonNullableByDefault: true);
   final Map<String, DartType Function()> additionalTypes = {
     "UNKNOWN": () => new UnknownType()
   };
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index dd4a329..3d30f92 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -18,7 +18,7 @@
 
 @reflectiveTest
 class TypeSchemaEliminationTest {
-  final Env env = new Env("");
+  final Env env = new Env("", isNonNullableByDefault: false);
   final Map<String, DartType Function()> additionalTypes = {
     "UNKNOWN": () => new UnknownType()
   };
diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
index cf9cfa5..b1ac139 100644
--- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
@@ -36,6 +36,9 @@
   FastaLegacyUpperBoundTest(this.ticker, this.context);
 
   @override
+  bool get isNonNullableByDefault => false;
+
+  @override
   Future<void> parseComponent(String source) async {
     await super.parseComponent(source);
 
diff --git a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
index 0409fcb..e353327 100644
--- a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
@@ -12,6 +12,9 @@
   ClassHierarchy hierarchy;
 
   @override
+  bool get isNonNullableByDefault => true;
+
+  @override
   Future<void> parseComponent(String source) {
     super.parseComponent(source);
     hierarchy = new ClassHierarchy(env.component, env.coreTypes);
diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
index f55fe0a..5a50c9e 100644
--- a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
+++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
@@ -17,8 +17,11 @@
   Library coreLibrary;
   Library testLibrary;
 
+  bool get isNonNullableByDefault;
+
   void parseComponent(String source) {
-    env = new parser.Env(source);
+    env =
+        new parser.Env(source, isNonNullableByDefault: isNonNullableByDefault);
     assert(
         env.component.libraries.length == 2,
         "The test component is expected to have exactly two libraries: "
@@ -30,6 +33,10 @@
       coreLibrary = firstLibrary;
       testLibrary = secondLibrary;
     } else {
+      assert(
+          secondLibrary.importUri.scheme == "dart" &&
+              secondLibrary.importUri.path == "core",
+          "One of the libraries is expected to be 'dart:core'.");
       coreLibrary = secondLibrary;
       testLibrary = firstLibrary;
     }
diff --git a/pkg/js/analysis_options.yaml b/pkg/js/analysis_options.yaml
index 9951703..afaa4eb 100644
--- a/pkg/js/analysis_options.yaml
+++ b/pkg/js/analysis_options.yaml
@@ -3,8 +3,6 @@
 analyzer:
   strong-mode:
     implicit-casts: false
-  enable-experiment:
-    - non-nullable
 
 linter:
   rules:
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 70dd2ef..ced3c9e 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2629,7 +2629,7 @@
   @override
   Supertype readSupertype() {
     final int nodeOffset = _byteOffset;
-    InterfaceType type = super.readDartType();
+    InterfaceType type = super.readDartType(forSupertype: true);
     return _associateMetadata(
         new Supertype.byReference(type.className, type.typeArguments),
         nodeOffset);
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 757ee7a..7388412 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -98,17 +98,22 @@
 
   TypeParserEnvironment _libraryEnvironment;
 
-  Env(String source) {
+  final bool isNonNullableByDefault;
+
+  Env(String source, {this.isNonNullableByDefault}) {
+    assert(isNonNullableByDefault != null);
     Uri libraryUri = Uri.parse('memory:main.dart');
     Uri coreUri = Uri.parse("dart:core");
     TypeParserEnvironment coreEnvironment =
         new TypeParserEnvironment(coreUri, coreUri);
     Library coreLibrary =
-        parseLibrary(coreUri, mockSdk, environment: coreEnvironment);
+        parseLibrary(coreUri, mockSdk, environment: coreEnvironment)
+          ..isNonNullableByDefault = isNonNullableByDefault;
     _libraryEnvironment = new TypeParserEnvironment(libraryUri, libraryUri)
         ._extend(coreEnvironment._declarations);
     Library library =
-        parseLibrary(libraryUri, source, environment: _libraryEnvironment);
+        parseLibrary(libraryUri, source, environment: _libraryEnvironment)
+          ..isNonNullableByDefault = isNonNullableByDefault;
     library.name = "lib";
     component = new Component(libraries: <Library>[coreLibrary, library]);
     coreTypes = new CoreTypes(component);
@@ -120,16 +125,27 @@
         additionalTypes: additionalTypes);
   }
 
-  void extendWithTypeParameters(String typeParameters) {
-    _libraryEnvironment =
-        _libraryEnvironment.extendWithTypeParameters(typeParameters);
+  List<TypeParameter> extendWithTypeParameters(String typeParameters) {
+    if (typeParameters == null || typeParameters.isEmpty) {
+      return <TypeParameter>[];
+    }
+    ParameterEnvironment parameterEnvironment =
+        _libraryEnvironment.extendToParameterEnvironment(typeParameters);
+    _libraryEnvironment = parameterEnvironment.environment;
+    return parameterEnvironment.parameters;
   }
 
-  void withTypeParameters(String typeParameters, void Function() f) {
-    TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
-    extendWithTypeParameters(typeParameters);
-    f();
-    _libraryEnvironment = oldLibraryEnvironment;
+  void withTypeParameters(
+      String typeParameters, void Function(List<TypeParameter>) f) {
+    if (typeParameters == null || typeParameters.isEmpty) {
+      f(<TypeParameter>[]);
+    } else {
+      TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
+      List<TypeParameter> typeParameterNodes =
+          extendWithTypeParameters(typeParameters);
+      f(typeParameterNodes);
+      _libraryEnvironment = oldLibraryEnvironment;
+    }
   }
 }
 
@@ -197,10 +213,13 @@
 
   TypeParserEnvironment extendWithTypeParameters(String typeParameters) {
     if (typeParameters?.isEmpty ?? true) return this;
-    return const _KernelFromParsedType()
-        .computeTypeParameterEnvironment(
-            parseTypeVariables("<${typeParameters}>"), this)
-        .environment;
+    return extendToParameterEnvironment(typeParameters).environment;
+  }
+
+  ParameterEnvironment extendToParameterEnvironment(String typeParameters) {
+    assert(typeParameters != null && typeParameters.isNotEmpty);
+    return const _KernelFromParsedType().computeTypeParameterEnvironment(
+        parseTypeVariables("<${typeParameters}>"), this);
   }
 
   /// Returns the predefined type by the [name], if any.
diff --git a/pkg/kernel/test/dart_type_equivalence_test.dart b/pkg/kernel/test/dart_type_equivalence_test.dart
index 4f27768..462c637 100644
--- a/pkg/kernel/test/dart_type_equivalence_test.dart
+++ b/pkg/kernel/test/dart_type_equivalence_test.dart
@@ -169,8 +169,9 @@
     bool equateTopTypes = false,
     bool ignoreAllNullabilities = false,
     bool ignoreTopLevelNullability = false}) {
-  Env env = new Env("typedef Typedef<T> () -> T;\n")
-    ..extendWithTypeParameters(typeParameters);
+  Env env =
+      new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+        ..extendWithTypeParameters(typeParameters);
   DartType t1 = env.parseType(type1);
   DartType t2 = env.parseType(type2);
 
@@ -208,8 +209,9 @@
     bool equateTopTypes = false,
     bool ignoreAllNullabilities = false,
     bool ignoreTopLevelNullability = false}) {
-  Env env = new Env("typedef Typedef<T> () -> T;\n")
-    ..extendWithTypeParameters(typeParameters);
+  Env env =
+      new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+        ..extendWithTypeParameters(typeParameters);
   DartType t1 = env.parseType(type1);
   DartType t2 = env.parseType(type2);
 
diff --git a/pkg/kernel/test/flatten_test.dart b/pkg/kernel/test/flatten_test.dart
index ab6c1ee..6983445 100644
--- a/pkg/kernel/test/flatten_test.dart
+++ b/pkg/kernel/test/flatten_test.dart
@@ -66,13 +66,14 @@
 }
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   ClassHierarchy classHierarchy =
       new ClassHierarchy(env.component, env.coreTypes);
   TypeEnvironment typeEnvironment =
       new TypeEnvironment(env.coreTypes, classHierarchy);
   data.forEach((Test test) {
-    env.withTypeParameters(test.typeParameters, () {
+    env.withTypeParameters(test.typeParameters,
+        (List<TypeParameter> typeParameterNodes) {
       String input = test.input;
       String output = test.output;
       DartType inputType = env.parseType(input);
diff --git a/pkg/kernel/test/future_value_type_test.dart b/pkg/kernel/test/future_value_type_test.dart
index 5c0f032..8a7bfac 100644
--- a/pkg/kernel/test/future_value_type_test.dart
+++ b/pkg/kernel/test/future_value_type_test.dart
@@ -68,7 +68,7 @@
 };
 
 main() {
-  Env env = new Env('')
+  Env env = new Env('', isNonNullableByDefault: true)
     ..extendWithTypeParameters('X,'
         'X_extends_FutureInt extends Future<int>,'
         'X_extends_FutureOrInt extends FutureOr<int>');
diff --git a/pkg/kernel/test/legacy_erasure_test.dart b/pkg/kernel/test/legacy_erasure_test.dart
index 4757d00..4f82dea 100644
--- a/pkg/kernel/test/legacy_erasure_test.dart
+++ b/pkg/kernel/test/legacy_erasure_test.dart
@@ -54,7 +54,7 @@
 };
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   data.forEach((String input, String output) {
     DartType inputType = env.parseType(input);
     DartType expectedOutputType = env.parseType(output);
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index 4eb5d40..bd82a7e 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -111,7 +111,7 @@
 };
 
 main() {
-  Env env = new Env('');
+  Env env = new Env('', isNonNullableByDefault: true);
   data.forEach((String input, dynamic output) {
     List<String> parts = input.split(' vs ');
     DartType aType = env.parseType(parts[0]);
diff --git a/pkg/kernel/test/non_null_test.dart b/pkg/kernel/test/non_null_test.dart
index 542cc09..d9a04aa 100644
--- a/pkg/kernel/test/non_null_test.dart
+++ b/pkg/kernel/test/non_null_test.dart
@@ -78,7 +78,7 @@
 };
 
 main() {
-  Env env = new Env('')
+  Env env = new Env('', isNonNullableByDefault: true)
     ..extendWithTypeParameters('X,'
         'X_extends_Object extends Object,'
         'X_extends_dynamic extends dynamic,'
diff --git a/pkg/kernel/test/norm_test.dart b/pkg/kernel/test/norm_test.dart
index b8a5f3e..c287025 100644
--- a/pkg/kernel/test/norm_test.dart
+++ b/pkg/kernel/test/norm_test.dart
@@ -143,7 +143,8 @@
 }
 
 check(String input, String output, [String typeParameters = '']) {
-  Env env = new Env('')..extendWithTypeParameters(typeParameters);
+  Env env = new Env('', isNonNullableByDefault: true)
+    ..extendWithTypeParameters(typeParameters);
   DartType inputType = env.parseType(input);
   DartType expectedOutputType = env.parseType(output);
   DartType actualOutputType = norm(env.coreTypes, inputType);
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 8833c58..3ded01d 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -807,11 +807,6 @@
     }
   }
 
-  void _fatalErrorReported(String detail) {
-    logger.stderr(detail);
-    throw MigrationExit(1);
-  }
-
   void _exceptionReported(String detail) {
     if (_hasExceptions) return;
     _hasExceptions = true;
@@ -849,6 +844,11 @@
     }
   }
 
+  void _fatalErrorReported(String detail) {
+    logger.stderr(detail);
+    throw MigrationExit(1);
+  }
+
   void _logErrors(AnalysisResult analysisResult) {
     logger.stdout('');
 
@@ -861,35 +861,41 @@
     for (AnalysisError error in analysisResult.errors) {
       renderer.render(error);
     }
-
     logger.stdout('');
-    logger.stdout('Note: analysis errors will result in erroneous migration '
-        'suggestions.');
-
     _hasAnalysisErrors = true;
+
     if (options.ignoreErrors) {
+      logger.stdout('Note: analysis errors will result in erroneous migration '
+          'suggestions.');
       logger.stdout('Continuing with migration suggestions due to the use of '
           '--${CommandLineOptions.ignoreErrorsFlag}.');
     } else {
       // Fail with how to continue.
+      logger.stdout("The migration tool didn't start, due to analysis errors.");
       logger.stdout('');
       if (analysisResult.hasImportErrors) {
-        logger
-            .stdout('Unresolved URIs found.  Did you forget to run "pub get"?');
-        logger.stdout('');
-      }
-      if (analysisResult.allSourcesAlreadyMigrated) {
         logger.stdout('''
-All files appear to have null safety already enabled.  Did you update the
-language version prior to running "dart migrate"?  If so, you need to un-do this
-(and re-run "pub get") prior to performing the migration.
+The following steps might fix your problem:
+1. Run `dart pub get`.
+2. Try running `dart migrate` again.
 ''');
-        logger.stdout('');
+      } else if (analysisResult.allSourcesAlreadyMigrated) {
+        logger.stdout('''
+The following steps might fix your problem:
+1. Set the lower SDK constraint (in pubspec.yaml) to a version before 2.12.
+2. Run `dart pub get`.
+3. Try running `dart migrate` again.
+''');
+      } else {
+        const ignoreErrors = CommandLineOptions.ignoreErrorsFlag;
+        logger.stdout('''
+We recommend fixing the analysis issues before running `dart migrate`.
+Alternatively, you can run `dart migrate --$ignoreErrors`, but you might
+get erroneous migration suggestions.
+''');
       }
       logger.stdout(
-          'Please fix the analysis issues (or, force generation of migration '
-          'suggestions by re-running with '
-          '--${CommandLineOptions.ignoreErrorsFlag}).');
+          'More information: https://dart.dev/go/null-safety-migration');
     }
   }
 
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 36027a0..af33d0d 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -330,15 +330,15 @@
   /// Check if this migration is being run permissively.
   bool get isPermissive;
 
-  void finalizeInput(ResolvedUnitResult result);
-
-  void finish();
-
   /// Use this getter after any calls to [prepareInput] to obtain a list of URIs
   /// of unmigrated dependencies.  Ideally, this list should be empty before the
   /// user tries to migrate their package.
   List<String> get unmigratedDependencies;
 
+  void finalizeInput(ResolvedUnitResult result);
+
+  void finish();
+
   void prepareInput(ResolvedUnitResult result);
 
   void processInput(ResolvedUnitResult result);
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 35957ce..ce9eb5f 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -745,15 +745,9 @@
         output,
         contains("error • Expected to find ';' at lib${sep}test.dart:1:12 • "
             '(expected_token)'));
-    expect(
-        output,
-        contains(
-            'analysis errors will result in erroneous migration suggestions'));
-    expect(output, contains('Please fix the analysis issues'));
-    expect(
-        output,
-        isNot(
-            contains('All files appear to have null safety already enabled')));
+    expect(output, contains('erroneous migration suggestions'));
+    expect(output, contains('We recommend fixing the analysis issues'));
+    expect(output, isNot(contains('Set the lower SDK constraint')));
   }
 
   test_lifecycle_ignore_errors_enable() async {
@@ -1488,17 +1482,10 @@
     var output = logger.stdoutBuffer.toString();
     expect(output, contains('1 analysis issue found'));
     expect(output, contains('uri_does_not_exist'));
-    expect(
-        output,
-        contains(
-            'analysis errors will result in erroneous migration suggestions'));
-    expect(output,
-        contains('Unresolved URIs found.  Did you forget to run "pub get"?'));
-    expect(output, contains('Please fix the analysis issues'));
-    expect(
-        output,
-        isNot(
-            contains('All files appear to have null safety already enabled')));
+    expect(output, isNot(contains('erroneous migration suggestions')));
+    expect(output, contains('Run `dart pub get`'));
+    expect(output, contains('Try running `dart migrate` again'));
+    expect(output, isNot(contains('Set the lower SDK constraint')));
   }
 
   test_migrate_path_absolute() {
@@ -1912,9 +1899,7 @@
         errorOutput,
         contains("A value of type 'Null' can't be returned from function 'f' "
             "because it has a return type of 'int'"));
-    expect(errorOutput, contains('''
-All files appear to have null safety already enabled.  Did you update the
-language version prior to running "dart migrate"?'''));
+    expect(errorOutput, contains('Set the lower SDK constraint'));
   }
 
   String _getHelpText({@required bool verbose}) {
diff --git a/pkg/vm_service/test/get_stack_test.dart b/pkg/vm_service/test/get_stack_test.dart
new file mode 100644
index 0000000..6e61379
--- /dev/null
+++ b/pkg/vm_service/test/get_stack_test.dart
@@ -0,0 +1,161 @@
+// 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.
+
+// VMOptions=--lazy-async-stacks --no-causal-async-stacks --verbose_debug
+
+import 'dart:developer';
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const LINE_A = 33;
+const LINE_B = 35;
+
+Future<void> testMain() async {
+  await func1();
+}
+
+Future func1() async => await func2();
+Future func2() async => await func3();
+Future func3() async => await func4();
+Future func4() async => await func5();
+Future func5() async => await func6();
+Future func6() async => await func7();
+Future func7() async => await func8();
+Future func8() async => await func9();
+Future func9() async => await func10();
+Future func10() async {
+  debugger(); // LINE_A
+  await 0;
+  debugger(); // LINE_B
+  print("Hello, world!");
+}
+
+void expectFrame(
+    final frame, final kindExpectation, final codeNameExpectation) {
+  expect(frame.kind, kindExpectation);
+  expect(frame.code?.name, codeNameExpectation);
+}
+
+void expectFrames(final frames, final expectKindAndCodeName) {
+  for (int i = 0; i < expectKindAndCodeName.length; i++) {
+    expectFrame(
+        frames[i], expectKindAndCodeName[i][0], expectKindAndCodeName[i][1]);
+  }
+}
+
+final tests = <IsolateTest>[
+  // Before the first await.
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_A),
+  (VmService service, IsolateRef isolateRef) async {
+    final result = await service.getStack(isolateRef.id);
+
+    expect(result.frames, hasLength(16));
+    expect(result.asyncCausalFrames, hasLength(16));
+    expect(result.awaiterFrames, hasLength(16));
+
+    expectFrames(result.frames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('Regular'), endsWith(' func9')],
+      [equals('Regular'), endsWith(' func8')],
+      [equals('Regular'), endsWith(' func7')],
+      [equals('Regular'), endsWith(' func6')],
+      [equals('Regular'), endsWith(' func5')],
+      [equals('Regular'), endsWith(' func4')],
+      [equals('Regular'), endsWith(' func3')],
+      [equals('Regular'), endsWith(' func2')],
+      [equals('Regular'), endsWith(' func1')],
+      [equals('Regular'), endsWith(' testMain')],
+    ]);
+
+    expectFrames(result.asyncCausalFrames, [
+      [equals('AsyncCausal'), endsWith(' func10')],
+      [equals('AsyncCausal'), endsWith(' func9')],
+      [equals('AsyncCausal'), endsWith(' func8')],
+      [equals('AsyncCausal'), endsWith(' func7')],
+      [equals('AsyncCausal'), endsWith(' func6')],
+      [equals('AsyncCausal'), endsWith(' func5')],
+      [equals('AsyncCausal'), endsWith(' func4')],
+      [equals('AsyncCausal'), endsWith(' func3')],
+      [equals('AsyncCausal'), endsWith(' func2')],
+      [equals('AsyncCausal'), endsWith(' func1')],
+      [equals('AsyncCausal'), endsWith(' testMain')],
+    ]);
+
+    expectFrames(result.awaiterFrames, [
+      [equals('AsyncActivation'), endsWith(' func10')],
+      [equals('AsyncActivation'), endsWith(' func9')],
+      [equals('AsyncActivation'), endsWith(' func8')],
+      [equals('AsyncActivation'), endsWith(' func7')],
+      [equals('AsyncActivation'), endsWith(' func6')],
+      [equals('AsyncActivation'), endsWith(' func5')],
+      [equals('AsyncActivation'), endsWith(' func4')],
+      [equals('AsyncActivation'), endsWith(' func3')],
+      [equals('AsyncActivation'), endsWith(' func2')],
+      [equals('AsyncActivation'), endsWith(' func1')],
+      [equals('AsyncActivation'), endsWith(' testMain')],
+    ]);
+  },
+  // After resuming the continuation - i.e. running async.
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_B),
+  (VmService service, IsolateRef isolateRef) async {
+    final result = await service.getStack(isolateRef.id);
+
+    expect(result.frames, hasLength(10));
+    expect(result.asyncCausalFrames, hasLength(26));
+    expect(result.awaiterFrames, hasLength(2));
+
+    expectFrames(result.frames, [
+      [equals('Regular'), endsWith(' func10')],
+      [equals('Regular'), endsWith(' _RootZone.runUnary')],
+      [equals('Regular'), anything], // Internal mech. ..
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), anything],
+      [equals('Regular'), endsWith(' _RawReceivePortImpl._handleMessage')],
+    ]);
+
+    expectFrames(result.asyncCausalFrames, [
+      [equals('AsyncCausal'), endsWith(' func10')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func9')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func8')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func7')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func6')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func5')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func4')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func3')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func2')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' func1')],
+      [equals('AsyncSuspensionMarker'), isNull],
+      [equals('AsyncCausal'), endsWith(' testMain')],
+      [equals('AsyncSuspensionMarker'), isNull],
+    ]);
+
+    expectFrames(result.awaiterFrames, [
+      [equals('AsyncActivation'), endsWith(' func10')],
+      [equals('AsyncActivation'), endsWith(' func9')],
+    ]);
+  },
+];
+
+main([args = const <String>[]]) =>
+    runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 0c3d7cd..36394b0 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1919,31 +1919,23 @@
 DebuggerStackTrace* Debugger::CollectAsyncLazyStackTrace() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
 
   Code& code = Code::Handle(zone);
-  Code& inlined_code = Code::Handle(zone);
-  Smi& offset = Smi::Handle();
-  Array& deopt_frame = Array::Handle(zone);
+  Smi& offset = Smi::Handle(zone);
+  Function& function = Function::Handle(zone);
 
   constexpr intptr_t kDefaultStackAllocation = 8;
   auto stack_trace = new DebuggerStackTrace(kDefaultStackAllocation);
 
-  std::function<void(StackFrame*)> on_sync_frame = [&](StackFrame* frame) {
-    code = frame->LookupDartCode();
-    AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
-                     &inlined_code, &deopt_frame);
-  };
-
   const auto& code_array = GrowableObjectArray::ZoneHandle(
       zone, GrowableObjectArray::New(kDefaultStackAllocation));
   const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
       zone, GrowableObjectArray::New(kDefaultStackAllocation));
   bool has_async = false;
   StackTraceUtils::CollectFramesLazy(thread, code_array, pc_offset_array,
-                                     /*skip_frames=*/0, &on_sync_frame,
-                                     &has_async);
+                                     /*skip_frames=*/0, &has_async);
 
+  // If the entire stack is sync, return no trace.
   if (!has_async) {
     return nullptr;
   }
@@ -1951,13 +1943,25 @@
   const intptr_t length = code_array.Length();
   for (intptr_t i = stack_trace->Length(); i < length; ++i) {
     code ^= code_array.At(i);
-    offset ^= pc_offset_array.At(i);
+
     if (code.raw() == StubCode::AsynchronousGapMarker().raw()) {
       stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
-    } else {
-      const uword absolute_pc = code.PayloadStart() + offset.Value();
-      stack_trace->AddAsyncCausalFrame(absolute_pc, code);
+      continue;
     }
+
+    if (!code.IsFunctionCode()) {
+      continue;
+    }
+
+    // Skip invisible function frames.
+    function ^= code.function();
+    if (!function.is_visible()) {
+      continue;
+    }
+
+    offset ^= pc_offset_array.At(i);
+    const uword absolute_pc = code.PayloadStart() + offset.Value();
+    stack_trace->AddAsyncCausalFrame(absolute_pc, code);
   }
 
   return stack_trace;
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 5b146ff..572c222 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -287,7 +287,6 @@
     const GrowableObjectArray& code_array,
     const GrowableObjectArray& pc_offset_array,
     int skip_frames,
-    std::function<void(StackFrame*)>* on_sync_frames,
     bool* has_async) {
   if (has_async != nullptr) {
     *has_async = false;
@@ -327,9 +326,6 @@
     ASSERT(pc_offset > 0 && pc_offset <= code.Size());
     offset = Smi::New(pc_offset);
     pc_offset_array.Add(offset);
-    if (on_sync_frames != nullptr) {
-      (*on_sync_frames)(frame);
-    }
 
     // Either continue the loop (sync-async case) or find all await'ers and
     // return.
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 660746a..e3fd332 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -80,15 +80,11 @@
   ///       closure = closure.context[Context::kAsyncCompleterVarIndex]._future
   ///           ._resultOrListeners.callback;
   ///     }
-  ///
-  /// If [on_sync_frames] is non-nullptr, it will be called for every
-  /// synchronous frame which is collected.
   static void CollectFramesLazy(
       Thread* thread,
       const GrowableObjectArray& code_array,
       const GrowableObjectArray& pc_offset_array,
       int skip_frames,
-      std::function<void(StackFrame*)>* on_sync_frames = nullptr,
       bool* has_async = nullptr);
 
   /// Counts the number of stack frames.
diff --git a/tools/VERSION b/tools/VERSION
index 517c0f1..ffc3992 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 36
+PRERELEASE 37
 PRERELEASE_PATCH 0
\ No newline at end of file