Version 2.17.0-90.0.dev

Merge commit '07d41c68a630953d664bb07238e3a927155abc3a' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7367659..99b39d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3943,8 +3943,8 @@
 - **(Breaking)** "dart:isolate" and "dart:mirrors" are no longer supported when
   using Dart for the web. They are still supported in the command-line VM.
 
-- **(Breaking)** Pub's transformer-based build system has been [replaced by a
-  new build system][transformers].
+- **(Breaking)** Pub's transformer-based build system has been replaced by a
+  [new build system][build system].
 
 - The `new` keyword is optional and can be omitted. Likewise, `const` can be
   omitted inside a const context ([issue 30921][]).
@@ -3953,8 +3953,8 @@
 
 [issue 30345]: https://github.com/dart-lang/sdk/issues/30345
 [issue 30921]: https://github.com/dart-lang/sdk/issues/30921
-[strong mode]: https://www.dartlang.org/guides/language/sound-dart
-[transformers]: https://www.dartlang.org/tools/pub/obsolete
+[strong mode]: https://dart.dev/guides/language/type-system
+[build system]: https://github.com/dart-lang/build
 
 ### Language
 
@@ -4881,7 +4881,7 @@
 ```
 
 To opt back into the warnings, add the following to the
-[.analysis_options](https://www.dartlang.org/guides/language/analysis-options)
+[.analysis_options](https://dart.dev/guides/language/analysis-options)
 file for your project.
 
 ```
@@ -5316,7 +5316,7 @@
 
 - We have improved the way that the VM locates the native code library for a
   native extension (e.g. `dart-ext:` import). We have updated this
-  [article on native extensions](https://www.dartlang.org/articles/dart-vm/native-extensions)
+  [article on native extensions](https://dart.dev/server/c-interop-native-extensions)
   to reflect the VM's improved behavior.
 
 - Linux builds of the VM will now use the `tcmalloc` library for memory
@@ -6107,7 +6107,7 @@
 ### Tool changes
 
 - `dart2js` and Dartium now support improved Javascript Interoperability via the
-  [js package](https://pub.dartlang.org/packages/js).
+  [js package](https://pub.dev/packages/js).
 
 - `docgen` and `dartdocgen` no longer ship in the SDK. The `docgen` sources have
   been removed from the repository.
@@ -6223,7 +6223,7 @@
 - Documentation tools
 
   - `dartdoc` is now the default tool to generate static HTML for API docs.
-    [Learn more](https://pub.dartlang.org/packages/dartdoc).
+    [Learn more](https://pub.dev/packages/dartdoc).
 
   - `docgen` and `dartdocgen` have been deprecated. Currently plan is to remove
     them in 1.13.
@@ -6416,7 +6416,7 @@
 ### Tool changes
 
 - This is the first release that does not include the Eclipse-based **Dart
-  Editor**. See [dartlang.org/tools](https://www.dartlang.org/tools/) for
+  Editor**. See [dart.dev/tools](https://dart.dev/tools#ides-and-editors) for
   alternatives.
 - This is the last release that ships the (unsupported) dart2dart (aka
   `dart2js --output-type=dart`) utility as part of dart2js
@@ -6496,8 +6496,8 @@
 
 - Enum support is fully enabled. See [the language tour][enum] for more details.
 
-[async]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#asynchrony
-[enum]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#enums
+[async]: https://dart.dev/guides/language/language-tour#asynchrony
+[enum]: https://dart.dev/guides/language/language-tour#enums
 
 ### Tool changes
 
@@ -6511,7 +6511,7 @@
 - Analysis supports more and better hints, including unused variables and unused
   private members.
 
-[dartfmt]: https://www.dartlang.org/tools/dartfmt/
+[dartfmt]: https://dart.dev/tools/dart-format
 
 ### Core library changes
 
@@ -6529,7 +6529,7 @@
 #### Details
 
 For more information on any of these changes, see the corresponding
-documentation on the [Dart API site](http://api.dartlang.org).
+documentation on the [Dart API site](http://api.dart.dev).
 
 - `dart:async`:
 
@@ -6681,7 +6681,7 @@
   the same page.
 
 [pub global activate]:
-  https://www.dartlang.org/tools/pub/cmd/pub-global.html#running-a-script-from-your-path
+  https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path
 
 ### Core library changes
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6802814..cdfcdaf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,7 +11,7 @@
       click that icon to report a bug on the page.
     * To report an API doc bug,
       [create an SDK issue](https://github.com/dart-lang/sdk/issues/new?title=API%20doc%20issue:).
-  * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)) and [dart.dev/web](https://dart.dev/web) (repo: [dart-lang/site-www/src/web](https://github.com/dart-lang/site-www/tree/master/src/web)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/wiki/Writing-for-Dart-and-Flutter-websites).
+  * Contribute to the Dart developer websites such as [dart.dev](https://dart.dev) (repo: [dart-lang/site-www](https://github.com/dart-lang/site-www)). For more information, see [Writing for Dart and Flutter websites](https://github.com/dart-lang/site-shared/blob/master/doc/writing-for-dart-and-flutter-websites.md).
   * Improve the API reference docs at [api.dart.dev](https://api.dart.dev) by editing doc comments in the [Dart SDK repo](https://github.com/dart-lang/sdk/tree/main/sdk/lib). For more information on how to write API docs, see [Effective Dart: Documentation](https://dart.dev/guides/language/effective-dart/documentation).
 
 ## Before you contribute
@@ -20,9 +20,13 @@
 
 Before you start working on a larger contribution, you should get in touch with us first through the  [Dart Issue Tracker](https://dartbug.com) with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on.
 
-All submissions, including submissions by project members, require review.  We use the same code-review tools and process as the chromium project.  In order to submit a patch, you need to get the [depot\_tools](http://dev.chromium.org/developers/how-tos/depottools).
+All submissions, including submissions by project members, require review.  We use the same code-review tools and process as the chromium project.
 
-We occasionally take pull requests, e.g., for comment changes, but the main flow is to use the Rietveld review system as explained below.
+We occasionally take pull requests, e.g., for comment changes, but the main flow is to use the Gerrit review system as explained below.
+
+## Setting up Environment
+
+In order to submit a patch, you need to get the [depot\_tools](http://dev.chromium.org/developers/how-tos/depottools).
 
 ## Getting the code
 
@@ -69,7 +73,9 @@
 git cl upload -s
 ```
 
-The above command returns a URL for the review. Attach this review to your issue in https://dartbug.com
+The above command returns a URL for the review. Attach this review to your issue in https://dartbug.com.
+
+To update the cl, just commit your changes and run `git cl upload -s` for your branch.
 
 If you have commit access, when the review is done and the patch is good to go, submit the patch on https://dart-review.googlesource.com:
 
diff --git a/DEPS b/DEPS
index 375023d..e65568d 100644
--- a/DEPS
+++ b/DEPS
@@ -109,7 +109,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_rev": "6f894c0ca33686122be9085f06e5b9bf6ad55262",
 
-  "dartdoc_rev" : "f9cfab1b84176873c80b89e7c8b54c669344f9ed",
+  "dartdoc_rev" : "b3927dd89d6ff9c78dc88ab2901e63b6a3bf29b7",
   "devtools_rev" : "3b054edf3a14a4a51bc8019f456efcf0073cd626",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
   "fixnum_rev": "848341f061359ef7ddc0cad472c2ecbb036b28ac",
diff --git a/SECURITY.md b/SECURITY.md
index a341d38..573f212 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,3 +1,8 @@
 ## Reporting vulnerabilities
 To report potential vulnerabilities, please see our security policy on
 [https://dart.dev/security](https://dart.dev/security).
+
+## Published security advisories
+
+For advisories published for the Dart SDK, see
+[security advisories](https://github.com/dart-lang/sdk/security/advisories?state=published).
diff --git a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
index b3d40c0..3451cc3 100644
--- a/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart/BigIntParsePrint.dart
@@ -4,6 +4,8 @@
 
 // ignore_for_file: avoid_function_literals_in_foreach_calls
 
+import 'dart:math' show Random;
+
 import 'package:benchmark_harness/benchmark_harness.dart';
 import 'package:fixnum/fixnum.dart';
 
@@ -240,7 +242,9 @@
 class DummyBenchmark extends BenchmarkBase {
   DummyBenchmark(String name) : super(name);
   @override
-  double measure() => 2000 * 1000 * 1.0; // A rate of one run per 2s.
+  // A rate of one run per 2s, with a millisecond of noise.  Some variation is
+  // needed for Golem's noise-based filtering and regression detection.
+  double measure() => (2000 + Random().nextDouble() - 0.5) * 1000;
 }
 
 /// Create [ParseJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
diff --git a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
index db19b68..2ff130d 100644
--- a/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
+++ b/benchmarks/BigIntParsePrint/dart2/BigIntParsePrint.dart
@@ -6,6 +6,8 @@
 
 // @dart=2.9
 
+import 'dart:math' show Random;
+
 import 'package:benchmark_harness/benchmark_harness.dart';
 import 'package:fixnum/fixnum.dart';
 
@@ -242,7 +244,9 @@
 class DummyBenchmark extends BenchmarkBase {
   DummyBenchmark(String name) : super(name);
   @override
-  double measure() => 2000 * 1000 * 1.0; // A rate of one run per 2s.
+  // A rate of one run per 2s, with a millisecond of noise.  Some variation is
+  // needed for Golem's noise-based filtering and regression detection.
+  double measure() => (2000 + Random().nextDouble() - 0.5) * 1000;
 }
 
 /// Create [ParseJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
index 4e453145..a25f8e8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/libraries_specification.dart
@@ -238,7 +238,7 @@
               _reportError(messageIncludePathIsNotAString(targetName, specUri));
             }
             Uri uri = Uri.parse(path);
-            if (uri.scheme != '' && uri.scheme != 'file') {
+            if (uri.hasScheme && !uri.isScheme('file')) {
               return _reportError(messageUnsupportedUriScheme(path, specUri));
             }
             LibrariesSpecification specification =
@@ -269,7 +269,7 @@
                 uriString, libraryName, targetName, specUri));
           }
           Uri uri = Uri.parse(uriString);
-          if (uri.scheme != '' && uri.scheme != 'file') {
+          if (uri.hasScheme && !uri.isScheme('file')) {
             return _reportError(
                 messageUnsupportedUriScheme(uriString, specUri));
           }
diff --git a/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart b/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
index 2600d6d..39ce9d4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/util/resolve_input_uri.dart
@@ -18,7 +18,7 @@
 
 Uri parseUri(String path) {
   if (path.startsWith("file:")) {
-    if (Uri.base.scheme == "file") {
+    if (Uri.base.isScheme("file")) {
       // The Uri class doesn't handle relative file URIs correctly, the
       // following works around that issue.
       return new Uri(path: Uri.parse("x-$path").path);
diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart
index e9f6fb0..6dab119 100644
--- a/pkg/_js_interop_checks/lib/js_interop_checks.dart
+++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart
@@ -362,7 +362,7 @@
   /// or a from environment constructor.
   bool _isAllowedExternalUsage(Member member) {
     Uri uri = member.enclosingLibrary.importUri;
-    return uri.scheme == 'dart' &&
+    return uri.isScheme('dart') &&
             _pathsWithAllowedDartExternalUsage.contains(uri.path) ||
         _allowedNativeTestPatterns.any((pattern) => uri.path.contains(pattern));
   }
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index d51da04..e16e3078 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -82,7 +82,7 @@
           if (library != null) {
             var uri = library.source.uri;
             var analysisSession = _unit.declaredElement?.session;
-            if (uri.scheme == 'file' && analysisSession != null) {
+            if (uri.isScheme('file') && analysisSession != null) {
               // for 'file:' URIs, use the path after the project root
               var context = analysisSession.resourceProvider.pathContext;
               var projectRootDir =
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index 3c7bbac..bca2807 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -173,7 +173,7 @@
 
 /// Computes the best URI to import [what] into the [unit] library.
 String? _getRelativeFileUri(DartCompletionRequest request, Uri what) {
-  if (what.scheme == 'file') {
+  if (what.isScheme('file')) {
     var pathContext = request.analysisSession.resourceProvider.pathContext;
 
     var libraryPath = request.libraryElement.source.fullName;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
index 93e6460..7d3b150 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -43,14 +43,14 @@
       }
 
       var importUri = uriSource.uri;
-      if (importUri.scheme != 'package') {
+      if (!importUri.isScheme('package')) {
         return;
       }
 
       // Don't offer to convert a 'package:' URI to itself.
       try {
         var uriContent = importDirective.uriContent;
-        if (uriContent == null || Uri.parse(uriContent).scheme == 'package') {
+        if (uriContent == null || Uri.parse(uriContent).isScheme('package')) {
           return;
         }
       } on FormatException {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
index 7acecb5..49bedd1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -45,7 +45,7 @@
 
     // Ignore if the uri is not a package: uri.
     var sourceUri = resolvedResult.uri;
-    if (sourceUri.scheme != 'package') {
+    if (!sourceUri.isScheme('package')) {
       return;
     }
 
@@ -61,7 +61,7 @@
     }
 
     // Ignore if import uri is not a package: uri.
-    if (importUri.scheme != 'package') {
+    if (!importUri.isScheme('package')) {
       return;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 9066429..f5935dd 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -322,7 +322,7 @@
 /// Computes the best URI to import [what] into [from].
 String getLibrarySourceUri(
     path.Context pathContext, LibraryElement from, Uri what) {
-  if (what.scheme == 'file') {
+  if (what.isScheme('file')) {
     var fromFolder = pathContext.dirname(from.source.fullName);
     var relativeFile = pathContext.relative(what.path, from: fromFolder);
     return pathContext.split(relativeFile).join('/');
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 56c9b15..c43d2d6 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -161,6 +161,7 @@
   CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
   CompileTimeErrorCode.DUPLICATE_PART,
   CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
+  CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR,
   CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE,
   CompileTimeErrorCode.ENUM_WITH_ABSTRACT_MEMBER,
   CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET,
@@ -485,6 +486,7 @@
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+  CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index f916a7c..16f20e9 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -3664,6 +3664,13 @@
     correctionMessage: "Try renaming the constant.",
   );
 
+  static const CompileTimeErrorCode ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR =
+      CompileTimeErrorCode(
+    'ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR',
+    "The invoked constructor isn't a const constructor.",
+    correctionMessage: "Try invoking a const generative constructor.",
+  );
+
   static const CompileTimeErrorCode ENUM_MIXIN_WITH_INSTANCE_VARIABLE =
       CompileTimeErrorCode(
     'ENUM_MIXIN_WITH_INSTANCE_VARIABLE',
@@ -15888,6 +15895,19 @@
 
   /**
    * Parameters:
+   * 0: the number of type parameters that were declared
+   * 1: the number of type arguments provided
+   */
+  static const CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM =
+      CompileTimeErrorCode(
+    'WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM',
+    "The enum is declared with {0} type parameters, but {1} type arguments "
+        "were given.",
+    correctionMessage: "Try adjusting the number of type arguments.",
+  );
+
+  /**
+   * Parameters:
    * 0: the name of the extension being referenced
    * 1: the number of type parameters that were declared
    * 2: the number of type arguments provided
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 1488253..db01b0b 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -91,6 +91,55 @@
     }
   }
 
+  void checkEnumConstantDeclaration(EnumConstantDeclaration node) {
+    var constructorElement = node.constructorElement;
+    if (constructorElement == null) {
+      return;
+    }
+
+    var enumElement = constructorElement.enclosingElement;
+    var typeParameters = enumElement.typeParameters;
+
+    var typeArgumentList = node.arguments?.typeArguments;
+    var typeArgumentNodes = typeArgumentList?.arguments;
+    if (typeArgumentList != null &&
+        typeArgumentNodes != null &&
+        typeArgumentNodes.length != typeParameters.length) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM,
+        typeArgumentList,
+        [typeParameters.length, typeArgumentNodes.length],
+      );
+    }
+
+    if (typeParameters.isEmpty) {
+      return;
+    }
+
+    // Check that type arguments are regular-bounded.
+    var typeArguments = constructorElement.returnType.typeArguments;
+    var substitution = Substitution.fromPairs(typeParameters, typeArguments);
+    for (var i = 0; i < typeArguments.length; i++) {
+      var typeParameter = typeParameters[i];
+      var typeArgument = typeArguments[i];
+
+      var bound = typeParameter.bound;
+      if (bound == null) {
+        continue;
+      }
+
+      bound = substitution.substituteType(bound);
+
+      if (!_typeSystem.isSubtypeOf(typeArgument, bound)) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+          typeArgumentNodes?[i] ?? node.name,
+          [typeArgument, typeParameter.name, bound],
+        );
+      }
+    }
+  }
+
   void checkFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     _checkInvocationTypeArguments(
       node.typeArguments?.arguments,
diff --git a/pkg/analyzer/lib/src/file_system/file_system.dart b/pkg/analyzer/lib/src/file_system/file_system.dart
index b7b4655..d7bfadf 100644
--- a/pkg/analyzer/lib/src/file_system/file_system.dart
+++ b/pkg/analyzer/lib/src/file_system/file_system.dart
@@ -37,5 +37,5 @@
   Uri restoreAbsolute(Source source) => pathToUri(source.fullName);
 
   /// Return `true` if the given [uri] is a `file` URI.
-  static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
+  static bool isFileUri(Uri uri) => uri.isScheme(FILE_SCHEME);
 }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 36d3095..2cc6b50 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -560,6 +560,7 @@
   @override
   void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     _requiredParametersVerifier.visitEnumConstantDeclaration(node);
+    _typeArgumentsVerifier.checkEnumConstantDeclaration(node);
     super.visitEnumConstantDeclaration(node);
   }
 
@@ -2744,21 +2745,26 @@
       return;
     }
 
-    var languageVersionToken = node.languageVersionToken;
-    if (languageVersionToken == null) {
-      return;
-    }
-
     var languageVersion = _currentLibrary.languageVersion.effective;
     if (sourceLanguageConstraint.allows(languageVersion)) {
       return;
     }
 
-    errorReporter.reportErrorForToken(
-      CompileTimeErrorCode.ILLEGAL_LANGUAGE_VERSION_OVERRIDE,
-      languageVersionToken,
-      ['$sourceLanguageConstraint'],
-    );
+    var languageVersionToken = node.languageVersionToken;
+    if (languageVersionToken != null) {
+      errorReporter.reportErrorForToken(
+        CompileTimeErrorCode.ILLEGAL_LANGUAGE_VERSION_OVERRIDE,
+        languageVersionToken,
+        ['$sourceLanguageConstraint'],
+      );
+    } else {
+      errorReporter.reportErrorForOffset(
+        CompileTimeErrorCode.ILLEGAL_LANGUAGE_VERSION_OVERRIDE,
+        0,
+        0,
+        ['$sourceLanguageConstraint'],
+      );
+    }
   }
 
   /// Verify that the given implements [clause] does not implement classes such
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 6253c65..da1b04c 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1565,6 +1565,12 @@
       var constructorElement = constructorName.staticElement;
       if (constructorElement != null) {
         node.constructorElement = constructorElement;
+        if (!constructorElement.isConst && constructorElement.isFactory) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR,
+            node.arguments?.constructorSelector?.name ?? node.name,
+          );
+        }
       } else {
         var typeName = constructorName.type2.name;
         if (typeName.staticElement is EnumElementImpl) {
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index ed375ff..77865a9 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -31,7 +31,7 @@
 
   @Deprecated('Use uri.isScheme("dart") instead')
   @override
-  bool get isInSystemLibrary => uri.scheme == 'dart';
+  bool get isInSystemLibrary => uri.isScheme('dart');
 
   @override
   String get shortName => pathos.basename(fullName);
diff --git a/pkg/analyzer/lib/src/source/package_map_resolver.dart b/pkg/analyzer/lib/src/source/package_map_resolver.dart
index 9b96f99..c1d3bf0 100644
--- a/pkg/analyzer/lib/src/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/src/source/package_map_resolver.dart
@@ -79,6 +79,6 @@
 
   /// Returns `true` if [uri] is a `package` URI.
   static bool isPackageUri(Uri uri) {
-    return uri.scheme == PACKAGE_SCHEME;
+    return uri.isScheme(PACKAGE_SCHEME);
   }
 }
diff --git a/pkg/analyzer/lib/src/source/source_resource.dart b/pkg/analyzer/lib/src/source/source_resource.dart
index 9334b31..3e4adf7 100644
--- a/pkg/analyzer/lib/src/source/source_resource.dart
+++ b/pkg/analyzer/lib/src/source/source_resource.dart
@@ -80,7 +80,7 @@
 
   @Deprecated('Use uri.isScheme("dart") instead')
   @override
-  bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
+  bool get isInSystemLibrary => uri.isScheme(DartUriResolver.DART_SCHEME);
 
   @Deprecated('Not used anymore')
   @override
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index ae54e97..7350937 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -83,7 +83,7 @@
   }
 
   Source? _resolveAbsolute(Uri uri) {
-    if (uri.scheme == 'file') {
+    if (uri.isScheme('file')) {
       var path = fileUriToNormalizedPath(_context, uri);
       var pathRelativeToRoot = _workspace._relativeToRoot(path);
       if (pathRelativeToRoot == null) return null;
@@ -91,7 +91,7 @@
       var file = _workspace.findFile(fullFilePath);
       return file?.createSource(uri);
     }
-    if (uri.scheme != 'package') {
+    if (!uri.isScheme('package')) {
       return null;
     }
     String uriPath = Uri.decodeComponent(uri.path);
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 4e06f04..c30333e 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -73,7 +73,7 @@
 
   @override
   Source? resolveAbsolute(Uri uri) {
-    if (uri.scheme != 'package') {
+    if (!uri.isScheme('package')) {
       return null;
     }
 
diff --git a/pkg/analyzer/lib/src/workspace/workspace.dart b/pkg/analyzer/lib/src/workspace/workspace.dart
index 34ab9c1..035744b 100644
--- a/pkg/analyzer/lib/src/workspace/workspace.dart
+++ b/pkg/analyzer/lib/src/workspace/workspace.dart
@@ -82,7 +82,7 @@
   /// example, the case of a [InSummarySource]). In this case, use
   /// [workspace]'s package URI resolver to fetch the file path.
   String? filePathFromSource(Source source) {
-    if (source.uri.scheme == 'package') {
+    if (source.uri.isScheme('package')) {
       return workspace.packageUriResolver.resolveAbsolute(source.uri)?.fullName;
     } else {
       return source.fullName;
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 25d0a13..3c90ccd 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -3351,6 +3351,9 @@
   ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING:
     problemMessage: "The name of the enum constant can't be the same as the enum's name."
     correctionMessage: Try renaming the constant.
+  ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR:
+    problemMessage: The invoked constructor isn't a const constructor.
+    correctionMessage: Try invoking a const generative constructor.
   ENUM_MIXIN_WITH_INSTANCE_VARIABLE:
     problemMessage: Mixins applied to enums can't have instance variables.
     correctionMessage: Try replacing the instance variables with getters.
@@ -13629,6 +13632,13 @@
       }
       C f() => C.named();
       ```
+  WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM:
+    problemMessage: The enum is declared with {0} type parameters, but {1} type arguments were given.
+    correctionMessage: Try adjusting the number of type arguments.
+    comment: |-
+      Parameters:
+      0: the number of type parameters that were declared
+      1: the number of type arguments provided
   WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION:
     problemMessage: "The extension '{0}' is declared with {1} type parameters, but {2} type arguments were given."
     correctionMessage: Try adjusting the number of type arguments.
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 927a542..c170e15 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -530,9 +530,9 @@
   @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind {
-    if (uri.scheme == 'dart') {
+    if (uri.isScheme('dart')) {
       return UriKind.DART_URI;
-    } else if (uri.scheme == 'package') {
+    } else if (uri.isScheme('package')) {
       return UriKind.PACKAGE_URI;
     }
     return UriKind.FILE_URI;
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 539ff59..996d5d5 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -783,7 +783,7 @@
       if (file is LibraryCycle) {
         return !file.libraries.any((file) => file.uri.isScheme('dart'));
       } else if (file is FileState) {
-        return file.uri.scheme != 'dart';
+        return !file.uri.isScheme('dart');
       } else if (file == null) {
         return true;
       } else {
diff --git a/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart
new file mode 100644
index 0000000..0134e87
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/enum_constant_with_non_const_constructor_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EnumConstantWithNonConstConstructorTest);
+  });
+}
+
+@reflectiveTest
+class EnumConstantWithNonConstConstructorTest extends PubPackageResolutionTest {
+  test_named() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v.named();
+  factory E.named() => throw 0;
+  const E(); 
+}
+''', [
+      error(
+          CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR, 13, 5),
+    ]);
+  }
+
+  test_unnamed_withArguments() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v();
+  factory E() => throw 0;
+  const E.named(); 
+}
+''', [
+      error(
+          CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR, 11, 1),
+    ]);
+  }
+
+  test_unnamed_withoutArguments() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v;
+  factory E() => throw 0;
+  const E.named(); 
+}
+''', [
+      error(
+          CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR, 11, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/illegal_language_version_override_test.dart b/pkg/analyzer/test/src/diagnostics/illegal_language_version_override_test.dart
index a212ea3..3076cbb5a 100644
--- a/pkg/analyzer/test/src/diagnostics/illegal_language_version_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/illegal_language_version_override_test.dart
@@ -40,6 +40,31 @@
     ]);
   }
 
+  test_hasPackageLanguage_less_hasOverride_greater() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.12
+void f() {}
+''');
+  }
+
+  test_hasPackageLanguage_less_noOverride_less() async {
+    writeTestPackageConfig(
+      PackageConfigFileBuilder(),
+      languageVersion: '2.9',
+    );
+
+    await assertErrorsInCode(r'''
+void f() {}
+''', [
+      error(CompileTimeErrorCode.ILLEGAL_LANGUAGE_VERSION_OVERRIDE, 0, 0),
+    ]);
+  }
+
   test_noOverride() async {
     await assertNoErrorsInCode(r'''
 void f() {}
diff --git a/pkg/analyzer/test/src/diagnostics/non_const_generative_enum_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/non_const_generative_enum_constructor_test.dart
index 5f509b3..6b9eaef 100644
--- a/pkg/analyzer/test/src/diagnostics/non_const_generative_enum_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_const_generative_enum_constructor_test.dart
@@ -15,15 +15,6 @@
 
 @reflectiveTest
 class NonConstGenerativeEnumConstructorTest extends PubPackageResolutionTest {
-  test_factory() async {
-    await assertNoErrorsInCode(r'''
-enum E {
-  v(0);
-  factory E(int i) => values[i];
-}
-''');
-  }
-
   test_generative_const() async {
     await assertNoErrorsInCode(r'''
 enum E {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 7534e41..a98026b 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -156,6 +156,8 @@
 import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
 import 'enum_constant_same_name_as_enclosing_test.dart'
     as enum_constant_same_name_as_enclosing;
+import 'enum_constant_with_non_const_constructor_test.dart'
+    as enum_constant_with_non_const_constructor;
 import 'enum_mixin_with_instance_variable_test.dart'
     as enum_mixin_with_instance_variable;
 import 'enum_with_abstract_member_test.dart' as enum_with_abstract_member;
@@ -774,6 +776,8 @@
     as wrong_number_of_parameters_for_operator;
 import 'wrong_number_of_parameters_for_setter_test.dart'
     as wrong_number_of_parameters_for_setter;
+import 'wrong_number_of_type_arguments_enum_test.dart'
+    as wrong_number_of_type_arguments_enum;
 import 'wrong_number_of_type_arguments_extension_test.dart'
     as wrong_number_of_type_arguments_extension;
 import 'wrong_number_of_type_arguments_test.dart'
@@ -891,6 +895,7 @@
     duplicate_part.main();
     duplicate_shown_name.main();
     enum_constant_same_name_as_enclosing.main();
+    enum_constant_with_non_const_constructor.main();
     enum_mixin_with_instance_variable.main();
     enum_with_abstract_member.main();
     equal_elements_in_const_set.main();
@@ -1303,6 +1308,7 @@
     void_with_type_arguments_test.main();
     wrong_number_of_parameters_for_operator.main();
     wrong_number_of_parameters_for_setter.main();
+    wrong_number_of_type_arguments_enum.main();
     wrong_number_of_type_arguments_extension.main();
     wrong_number_of_type_arguments.main();
     wrong_type_parameter_variance_in_superinterface.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
index 3149899..2aea194 100644
--- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -431,6 +431,35 @@
 class TypeArgumentNotMatchingBoundsWithNullSafetyTest
     extends PubPackageResolutionTest
     with TypeArgumentNotMatchingBoundsTestCases {
+  test_enum_inferred() async {
+    await assertErrorsInCode('''
+enum E<T extends int> {
+  v('');
+  const E(T t);
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 26, 1),
+    ]);
+  }
+
+  test_enum_superBounded() async {
+    await assertNoErrorsInCode('''
+enum E<T extends E<T>> {
+  v<Never>()
+}
+''');
+  }
+
+  test_enum_withTypeArguments() async {
+    await assertErrorsInCode('''
+enum E<T extends int> {
+  v<String>()
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 28, 6),
+    ]);
+  }
+
   test_extends_optIn_fromOptOut_Null() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 class A<X extends int> {}
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart
new file mode 100644
index 0000000..60e12c9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for 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/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(WrongNumberOfTypeArgumentsEnumTest);
+  });
+}
+
+@reflectiveTest
+class WrongNumberOfTypeArgumentsEnumTest extends PubPackageResolutionTest {
+  test_tooFew() async {
+    await assertErrorsInCode(r'''
+enum E<T, U> {
+  v<int>()
+}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM, 18, 5),
+    ]);
+  }
+
+  test_tooMany() async {
+    await assertErrorsInCode(r'''
+enum E<T> {
+  v<int, int>()
+}
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM, 15, 10),
+    ]);
+  }
+}
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 19caf6d..fff1252 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -127,7 +127,7 @@
     files.clear();
     errorsResults.clear();
     var libraryUri = libraryFile.uri;
-    if (libraryUri.scheme == 'package' && libraryUri.pathSegments.isNotEmpty) {
+    if (libraryUri.isScheme('package') && libraryUri.pathSegments.isNotEmpty) {
       _selfPackageName = libraryUri.pathSegments[0];
     }
   }
@@ -177,7 +177,7 @@
 
   /// Determine whether the given URI refers to a package being analyzed.
   bool _isAnalyzedPackage(Uri uri) {
-    if (uri.scheme != 'package' || uri.pathSegments.isEmpty) {
+    if (!uri.isScheme('package') || uri.pathSegments.isEmpty) {
       return false;
     }
     var packageName = uri.pathSegments.first;
diff --git a/pkg/analyzer_plugin/doc/tutorial/package_structure.md b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
index 0eb7224..b1f726f 100644
--- a/pkg/analyzer_plugin/doc/tutorial/package_structure.md
+++ b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
@@ -90,4 +90,4 @@
 package, and the file `tools/analyzer_plugin/bin/plugin.dart` is run in its own
 isolate.
 
-[pub]:https://www.dartlang.org/tools/pub/get-started
+[pub]: https://dart.dev/guides/packages
diff --git a/pkg/build_integration/lib/file_system/multi_root.dart b/pkg/build_integration/lib/file_system/multi_root.dart
index 14772cc..7fff8e7 100644
--- a/pkg/build_integration/lib/file_system/multi_root.dart
+++ b/pkg/build_integration/lib/file_system/multi_root.dart
@@ -52,7 +52,7 @@
       _delegate ??= await _resolveEntity();
 
   Future<FileSystemEntity> _resolveEntity() async {
-    if (uri.scheme == multiRootFileSystem.markerScheme) {
+    if (uri.isScheme(multiRootFileSystem.markerScheme)) {
       if (!uri.isAbsolute) {
         throw new FileSystemException(
             uri, "This MultiRootFileSystem only handles absolutes URIs: $uri");
diff --git a/pkg/build_integration/lib/file_system/single_root.dart b/pkg/build_integration/lib/file_system/single_root.dart
index 30cbc66..896dfc3 100644
--- a/pkg/build_integration/lib/file_system/single_root.dart
+++ b/pkg/build_integration/lib/file_system/single_root.dart
@@ -33,7 +33,7 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme != markerScheme) {
+    if (!uri.isScheme(markerScheme)) {
       throw new FileSystemException(
           uri,
           "This SingleRootFileSystem only handles URIs with the '$markerScheme'"
diff --git a/pkg/compiler/lib/compiler.dart b/pkg/compiler/lib/compiler.dart
index b3e8552..b9c098a 100644
--- a/pkg/compiler/lib/compiler.dart
+++ b/pkg/compiler/lib/compiler.dart
@@ -118,7 +118,7 @@
 /// Kind of diagnostics that the compiler can report.
 class Diagnostic {
   /// An error as identified by the "Dart Programming Language
-  /// Specification" [http://www.dartlang.org/docs/spec/].
+  /// Specification" [https://dart.dev/guides/language/spec].
   ///
   /// Note: the compiler may still produce an executable result after
   /// reporting a compilation error. The specification says:
@@ -133,7 +133,7 @@
   static const Diagnostic ERROR = const Diagnostic(1, 'error');
 
   /// A warning as identified by the "Dart Programming Language
-  /// Specification" [http://www.dartlang.org/docs/spec/].
+  /// Specification" [https://dart.dev/guides/language/spec].
   static const Diagnostic WARNING = const Diagnostic(2, 'warning');
 
   /// Any other warning that is not covered by [WARNING].
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 9bbada1..4c636e3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -726,7 +726,7 @@
   Uri getCanonicalUri(Entity element) {
     Uri libraryUri = _uriFromElement(element);
     if (libraryUri == null) return null;
-    if (libraryUri.scheme == 'package') {
+    if (libraryUri.isScheme('package')) {
       int slashPos = libraryUri.path.indexOf('/');
       if (slashPos != -1) {
         String packageName = libraryUri.path.substring(0, slashPos);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index a57892b..7cb0173 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -1102,7 +1102,7 @@
 
 void writeString(Uri uri, String text) {
   if (!enableWriteString) return;
-  if (uri.scheme != 'file') {
+  if (!uri.isScheme('file')) {
     fail('Unhandled scheme ${uri.scheme}.');
   }
   var file = (File(uri.toFilePath())..createSync(recursive: true))
diff --git a/pkg/compiler/lib/src/diagnostics/code_location.dart b/pkg/compiler/lib/src/diagnostics/code_location.dart
index 58bc177..515f359 100644
--- a/pkg/compiler/lib/src/diagnostics/code_location.dart
+++ b/pkg/compiler/lib/src/diagnostics/code_location.dart
@@ -18,7 +18,7 @@
   String relativize(Uri baseUri);
 
   factory CodeLocation(Uri uri) {
-    if (uri.scheme == 'package') {
+    if (uri.isScheme('package')) {
       int slashPos = uri.path.indexOf('/');
       if (slashPos != -1) {
         String packageName = uri.path.substring(0, slashPos);
@@ -42,7 +42,7 @@
 
   @override
   bool inSameLocation(Uri uri) {
-    return this.uri.scheme == uri.scheme;
+    return this.uri.isScheme(uri.scheme);
   }
 
   @override
@@ -62,7 +62,7 @@
 
   @override
   bool inSameLocation(Uri uri) {
-    return uri.scheme == 'package' && uri.path.startsWith('$packageName/');
+    return uri.isScheme('package') && uri.path.startsWith('$packageName/');
   }
 
   @override
diff --git a/pkg/compiler/lib/src/elements/entity_utils.dart b/pkg/compiler/lib/src/elements/entity_utils.dart
index 2942392..7e58133 100644
--- a/pkg/compiler/lib/src/elements/entity_utils.dart
+++ b/pkg/compiler/lib/src/elements/entity_utils.dart
@@ -19,17 +19,17 @@
   }
 
   // Order: platform < package < other.
-  if (a.scheme == 'dart') {
-    if (b.scheme == 'dart') return byCanonicalUriPath();
+  if (a.isScheme('dart')) {
+    if (b.isScheme('dart')) return byCanonicalUriPath();
     return -1;
   }
-  if (b.scheme == 'dart') return 1;
+  if (b.isScheme('dart')) return 1;
 
-  if (a.scheme == 'package') {
-    if (b.scheme == 'package') return byCanonicalUriPath();
+  if (a.isScheme('package')) {
+    if (b.isScheme('package')) return byCanonicalUriPath();
     return -1;
   }
-  if (b.scheme == 'package') return 1;
+  if (b.isScheme('package')) return 1;
 
   return _compareCanonicalUri(a, b);
 }
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index 27b00cb..e825b52 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -251,7 +251,7 @@
 
 /// Returns true if [importUri] corresponds to dart:html and related libraries.
 bool _isWebLibrary(Uri importUri) =>
-    importUri.scheme == 'dart' &&
+    importUri.isScheme('dart') &&
         (importUri.path == 'html' ||
             importUri.path == 'svg' ||
             importUri.path == 'indexed_db' ||
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 7ae9894..cf4c049 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -156,7 +156,7 @@
 
   Uri uri = member.enclosingLibrary.importUri;
   bool platformAnnotationsAllowed =
-      options.testMode || uri.scheme == 'dart' || maybeEnableNative(uri);
+      options.testMode || uri.isScheme('dart') || maybeEnableNative(uri);
 
   for (PragmaAnnotationData data in pragmaAnnotationData) {
     String name = data.name;
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 23f8c73..6f87f10 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -158,7 +158,7 @@
   bool _isValidBackendUse(Entity element, LibraryEntity library) {
     if (_isValidEntity(element)) return true;
     SourceSpan span = _frontendStrategy.spanFromSpannable(element, element);
-    if (library.canonicalUri.scheme == 'dart' &&
+    if (library.canonicalUri.isScheme('dart') &&
         span.uri.path.contains('_internal/js_runtime/lib/')) {
       // TODO(johnniwinther): We should be more precise about these.
       return true;
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 156e7a4..c6e7a5e 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -55,7 +55,7 @@
 
 bool maybeEnableNative(Uri uri) {
   bool allowedDartLibrary() {
-    if (uri.scheme != 'dart') return false;
+    if (!uri.isScheme('dart')) return false;
     return _allowedDartSchemePaths.contains(uri.path);
   }
 
@@ -118,7 +118,7 @@
   bool allowPlatformPrivateLibraryAccess(Uri importer, Uri imported) =>
       super.allowPlatformPrivateLibraryAccess(importer, imported) ||
       maybeEnableNative(importer) ||
-      (importer.scheme == 'package' &&
+      (importer.isScheme('package') &&
           importer.path.startsWith('dart2js_runtime_metrics/'));
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 9a542a8..605b3bd 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -23,7 +23,7 @@
 
   @override
   fe.FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'data') {
+    if (uri.isScheme('data')) {
       return fe.DataFileSystemEntity(Uri.base.resolveUri(uri));
     } else {
       return _CompilerFileSystemEntity(uri, this);
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index cdab490..aaf5016 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -269,7 +269,7 @@
 
       // Libraries dependencies do not show implicit imports to `dart:core`.
       var dartCore = component.libraries.firstWhere((lib) {
-        return lib.importUri.scheme == 'dart' && lib.importUri.path == 'core';
+        return lib.importUri.isScheme('dart') && lib.importUri.path == 'core';
       });
       search(dartCore);
 
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index c2efa63..c0c8468 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -826,7 +826,7 @@
       return true;
     }
     if (shownPackageWarnings != null) {
-      return uri.scheme == 'package' &&
+      return uri.isScheme('package') &&
           shownPackageWarnings!.contains(uri.pathSegments.first);
     }
     return false;
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 359fead..c869d49 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -40,9 +40,9 @@
     }
     if (input != null) return Future.value(input);
 
-    if (resourceUri.scheme == 'file') {
+    if (resourceUri.isScheme('file')) {
       return _readFromFile(resourceUri, inputKind);
-    } else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
+    } else if (resourceUri.isScheme('http') || resourceUri.isScheme('https')) {
       return _readFromHttp(resourceUri, inputKind);
     } else {
       throw ArgumentError("Unknown scheme in uri '$resourceUri'");
@@ -50,7 +50,7 @@
   }
 
   api.Input _readFromFileSync(Uri resourceUri, api.InputKind inputKind) {
-    assert(resourceUri.scheme == 'file');
+    assert(resourceUri.isScheme('file'));
     List<int> source;
     try {
       source = readAll(resourceUri.toFilePath(),
@@ -99,7 +99,7 @@
 
   Future<api.Input<List<int>>> _readFromHttp(
       Uri resourceUri, api.InputKind inputKind) {
-    assert(resourceUri.scheme == 'http');
+    assert(resourceUri.isScheme('http'));
     HttpClient client = HttpClient();
     return client
         .getUrl(resourceUri)
@@ -279,7 +279,7 @@
       api.Input file = provider.getUtf8SourceFile(uri);
       if (file == null &&
           autoReadFileUri &&
-          (uri.scheme == 'file' || !uri.isAbsolute) &&
+          (uri.isScheme('file') || !uri.isAbsolute) &&
           uri.path.endsWith('.dart')) {
         if (!uri.isAbsolute) {
           uri = provider.cwd.resolveUri(uri);
@@ -379,7 +379,7 @@
     Uri uri = createUri(name, extension, type);
     bool isPrimaryOutput = uri == out;
 
-    if (uri.scheme != 'file') {
+    if (!uri.isScheme('file')) {
       onFailure('Unhandled scheme ${uri.scheme} in $uri.');
     }
 
@@ -428,7 +428,7 @@
 
     allOutputFiles.add(fe.relativizeUri(Uri.base, uri, Platform.isWindows));
 
-    if (uri.scheme != 'file') {
+    if (!uri.isScheme('file')) {
       onFailure('Unhandled scheme ${uri.scheme} in $uri.');
     }
 
@@ -608,7 +608,7 @@
   Future<api.Input<List<int>>> readFromUri(Uri uri,
       {InputKind inputKind = InputKind.UTF8}) async {
     var resolvedUri = uri;
-    if (resolvedUri.scheme == markerScheme) {
+    if (resolvedUri.isScheme(markerScheme)) {
       var path = resolvedUri.path;
       if (path.startsWith('/')) path = path.substring(1);
       for (var dir in roots) {
@@ -634,7 +634,7 @@
 
   @override
   api.Input autoReadFromFile(Uri resourceUri) {
-    if (resourceUri.scheme == markerScheme) {
+    if (resourceUri.isScheme(markerScheme)) {
       var path = resourceUri.path;
       for (var dir in roots) {
         var file = dir.resolve(path);
diff --git a/pkg/compiler/test/analyses/analysis_helper.dart b/pkg/compiler/test/analyses/analysis_helper.dart
index b104a00..0d427c6 100644
--- a/pkg/compiler/test/analyses/analysis_helper.dart
+++ b/pkg/compiler/test/analyses/analysis_helper.dart
@@ -40,7 +40,7 @@
   Uri packageConfig = getPackages(argResults);
   List<String> options = getOptions(argResults);
   run(entryPoint, null,
-      analyzedUrisFilter: (Uri uri) => uri.scheme != 'dart',
+      analyzedUrisFilter: (Uri uri) => !uri.isScheme('dart'),
       librariesSpecificationUri: librariesSpecificationUri,
       packageConfig: packageConfig,
       options: options);
@@ -362,7 +362,7 @@
   String reportAssertionFailure(ir.Node node, String message) {
     SourceSpan span = computeSourceSpanFromTreeNode(node);
     Uri uri = span.uri;
-    if (uri.scheme == 'org-dartlang-sdk') {
+    if (uri.isScheme('org-dartlang-sdk')) {
       span = new SourceSpan(
           Uri.base.resolve(uri.path.substring(1)), span.begin, span.end);
     }
@@ -378,7 +378,7 @@
     String uriString = relativizeUri(Uri.base, uri, Platform.isWindows);
     Map<String, List<DiagnosticMessage>> actualMap = _actualMessages
         .putIfAbsent(uriString, () => <String, List<DiagnosticMessage>>{});
-    if (uri.scheme == 'org-dartlang-sdk') {
+    if (uri.isScheme('org-dartlang-sdk')) {
       span = new SourceSpan(
           Uri.base.resolve(uri.path.substring(1)), span.begin, span.end);
     }
diff --git a/pkg/compiler/test/analyses/api_dynamic_test.dart b/pkg/compiler/test/analyses/api_dynamic_test.dart
index 8119a4e..543cd86 100644
--- a/pkg/compiler/test/analyses/api_dynamic_test.dart
+++ b/pkg/compiler/test/analyses/api_dynamic_test.dart
@@ -14,7 +14,7 @@
   asyncTest(() async {
     await run(
         Uri.parse('memory:main.dart'), 'pkg/compiler/test/analyses/$goldenFile',
-        analyzedUrisFilter: (Uri uri) => uri.scheme == 'dart',
+        analyzedUrisFilter: (Uri uri) => uri.isScheme('dart'),
         memorySourceFiles: {'main.dart': 'main() {}'},
         verbose: args.contains('-v'),
         generate: args.contains('-g'));
diff --git a/pkg/compiler/test/end_to_end/modular_loader_test.dart b/pkg/compiler/test/end_to_end/modular_loader_test.dart
index 6b5c882..bc59954 100644
--- a/pkg/compiler/test/end_to_end/modular_loader_test.dart
+++ b/pkg/compiler/test/end_to_end/modular_loader_test.dart
@@ -109,7 +109,7 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'file') return physical.entityForUri(uri);
+    if (uri.isScheme('file')) return physical.entityForUri(uri);
     return memory.entityForUri(uri);
   }
 }
diff --git a/pkg/compiler/test/equivalence/id_equivalence_helper.dart b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
index 8a34cb9..30524c0 100644
--- a/pkg/compiler/test/equivalence/id_equivalence_helper.dart
+++ b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
@@ -248,8 +248,8 @@
 
   bool excludeLibrary(LibraryEntity library) {
     return forUserLibrariesOnly &&
-        (library.canonicalUri.scheme == 'dart' ||
-            library.canonicalUri.scheme == 'package');
+        (library.canonicalUri.isScheme('dart') ||
+            library.canonicalUri.isScheme('package'));
   }
 
   ir.Library getIrLibrary(LibraryEntity library) {
diff --git a/pkg/compiler/test/equivalence/show_helper.dart b/pkg/compiler/test/equivalence/show_helper.dart
index ecc6257..4aa3850 100644
--- a/pkg/compiler/test/equivalence/show_helper.dart
+++ b/pkg/compiler/test/equivalence/show_helper.dart
@@ -65,7 +65,7 @@
     SourceFileProvider provider = data.compiler.provider;
     for (Uri uri in data.actualMaps.keys) {
       Uri fileUri = uri;
-      if (fileUri.scheme == 'org-dartlang-sdk') {
+      if (fileUri.isScheme('org-dartlang-sdk')) {
         fileUri = Uri.base.resolve(fileUri.path.substring(1));
       }
       if (show != null && !show.any((f) => '$fileUri'.endsWith(f))) {
diff --git a/pkg/compiler/test/helpers/element_lookup.dart b/pkg/compiler/test/helpers/element_lookup.dart
index 0ff12c2..ae8bfa2 100644
--- a/pkg/compiler/test/helpers/element_lookup.dart
+++ b/pkg/compiler/test/helpers/element_lookup.dart
@@ -21,8 +21,8 @@
       closedWorld.commonElements.jsHelperLibrary, name);
   if (cls == null) {
     for (LibraryEntity library in elementEnvironment.libraries) {
-      if (library.canonicalUri.scheme != 'dart' &&
-          library.canonicalUri.scheme != 'package') {
+      if (!library.canonicalUri.isScheme('dart') &&
+          !library.canonicalUri.isScheme('package')) {
         cls = elementEnvironment.lookupClass(library, name);
         if (cls != null) {
           break;
@@ -70,8 +70,8 @@
       setter: isSetter);
   if (member == null) {
     for (LibraryEntity library in elementEnvironment.libraries) {
-      if (library.canonicalUri.scheme != 'dart' &&
-          library.canonicalUri.scheme != 'package') {
+      if (!library.canonicalUri.isScheme('dart') &&
+          !library.canonicalUri.isScheme('package')) {
         member = elementEnvironment.lookupLibraryMember(library, name,
             setter: isSetter);
         if (member != null) {
diff --git a/pkg/compiler/test/helpers/memory_source_file_helper.dart b/pkg/compiler/test/helpers/memory_source_file_helper.dart
index 865d20e..a15262b 100644
--- a/pkg/compiler/test/helpers/memory_source_file_helper.dart
+++ b/pkg/compiler/test/helpers/memory_source_file_helper.dart
@@ -31,7 +31,7 @@
   @override
   Future<Input<List<int>>> readBytesFromUri(
       Uri resourceUri, InputKind inputKind) {
-    if (resourceUri.scheme != 'memory') {
+    if (!resourceUri.isScheme('memory')) {
       return super.readBytesFromUri(resourceUri, inputKind);
     }
     // TODO(johnniwinther): We should use inputs already in the cache. Some
diff --git a/pkg/compiler/test/model/cfe_annotations_test.dart b/pkg/compiler/test/model/cfe_annotations_test.dart
index 9cb3b6e..e6e164a 100644
--- a/pkg/compiler/test/model/cfe_annotations_test.dart
+++ b/pkg/compiler/test/model/cfe_annotations_test.dart
@@ -351,7 +351,7 @@
         }
 
         for (ir.Library library in component.libraries) {
-          if (library.importUri.scheme == 'memory') {
+          if (library.importUri.isScheme('memory')) {
             String libraryId = library.importUri.path;
             LibraryEntity libraryEntity = elementMap.getLibrary(library);
 
diff --git a/pkg/compiler/test/model/receiver_type_test.dart b/pkg/compiler/test/model/receiver_type_test.dart
index d7567dc..7c73276 100644
--- a/pkg/compiler/test/model/receiver_type_test.dart
+++ b/pkg/compiler/test/model/receiver_type_test.dart
@@ -52,7 +52,7 @@
   Selector callSelector = new Selector.callClosure(0);
   closedWorld.classHierarchy.forEachStrictSubclassOf(
       closedWorld.commonElements.objectClass, (ClassEntity cls) {
-    if (cls.library.canonicalUri.scheme != 'memory')
+    if (!cls.library.canonicalUri.isScheme('memory'))
       return IterationStep.CONTINUE;
 
     TypeMask mask = new TypeMask.nonNullSubclass(cls, closedWorld);
diff --git a/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart b/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
index 6bca3c3..8f5e582 100644
--- a/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
+++ b/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
@@ -157,7 +157,7 @@
       .process(['--csp', Flags.disableInlining, ...options], verbose: verbose);
   TestResult result = new TestResult(config, filename, processor);
   for (SourceMapInfo info in sourceMaps.elementSourceMapInfos.values) {
-    if (info.element.library.canonicalUri.scheme == 'dart') continue;
+    if (info.element.library.canonicalUri.isScheme('dart')) continue;
     result.userInfoList.add(info);
     Iterable<CodePoint> missingCodePoints =
         info.codePoints.where((c) => c.isMissing);
diff --git a/pkg/compiler/tool/modular_test_suite_helper.dart b/pkg/compiler/tool/modular_test_suite_helper.dart
index cd583ad..d4ff09e 100644
--- a/pkg/compiler/tool/modular_test_suite_helper.dart
+++ b/pkg/compiler/tool/modular_test_suite_helper.dart
@@ -638,7 +638,7 @@
       String sourceUriOrPath, String relativeSnapshotPath) async {
     Uri sourceUri = sdkRoot.resolve(sourceUriOrPath);
     String result =
-        sourceUri.scheme == 'file' ? sourceUri.toFilePath() : sourceUriOrPath;
+        sourceUri.isScheme('file') ? sourceUri.toFilePath() : sourceUriOrPath;
     if (_options.useSdk) {
       String snapshot = Uri.file(Platform.resolvedExecutable)
           .resolve(relativeSnapshotPath)
diff --git a/pkg/dart2js_info/bin/src/deferred_library_layout.dart b/pkg/dart2js_info/bin/src/deferred_library_layout.dart
index 1c4f13f..95f20a5 100644
--- a/pkg/dart2js_info/bin/src/deferred_library_layout.dart
+++ b/pkg/dart2js_info/bin/src/deferred_library_layout.dart
@@ -64,7 +64,7 @@
     print('  contains:');
     map.forEach((lib, elements) {
       var uri = lib.uri;
-      var shortUri = (uri.scheme == 'file' && uri.path.startsWith(dir))
+      var shortUri = (uri.isScheme('file') && uri.path.startsWith(dir))
           ? uri.path.substring(dir.length + 1)
           : '$uri';
 
diff --git a/pkg/dart2js_info/lib/deferred_library_check.dart b/pkg/dart2js_info/lib/deferred_library_check.dart
index ef35cec..3b5c365c 100644
--- a/pkg/dart2js_info/lib/deferred_library_check.dart
+++ b/pkg/dart2js_info/lib/deferred_library_check.dart
@@ -133,7 +133,7 @@
   return current;
 }
 
-bool _isPackageUri(Uri uri) => uri.scheme == 'package';
+bool _isPackageUri(Uri uri) => uri.isScheme('package');
 
 String _getPackageName(Uri uri) {
   assert(_isPackageUri(uri));
diff --git a/pkg/dart2js_info/lib/src/util.dart b/pkg/dart2js_info/lib/src/util.dart
index 9ee83cb..874202c 100644
--- a/pkg/dart2js_info/lib/src/util.dart
+++ b/pkg/dart2js_info/lib/src/util.dart
@@ -116,7 +116,7 @@
     info = info.parent;
   }
   if (info is LibraryInfo) {
-    if (info.uri.scheme == 'package') {
+    if (info.uri.isScheme('package')) {
       return '${info.uri}'.split('/').first;
     }
   }
diff --git a/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart b/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart
index 4a43b6c..c04c951 100644
--- a/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart
+++ b/pkg/dart2js_tools/lib/deobfuscate_stack_trace.dart
@@ -31,7 +31,7 @@
   var provider = CachingFileProvider();
   StackDeobfuscationResult result = deobfuscateStack(obfuscatedTrace, provider);
   Frame firstFrame = result.original.frames.first;
-  String translatedError = (firstFrame.uri.scheme == 'error'
+  String translatedError = (firstFrame.uri.isScheme('error')
           ? null
           : translate(error, provider.mappingFor(firstFrame.uri))) ??
       '<no error message found>';
diff --git a/pkg/dart2js_tools/lib/src/util.dart b/pkg/dart2js_tools/lib/src/util.dart
index 1a733ac..eb8c366 100644
--- a/pkg/dart2js_tools/lib/src/util.dart
+++ b/pkg/dart2js_tools/lib/src/util.dart
@@ -34,7 +34,7 @@
 /// deobfuscation locally for debugging purposes.
 class DownloadedFileProvider extends CachingFileProvider {
   _localize(uri) {
-    if (uri.scheme == 'http' || uri.scheme == 'https') {
+    if (uri.isScheme('http') || uri.isScheme('https')) {
       String filename = uri.path.substring(uri.path.lastIndexOf('/') + 1);
       return Uri.base.resolve(filename);
     }
diff --git a/pkg/dartdev/lib/src/commands/devtools.dart b/pkg/dartdev/lib/src/commands/devtools.dart
index 63ff69c..4163e0d 100644
--- a/pkg/dartdev/lib/src/commands/devtools.dart
+++ b/pkg/dartdev/lib/src/commands/devtools.dart
@@ -14,7 +14,10 @@
   DevToolsCommand({
     this.customDevToolsPath,
     bool verbose = false,
-  })  : _argParser = DevToolsServer.buildArgParser(verbose: verbose),
+  })  : _argParser = DevToolsServer.buildArgParser(
+          verbose: verbose,
+          includeHelpOption: false,
+        ),
         super(
           'devtools',
           DevToolsServer.commandDescription,
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index f31e447..4d8a5e7 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -46,13 +46,13 @@
     DevToolsConfiguration? devToolsConfiguration,
     bool logRequests = false,
   }) async {
-    if (remoteVmServiceUri.scheme != 'http') {
+    if (!remoteVmServiceUri.isScheme('http')) {
       throw ArgumentError(
         'remoteVmServiceUri must have an HTTP scheme. Actual: ${remoteVmServiceUri.scheme}',
       );
     }
     if (serviceUri != null) {
-      if (serviceUri.scheme != 'http') {
+      if (!serviceUri.isScheme('http')) {
         throw ArgumentError(
           'serviceUri must have an HTTP scheme. Actual: ${serviceUri.scheme}',
         );
diff --git a/pkg/dds/lib/devtools_server.dart b/pkg/dds/lib/devtools_server.dart
index 1462458..185876e 100644
--- a/pkg/dds/lib/devtools_server.dart
+++ b/pkg/dds/lib/devtools_server.dart
@@ -47,8 +47,24 @@
   late ClientManager clientManager;
   final bool _isChromeOS = File('/dev/.cros_milestone').existsSync();
 
-  static ArgParser buildArgParser({bool verbose = false}) {
+  /// Builds an arg parser for the DevTools server.
+  ///
+  /// [includeHelpOption] should be set to false if this arg parser will be used
+  /// in a Command subclass.
+  static ArgParser buildArgParser({
+    bool verbose = false,
+    bool includeHelpOption = true,
+  }) {
     final argParser = ArgParser();
+
+    if (includeHelpOption) {
+      argParser.addFlag(
+        argHelp,
+        negatable: false,
+        abbr: 'h',
+        help: 'Prints help output.',
+      );
+    }
     argParser
       ..addFlag(
         argVersion,
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 9761f01..14685a4 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -460,11 +460,11 @@
 }
 
 bool isSdkInternalRuntimeUri(Uri importUri) {
-  return importUri.scheme == 'dart' && importUri.path == '_runtime';
+  return importUri.isScheme('dart') && importUri.path == '_runtime';
 }
 
 String libraryUriToJsIdentifier(Uri importUri) {
-  if (importUri.scheme == 'dart') {
+  if (importUri.isScheme('dart')) {
     return isSdkInternalRuntimeUri(importUri) ? 'dart' : importUri.path;
   }
   return pathToJSIdentifier(p.withoutExtension(importUri.pathSegments.last));
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index f70d35b..02472f7 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -347,7 +347,7 @@
 
 Uri sourcePathToRelativeUri(String source, {bool windows}) {
   var uri = sourcePathToUri(source, windows: windows);
-  if (uri.scheme == 'file') {
+  if (uri.isScheme('file')) {
     var uriPath = uri.path;
     var root = Uri.base.path;
     if (uriPath.startsWith(root)) {
@@ -400,7 +400,7 @@
       return sourcePath;
     }
 
-    if (uri.scheme == 'http') return sourcePath;
+    if (uri.isScheme('http')) return sourcePath;
 
     // Convert to a local file path if it's not.
     sourcePath = sourcePathToUri(p.absolute(p.fromUri(uri))).path;
diff --git a/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart b/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart
index b2647e0..33b6496 100644
--- a/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart
+++ b/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart
@@ -32,7 +32,7 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'file') {
+    if (uri.isScheme('file')) {
       return original.entityForUri(uri);
     }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 605c339..f6fc3a2 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -177,7 +177,7 @@
       options.multiRootScheme, multiRootPaths, fe.StandardFileSystem.instance);
 
   Uri toCustomUri(Uri uri) {
-    if (uri.scheme == '') {
+    if (!uri.hasScheme) {
       return Uri(scheme: options.multiRootScheme, path: '/' + uri.path);
     }
     return uri;
@@ -486,7 +486,7 @@
       compilerState.incrementalCompiler.updateNeededDillLibrariesWithHierarchy(
           neededDillLibraries, result.classHierarchy);
       for (var lib in neededDillLibraries) {
-        if (lib.importUri.scheme == 'dart') continue;
+        if (lib.importUri.isScheme('dart')) continue;
         var uri = compilerState.libraryToInputDill[lib.importUri];
         if (uri == null) {
           throw StateError('Library ${lib.importUri} was recorded as used, '
@@ -552,7 +552,7 @@
   var component = loadComponentFromBinary(inputs.single);
   var invalidLibraries = <Uri>[];
   for (var library in component.libraries) {
-    if (library.importUri.scheme != 'dart') {
+    if (!library.importUri.isScheme('dart')) {
       invalidLibraries.add(library.importUri);
     }
   }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 3919691..f0a8fc7 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -496,10 +496,10 @@
   @override
   String jsLibraryAlias(Library library) {
     var uri = library.importUri.normalizePath();
-    if (uri.scheme == 'dart') return null;
+    if (uri.isScheme('dart')) return null;
 
     Iterable<String> segments;
-    if (uri.scheme == 'package') {
+    if (uri.isScheme('package')) {
       // Strip the package name.
       segments = uri.pathSegments.skip(1);
     } else {
@@ -521,7 +521,7 @@
   /// True when [library] is the sdk internal library 'dart:_internal'.
   bool _isDartInternal(Library library) {
     var importUri = library.importUri;
-    return importUri.scheme == 'dart' && importUri.path == '_internal';
+    return importUri.isScheme('dart') && importUri.path == '_internal';
   }
 
   @override
@@ -531,7 +531,7 @@
 
   @override
   String libraryToModule(Library library) {
-    if (library.importUri.scheme == 'dart') {
+    if (library.importUri.isScheme('dart')) {
       // TODO(jmesserly): we need to split out HTML.
       return js_ast.dartSdkModule;
     }
@@ -1940,7 +1940,7 @@
 
   bool _isForwardingStub(Procedure member) {
     if (member.isForwardingStub || member.isForwardingSemiStub) {
-      if (_currentLibrary.importUri.scheme != 'dart') return true;
+      if (!_currentLibrary.importUri.isScheme('dart')) return true;
       // TODO(jmesserly): external methods in the SDK seem to get incorrectly
       // tagged as forwarding stubs even if they are patched. Perhaps there is
       // an ordering issue in CFE. So for now we pattern match to see if it
@@ -2254,7 +2254,7 @@
         _hierarchy.getClassAsInstanceOf(c.superclass, _coreTypes.iterableClass);
     if (parentIterable != null) return null;
 
-    if (c.enclosingLibrary.importUri.scheme == 'dart' &&
+    if (c.enclosingLibrary.importUri.isScheme('dart') &&
         c.procedures.any((m) => _jsExportName(m) == 'Symbol.iterator')) {
       return null;
     }
@@ -2764,7 +2764,7 @@
     var fn = _emitFunction(p.function, p.name.text)
       ..sourceInformation = _nodeEnd(p.fileEndOffset);
 
-    if (_currentLibrary.importUri.scheme == 'dart' &&
+    if (_currentLibrary.importUri.isScheme('dart') &&
         _isInlineJSFunction(p.function.body)) {
       fn = js_ast.simplifyPassThroughArrowFunCallBody(fn);
     }
@@ -3737,7 +3737,7 @@
 
   bool _reifyGenericFunction(Member m) =>
       m == null ||
-      m.enclosingLibrary.importUri.scheme != 'dart' ||
+      !m.enclosingLibrary.importUri.isScheme('dart') ||
       !m.annotations
           .any((a) => isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'));
 
@@ -5692,7 +5692,7 @@
 
   bool _isWebLibrary(Uri importUri) =>
       importUri != null &&
-      importUri.scheme == 'dart' &&
+      importUri.isScheme('dart') &&
       (importUri.path == 'html' ||
           importUri.path == 'svg' ||
           importUri.path == 'indexed_db' ||
@@ -5792,7 +5792,7 @@
 
     if (args.positional.isEmpty &&
         args.named.isEmpty &&
-        ctorClass.enclosingLibrary.importUri.scheme == 'dart') {
+        ctorClass.enclosingLibrary.importUri.isScheme('dart')) {
       // Skip the slow SDK factory constructors when possible.
       switch (ctorClass.name) {
         case 'Map':
@@ -6308,7 +6308,7 @@
       ]);
 
   bool _reifyFunctionType(FunctionNode f) {
-    if (_currentLibrary.importUri.scheme != 'dart') return true;
+    if (!_currentLibrary.importUri.isScheme('dart')) return true;
     var parent = f.parent;
 
     // SDK libraries can skip reification if they request it.
@@ -6337,7 +6337,7 @@
   /// under which functions are compiled and exported.
   String _jsExportName(NamedNode n) {
     var library = getLibrary(n);
-    if (library == null || library.importUri.scheme != 'dart') return null;
+    if (library == null || !library.importUri.isScheme('dart')) return null;
 
     return _annotationName(n, isJSExportNameAnnotation);
   }
@@ -6363,7 +6363,7 @@
   js_ast.Expression visitConstant(Constant node) {
     if (node is StaticTearOffConstant) {
       // JS() or external JS consts should not be lazily loaded.
-      var isSdk = node.target.enclosingLibrary.importUri.scheme == 'dart';
+      var isSdk = node.target.enclosingLibrary.importUri.isScheme('dart');
       if (_isInForeignJS) {
         return _emitStaticTarget(node.target);
       }
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
index 215ba19..4ba953c 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -299,7 +299,7 @@
     var libraryUri = Uri.parse(request.libraryUri);
     var moduleName = request.moduleName;
 
-    if (libraryUri.scheme == 'dart') {
+    if (libraryUri.isScheme('dart')) {
       // compiling expressions inside the SDK currently fails because
       // SDK kernel outlines do not contain information that is needed
       // to detect the scope for expression evaluation - such as local
@@ -329,7 +329,7 @@
     var originalComponent = _moduleCache.componentForModuleName[moduleName];
 
     var component = _sdkComponent;
-    if (libraryUri.scheme != 'dart') {
+    if (!libraryUri.isScheme('dart')) {
       _processedOptions.ticker.logMs('Collecting libraries for $moduleName');
 
       var libraries =
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 44fe33a..fa868d9 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -92,7 +92,7 @@
   var c = getAnnotationClass(value);
   if (c != null && c.name == className) {
     var uri = c.enclosingLibrary.importUri;
-    return uri.scheme == 'dart' && uri.path == libraryName;
+    return uri.isScheme('dart') && uri.path == libraryName;
   }
   return false;
 }
@@ -223,7 +223,7 @@
 ///
 /// `dart:html` has many of these.
 bool isUnsupportedFactoryConstructor(Procedure node) {
-  if (node.name.isPrivate && node.enclosingLibrary.importUri.scheme == 'dart') {
+  if (node.name.isPrivate && node.enclosingLibrary.importUri.isScheme('dart')) {
     var body = node.function.body;
     if (body is Block) {
       var statements = body.statements;
@@ -365,4 +365,4 @@
 }
 
 bool _isDartInternal(Uri uri) =>
-    uri.scheme == 'dart' && uri.path == '_internal';
+    uri.isScheme('dart') && uri.path == '_internal';
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index 665f722..6ff4cdf 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -170,5 +170,5 @@
   var c = getAnnotationClass(annotation);
   return c != null &&
       (c.name == 'Native' || c.name == 'JsPeerInterface') &&
-      c.enclosingLibrary.importUri.scheme == 'dart';
+      c.enclosingLibrary.importUri.isScheme('dart');
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 71aaed2..c1ec743 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -338,9 +338,9 @@
 
   bool _isInternalSdkAnnotation(Library library) {
     var uri = library.importUri;
-    return uri.scheme == 'dart' && uri.pathSegments[0] == '_js_helper' ||
+    return uri.isScheme('dart') && uri.pathSegments[0] == '_js_helper' ||
         allowPackageMetaAnnotations &&
-            uri.scheme == 'package' &&
+            uri.isScheme('package') &&
             uri.pathSegments[0] == 'meta';
   }
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 90dc78e..2fb1100 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -120,11 +120,11 @@
   /// test framework.
   bool _allowedTestLibrary(Uri uri) {
     // Multi-root scheme used by modular test framework.
-    if (uri.scheme == 'dev-dart-app') return true;
+    if (uri.isScheme('dev-dart-app')) return true;
     return allowedNativeTest(uri);
   }
 
-  bool _allowedDartLibrary(Uri uri) => uri.scheme == 'dart';
+  bool _allowedDartLibrary(Uri uri) => uri.isScheme('dart');
 
   @override
   bool enableNative(Uri uri) =>
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index 8dc187d..e5e91cc 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -42,7 +42,7 @@
 
   Module(this.importUri, this.fileUri)
       : name = libraryUriToJsIdentifier(importUri),
-        path = importUri.scheme == 'package'
+        path = importUri.isScheme('package')
             ? 'packages/${importUri.path}'
             : importUri.path;
 
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 901ca21..1c5d392 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -568,7 +568,7 @@
   void visitLibrary(Library node) {
     _staticTypeContext.enterLibrary(node);
     if (librariesFromDill.contains(node) ||
-        node.importUri.scheme == 'package' &&
+        node.importUri.isScheme('package') &&
             node.importUri.pathSegments[0] == 'meta') {
       return;
     }
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 379c5ac..aa49e7b 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -93,9 +93,9 @@
   if (!enabled!) {
     allowedExperimentalFlags ??= defaultAllowedExperimentalFlags;
     Set<ExperimentalFlag>? allowedFlags;
-    if (canonicalUri.scheme == 'dart') {
+    if (canonicalUri.isScheme('dart')) {
       allowedFlags = allowedExperimentalFlags.forSdkLibrary(canonicalUri.path);
-    } else if (canonicalUri.scheme == 'package') {
+    } else if (canonicalUri.isScheme('package')) {
       int index = canonicalUri.path.indexOf('/');
       String packageName;
       if (index >= 0) {
@@ -123,9 +123,9 @@
   allowedExperimentalFlags ??= defaultAllowedExperimentalFlags;
 
   Set<ExperimentalFlag>? allowedFlags;
-  if (canonicalUri.scheme == 'dart') {
+  if (canonicalUri.isScheme('dart')) {
     allowedFlags = allowedExperimentalFlags.forSdkLibrary(canonicalUri.path);
-  } else if (canonicalUri.scheme == 'package') {
+  } else if (canonicalUri.isScheme('package')) {
     int index = canonicalUri.path.indexOf('/');
     String packageName;
     if (index >= 0) {
@@ -187,9 +187,9 @@
 
   Set<ExperimentalFlag>? allowedFlags;
   bool enabledByAllowed = false;
-  if (canonicalUri.scheme == 'dart') {
+  if (canonicalUri.isScheme('dart')) {
     allowedFlags = allowedExperimentalFlags.forSdkLibrary(canonicalUri.path);
-  } else if (canonicalUri.scheme == 'package') {
+  } else if (canonicalUri.isScheme('package')) {
     int index = canonicalUri.path.indexOf('/');
     String packageName;
     if (index >= 0) {
diff --git a/pkg/front_end/lib/src/api_prototype/language_version.dart b/pkg/front_end/lib/src/api_prototype/language_version.dart
index 566c816..94dcb51 100644
--- a/pkg/front_end/lib/src/api_prototype/language_version.dart
+++ b/pkg/front_end/lib/src/api_prototype/language_version.dart
@@ -57,7 +57,7 @@
     UriTranslator uriTranslator = await context.options.getUriTranslator();
     Uri? fileUri;
     Package? package;
-    if (uri.scheme == "package") {
+    if (uri.isScheme("package")) {
       fileUri = uriTranslator.translate(uri);
       package = uriTranslator.getPackage(uri);
     } else {
@@ -65,8 +65,8 @@
       package = uriTranslator.packages.packageOf(uri);
     }
     Uri packageUri = uri;
-    if (packageUri.scheme != 'dart' &&
-        packageUri.scheme != 'package' &&
+    if (!packageUri.isScheme('dart') &&
+        !packageUri.isScheme('package') &&
         package != null &&
         // ignore: unnecessary_null_comparison
         package.name != null) {
diff --git a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
index e7fd2c5..d15af72 100644
--- a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
@@ -23,12 +23,12 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'file') {
+    if (uri.isScheme('file')) {
       return new _IoFileSystemEntity(uri);
-    } else if (uri.scheme == '') {
+    } else if (!uri.hasScheme) {
       // TODO(askesc): Empty schemes should have been handled elsewhere.
       return new _IoFileSystemEntity(Uri.base.resolveUri(uri));
-    } else if (uri.scheme == 'data') {
+    } else if (uri.isScheme('data')) {
       return new DataFileSystemEntity(Uri.base.resolveUri(uri));
     } else {
       throw new FileSystemException(
@@ -125,7 +125,7 @@
   final Uri uri;
 
   DataFileSystemEntity(this.uri)
-      : assert(uri.scheme == 'data'),
+      : assert(uri.isScheme('data')),
         assert(uri.data != null);
 
   @override
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index ea79f68..a91d6cb 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -563,7 +563,7 @@
     }
 
     // When compiling the SDK the input files are normally `dart:` URIs.
-    if (inputs.every((uri) => uri.scheme == 'dart')) {
+    if (inputs.every((uri) => uri.isScheme('dart'))) {
       return _packages = PackageConfig.empty;
     }
 
@@ -577,7 +577,7 @@
 
     Uri input = inputs.first;
 
-    if (input.scheme == 'package') {
+    if (input.isScheme('package')) {
       report(
           messageCantInferPackagesFromPackageUri.withLocation(
               input, -1, noLength),
diff --git a/pkg/front_end/lib/src/compute_platform_binaries_location.dart b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
index c849e08..e53340f 100644
--- a/pkg/front_end/lib/src/compute_platform_binaries_location.dart
+++ b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
@@ -95,7 +95,7 @@
 /// Translates an SDK URI ("org-dartlang-sdk:///...") to a file URI.
 Uri translateSdk(Uri uri) {
   if (CompilerContext.isActive) {
-    if (uri.scheme == "org-dartlang-sdk") {
+    if (uri.isScheme("org-dartlang-sdk")) {
       String path = uri.path;
       if (path.startsWith("/sdk/")) {
         CompilerContext context = CompilerContext.current;
@@ -148,7 +148,7 @@
 }
 
 bool isExistingFile(Uri uri) {
-  if (uri.scheme == "file") {
+  if (uri.isScheme("file")) {
     return new File.fromUri(uri).existsSync();
   } else {
     return false;
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 05653ef..758b070 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -326,7 +326,7 @@
     }
     if (name == "FutureOr") {
       LibraryBuilder parentLibrary = parent as LibraryBuilder;
-      if (parentLibrary.importUri.scheme == "dart" &&
+      if (parentLibrary.importUri.isScheme("dart") &&
           parentLibrary.importUri.path == "async") {
         assert(arguments != null && arguments.length == 1);
         return new FutureOrType(arguments!.single, nullability);
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 5960574..9d86de3 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -86,7 +86,7 @@
   }
 
   static void recordDependency(Uri uri) {
-    if (uri.scheme != "file" && uri.scheme != "http") {
+    if (!uri.isScheme("file") && !uri.isScheme("http")) {
       throw new ArgumentError("Expected a file or http URI, but got: '$uri'.");
     }
     CompilerContext? context = Zone.current[compilerContextKey];
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 9524f5b..b53d488 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -120,7 +120,7 @@
       assert(libraryBuilder != null, "No library found for $uri.");
       _builders[uri] = libraryBuilder!;
       assert(libraryBuilder.loader == this);
-      if (uri.scheme == "dart") {
+      if (uri.isScheme("dart")) {
         if (uri.path == "core") {
           _coreLibrary = libraryBuilder;
         }
@@ -352,7 +352,7 @@
   void registerLibraryBuilder(DillLibraryBuilder libraryBuilder) {
     Uri importUri = libraryBuilder.importUri;
     libraryBuilder.loader = this;
-    if (importUri.scheme == "dart" && importUri.path == "core") {
+    if (importUri.isScheme("dart") && importUri.path == "core") {
       _coreLibrary = libraryBuilder;
     }
     _builders[importUri] = libraryBuilder;
diff --git a/pkg/front_end/lib/src/fasta/hybrid_file_system.dart b/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
index d56e24f..55f8381 100644
--- a/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
+++ b/pkg/front_end/lib/src/fasta/hybrid_file_system.dart
@@ -37,7 +37,7 @@
   Future<FileSystemEntity> get delegate async {
     if (_delegate != null) return _delegate!;
     FileSystemEntity entity = _fs.memory.entityForUri(uri);
-    if (((uri.scheme != 'file' && uri.scheme != 'data') &&
+    if (((!uri.isScheme('file') && !uri.isScheme('data')) &&
             _fs.physical is StandardFileSystem) ||
         await entity.exists()) {
       _delegate = entity;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 5e0c376..3e10ccd 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1272,7 +1272,7 @@
       _platformBuilders = <LibraryBuilder>[];
       for (DillLibraryBuilder builder
           in dillLoadedData.loader.libraryBuilders) {
-        if (builder.importUri.scheme == "dart") {
+        if (builder.importUri.isScheme("dart")) {
           _platformBuilders!.add(builder);
         } else {
           _userBuilders![builder.importUri] = builder;
@@ -1425,7 +1425,7 @@
         _platformBuilders = <LibraryBuilder>[];
         for (DillLibraryBuilder builder
             in _dillLoadedData!.loader.libraryBuilders) {
-          if (builder.importUri.scheme == "dart") {
+          if (builder.importUri.isScheme("dart")) {
             _platformBuilders!.add(builder);
           } else {
             _userBuilders![builder.importUri] = builder;
@@ -1492,7 +1492,7 @@
           partUriToLibraryImportUri[partUri] = library.importUri;
         }
       }
-      if (library.importUri.scheme == "dart") {
+      if (library.importUri.isScheme("dart")) {
         result.add(library);
         inputLibrariesFiltered?.add(library);
       } else {
@@ -1501,7 +1501,7 @@
       }
     }
     for (LibraryBuilder libraryBuilder in reusedLibraries) {
-      if (libraryBuilder.importUri.scheme == "dart" &&
+      if (libraryBuilder.importUri.isScheme("dart") &&
           !libraryBuilder.isSynthetic) {
         continue;
       }
@@ -1550,7 +1550,7 @@
     List<Library> removedLibraries = <Library>[];
     bool removedDillBuilders = false;
     for (Uri uri in potentiallyReferencedLibraries.keys) {
-      if (uri.scheme == "package") continue;
+      if (uri.isScheme("package")) continue;
       LibraryBuilder? builder =
           currentKernelTarget.loader.deregisterLibraryBuilder(uri);
       if (builder != null) {
@@ -1913,7 +1913,7 @@
       if (importUri != fileUri && invalidatedUris.contains(fileUri)) {
         return true;
       }
-      if (_hasToCheckPackageUris && importUri.scheme == "package") {
+      if (_hasToCheckPackageUris && importUri.isScheme("package")) {
         // Get package name, check if the base URI has changed for the package,
         // if it has, translate the URI again,
         // otherwise the URI cannot have changed.
@@ -1935,7 +1935,7 @@
     }
 
     void addBuilderAndInvalidateUris(Uri uri, LibraryBuilder libraryBuilder) {
-      if (uri.scheme == "dart" && !libraryBuilder.isSynthetic) {
+      if (uri.isScheme("dart") && !libraryBuilder.isSynthetic) {
         if (seenUris.add(libraryBuilder.importUri)) {
           reusedLibraries.add(libraryBuilder);
         }
@@ -2355,7 +2355,7 @@
     bool foundDartCore = false;
     for (int i = 0; i < component.libraries.length; i++) {
       Library library = component.libraries[i];
-      if (library.importUri.scheme == "dart" &&
+      if (library.importUri.isScheme("dart") &&
           library.importUri.path == "core") {
         foundDartCore = true;
         break;
@@ -2501,7 +2501,7 @@
         // (e.g. the package still exists and hasn't been updated).
         // Also verify NNBD settings.
         for (Library lib in data.component!.libraries) {
-          if (lib.importUri.scheme == "package" &&
+          if (lib.importUri.isScheme("package") &&
               uriTranslator.translate(lib.importUri, false) != lib.fileUri) {
             // Package has been removed or updated.
             // This library should be thrown away.
@@ -2649,7 +2649,7 @@
 extension on UriTranslator {
   Uri? getPartFileUri(Uri parentFileUri, LibraryPart part) {
     Uri? fileUri = getPartUri(parentFileUri, part);
-    if (fileUri.scheme == "package") {
+    if (fileUri.isScheme("package")) {
       // Part was specified via package URI and the resolve above thus
       // did not go as expected. Translate the package URI to get the
       // actual file URI.
diff --git a/pkg/front_end/lib/src/fasta/incremental_serializer.dart b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
index 7289a11..bebdcd9 100644
--- a/pkg/front_end/lib/src/fasta/incremental_serializer.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_serializer.dart
@@ -43,7 +43,7 @@
         Uri uri = lib.importUri;
         // Uris need to be unique.
         if (!uris.add(lib.fileUri)) return false;
-        if (uri.scheme == "package") {
+        if (uri.isScheme("package")) {
           String thisPackageName = uri.pathSegments.first;
           if (packageName == null) {
             packageName = thisPackageName;
@@ -117,7 +117,7 @@
     List<Library> nonPackageLibraries = <Library>[];
     for (Library lib in component.libraries) {
       Uri uri = lib.importUri;
-      if (uri.scheme == "package") {
+      if (uri.isScheme("package")) {
         packageLibraries.add(lib);
       } else {
         nonPackageLibraries.add(lib);
@@ -179,7 +179,7 @@
     for (Library lib in component.libraries) {
       for (LibraryDependency dependency in lib.dependencies) {
         if (!got.contains(dependency.targetLibrary)) {
-          if (dependency.targetLibrary.importUri.scheme == "dart") {
+          if (dependency.targetLibrary.importUri.isScheme("dart")) {
             continue;
           }
           return false;
@@ -241,7 +241,7 @@
     for (Library lib in libraries) {
       for (LibraryDependency dep in lib.dependencies) {
         Library dependencyLibrary = dep.importedLibraryReference.asLibrary;
-        if (dependencyLibrary.importUri.scheme != "package") continue;
+        if (!dependencyLibrary.importUri.isScheme("package")) continue;
         Uri dependencyLibraryUri =
             dep.importedLibraryReference.asLibrary.fileUri;
         SerializationGroup? depGroup = uriToGroup[dependencyLibraryUri];
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 89836a7..e04f3aa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -355,7 +355,7 @@
         stringExpectedAfterNative = libraryBuilder
             .loader.target.backendTarget.nativeExtensionExpectsString,
         ignoreMainInGetMainClosure =
-            libraryBuilder.importUri.scheme == 'dart' &&
+            libraryBuilder.importUri.isScheme('dart') &&
                 (libraryBuilder.importUri.path == "_builtin" ||
                     libraryBuilder.importUri.path == "ui"),
         needsImplicitSuperInitializer =
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 7d665b8..9aca3e3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -965,7 +965,7 @@
   Map<String, String> _computeSupportedLibraries() {
     Map<String, String> map = {};
     for (Library library in component.libraries) {
-      if (library.importUri.scheme == 'dart') {
+      if (library.importUri.isScheme('dart')) {
         map[library.importUri.path] =
             DartLibrarySupport.getDartLibrarySupportValue(
                 library.importUri.path,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 6ac5ea0..aa458b7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1667,7 +1667,7 @@
   }
 
   void readPatchFiles(SourceLibraryBuilder library) {
-    assert(library.importUri.scheme == "dart");
+    assert(library.importUri.isScheme("dart"));
     List<Uri>? patches = uriTranslator.getDartPatches(library.importUri.path);
     if (patches != null) {
       SourceLibraryBuilder? first;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 79badb9..ec26f2a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -66,7 +66,7 @@
   static bool isObject(DartType type) {
     if (type is InterfaceType && type.classNode.name == 'Object') {
       Uri importUri = type.classNode.enclosingLibrary.importUri;
-      return importUri.scheme == 'dart' && importUri.path == 'core';
+      return importUri.isScheme('dart') && importUri.path == 'core';
     }
     return false;
   }
@@ -504,7 +504,7 @@
   }
 
   String get originMessage {
-    if (importUri.scheme == 'dart' && importUri.path == 'core') {
+    if (importUri.isScheme('dart') && importUri.path == 'core') {
       if (node is Class && denylistedCoreClasses.contains(name)) {
         // Denylisted core class. Only print if ambiguous.
         List<LabeledNode> entityForName = typeLabeler.nameMap[name]!;
@@ -521,7 +521,7 @@
         return "";
       }
     }
-    Message message = (importUri == fileUri || importUri.scheme == 'dart')
+    Message message = (importUri == fileUri || importUri.isScheme('dart'))
         ? templateTypeOrigin.withArguments(toString(), importUri)
         : templateTypeOriginWithFileUri.withArguments(
             toString(), importUri, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index ae560e2..3c825f6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -241,7 +241,7 @@
     // 'dart:test' is used in the unit tests and isn't an actual part of the
     // platform.
     if (skipPlatform &&
-        node.importUri.scheme == 'dart' &&
+        node.importUri.isScheme('dart') &&
         node.importUri.path != 'test') {
       return;
     }
@@ -304,7 +304,7 @@
 
   bool isObjectClass(Class c) {
     return c.name == "Object" &&
-        c.enclosingLibrary.importUri.scheme == "dart" &&
+        c.enclosingLibrary.importUri.isScheme("dart") &&
         c.enclosingLibrary.importUri.path == "core";
   }
 
@@ -435,7 +435,7 @@
   }
 
   void _checkConstructorTearOff(Node node, Member tearOffTarget) {
-    if (tearOffTarget.enclosingLibrary.importUri.scheme == 'dart') {
+    if (tearOffTarget.enclosingLibrary.importUri.isScheme('dart')) {
       // Platform libraries are not compilation with test flags and might
       // contain tear-offs not expected when testing lowerings.
       return;
@@ -540,7 +540,7 @@
     // 'dart:test' is used in the unit tests and isn't an actual part of the
     // platform.
     if (skipPlatform &&
-        node.importUri.scheme == 'dart' &&
+        node.importUri.isScheme('dart') &&
         node.importUri.path != "test") {
       return;
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 4d8edad..7b40a7c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -714,7 +714,7 @@
                 this.charOffset,
                 noLength);
           } else if (interface.cls.name == "FutureOr" &&
-              interface.cls.enclosingLibrary.importUri.scheme == "dart" &&
+              interface.cls.enclosingLibrary.importUri.isScheme("dart") &&
               interface.cls.enclosingLibrary.importUri.path == "async") {
             addProblem(messageImplementsFutureOr, this.charOffset, noLength);
           } else if (implemented.contains(interface)) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index dee61c4..a5a4d57 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -289,12 +289,12 @@
             new Scope.top()) {
     assert(
         _packageUri == null ||
-            importUri.scheme != 'package' ||
+            !importUri.isScheme('package') ||
             importUri.path.startsWith(_packageUri!.path),
         "Foreign package uri '$_packageUri' set on library with import uri "
         "'${importUri}'.");
     assert(
-        importUri.scheme != 'dart' || _packageUri == null,
+        !importUri.isScheme('dart') || _packageUri == null,
         "Package uri '$_packageUri' set on dart: library with import uri "
         "'${importUri}'.");
   }
@@ -638,7 +638,7 @@
     return previous;
   }
 
-  bool uriIsValid(Uri uri) => uri.scheme != MALFORMED_URI_SCHEME;
+  bool uriIsValid(Uri uri) => !uri.isScheme(MALFORMED_URI_SCHEME);
 
   Uri resolve(Uri baseUri, String? uri, int uriOffset, {isPart: false}) {
     if (uri == null) {
@@ -657,7 +657,7 @@
       return new Uri(
           scheme: MALFORMED_URI_SCHEME, query: Uri.encodeQueryComponent(uri));
     }
-    if (isPart && baseUri.scheme == "dart") {
+    if (isPart && baseUri.isScheme("dart")) {
       // Resolve using special rules for dart: URIs
       return resolveRelativeUri(baseUri, parsedUri);
     } else {
@@ -1668,7 +1668,7 @@
     if (className != "Function") {
       return;
     }
-    if (decType == "class" && importUri.scheme == "dart") {
+    if (decType == "class" && importUri.isScheme("dart")) {
       // Allow declaration of class Function in the sdk.
       return;
     }
@@ -3158,9 +3158,9 @@
         preferred = declaration;
       } else if (other is LoadLibraryBuilder) {
         preferred = other;
-      } else if (otherUri.scheme == "dart" && uri.scheme != "dart") {
+      } else if (otherUri.isScheme("dart") && !uri.isScheme("dart")) {
         preferred = declaration;
-      } else if (uri.scheme == "dart" && otherUri.scheme != "dart") {
+      } else if (uri.isScheme("dart") && !otherUri.isScheme("dart")) {
         preferred = other;
       }
     }
@@ -3901,7 +3901,7 @@
   }
 
   void exportMemberFromPatch(String name, Builder member) {
-    if (importUri.scheme != "dart" || !importUri.path.startsWith("_")) {
+    if (!importUri.isScheme("dart") || !importUri.path.startsWith("_")) {
       addProblem(templatePatchInjectionFailed.withArguments(name, importUri),
           member.charOffset, noLength, member.fileUri);
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 90ad778..766d631 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -265,7 +265,7 @@
 
   void registerLibraryBuilder(LibraryBuilder libraryBuilder) {
     Uri uri = libraryBuilder.importUri;
-    if (uri.scheme == "dart" && uri.path == "core") {
+    if (uri.isScheme("dart") && uri.path == "core") {
       _coreLibrary = libraryBuilder;
     }
     _builders[uri] = libraryBuilder;
@@ -326,7 +326,7 @@
         referencesFrom: referencesFrom,
         referenceIsPartOwner: referenceIsPartOwner,
         isUnsupported: origin?.library.isUnsupported ??
-            importUri.scheme == 'dart' &&
+            importUri.isScheme('dart') &&
                 !target.uriTranslator.isLibrarySupported(importUri.path));
   }
 
@@ -359,9 +359,9 @@
       Library? referencesFrom,
       bool? referenceIsPartOwner) {
     if (fileUri != null &&
-        (fileUri.scheme == "dart" ||
-            fileUri.scheme == "package" ||
-            fileUri.scheme == "dart-ext")) {
+        (fileUri.isScheme("dart") ||
+            fileUri.isScheme("package") ||
+            fileUri.isScheme("dart-ext"))) {
       fileUri = null;
     }
     package_config.Package? packageForLanguageVersion;
@@ -373,7 +373,7 @@
               new Uri(
                   scheme: untranslatableUriScheme,
                   path: Uri.encodeComponent("$uri"));
-          if (uri.scheme == "package") {
+          if (uri.isScheme("package")) {
             packageForLanguageVersion = target.uriTranslator.getPackage(uri);
           } else {
             packageForLanguageVersion =
@@ -396,8 +396,8 @@
     Message? packageLanguageVersionProblem;
     if (packageForLanguageVersion != null) {
       Uri importUri = origin?.importUri ?? uri;
-      if (importUri.scheme != 'dart' &&
-          importUri.scheme != 'package' &&
+      if (!importUri.isScheme('dart') &&
+          !importUri.isScheme('package') &&
           // ignore: unnecessary_null_comparison
           packageForLanguageVersion.name != null) {
         packageUri =
@@ -455,7 +455,7 @@
     if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
       libraryBuilder.mayImplementRestrictedTypes = true;
     }
-    if (uri.scheme == "dart") {
+    if (uri.isScheme("dart")) {
       target.readPatchFiles(libraryBuilder);
     }
     _unparsedLibraries.addLast(libraryBuilder);
@@ -516,7 +516,7 @@
   }
 
   void _checkForDartCore(Uri uri, LibraryBuilder libraryBuilder) {
-    if (uri.scheme == "dart") {
+    if (uri.isScheme("dart")) {
       if (uri.path == "core") {
         _coreLibrary = libraryBuilder;
       } else if (uri.path == "typed_data") {
@@ -595,7 +595,7 @@
   }
 
   bool _hasLibraryAccess({required Uri imported, required Uri? importer}) {
-    if (imported.scheme == "dart" && imported.path.startsWith("_")) {
+    if (imported.isScheme("dart") && imported.path.startsWith("_")) {
       if (importer == null) {
         return false;
       } else {
@@ -810,7 +810,7 @@
 
     if (bytes == null) {
       // Error recovery.
-      if (fileUri.scheme == untranslatableUriScheme) {
+      if (fileUri.isScheme(untranslatableUriScheme)) {
         Message message =
             templateUntranslatableUri.withArguments(library.importUri);
         library.addProblemAtAccessors(message);
@@ -820,7 +820,7 @@
             templateInternalProblemUriMissingScheme.withArguments(fileUri),
             -1,
             library.importUri);
-      } else if (fileUri.scheme == SourceLibraryBuilder.MALFORMED_URI_SCHEME) {
+      } else if (fileUri.isScheme(SourceLibraryBuilder.MALFORMED_URI_SCHEME)) {
         library.addProblemAtAccessors(messageExpectedUri);
         bytes = synthesizeSourceForMissingFile(library.importUri, null);
       }
@@ -1027,7 +1027,7 @@
           continue;
         }
       }
-      if (libraryBuilder.importUri.scheme == 'package') {
+      if (libraryBuilder.importUri.isScheme('package')) {
         (libraryByPackage[null] ??= []).add(libraryBuilder);
       } else {
         if (emitNonPackageErrors) {
@@ -1965,7 +1965,7 @@
     for (LibraryBuilder libraryBuilder in libraryBuilders) {
       if (!libraryBuilder.isPatch &&
           (libraryBuilder.loader == this ||
-              libraryBuilder.importUri.scheme == "dart" ||
+              libraryBuilder.importUri.isScheme("dart") ||
               libraryBuilder == this.first)) {
         if (libraries.add(libraryBuilder.library)) {
           workList.add(libraryBuilder.library);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index bdf3e38..5f7680b 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -1064,7 +1064,7 @@
               onType,
               onTypeInstantiateToBounds,
               target,
-              isPlatform: extensionBuilder.library.importUri.scheme == 'dart');
+              isPlatform: extensionBuilder.library.importUri.isScheme('dart'));
           if (noneMoreSpecific.isNotEmpty) {
             bool isMostSpecific = true;
             for (ExtensionAccessCandidate other in noneMoreSpecific) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
index 8927d85..d1023db 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -70,7 +70,7 @@
     assert(topType == const DynamicType() ||
         topType is InterfaceType &&
             topType.nullability == Nullability.nullable &&
-            topType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+            topType.classNode.enclosingLibrary.importUri.isScheme("dart") &&
             topType.classNode.enclosingLibrary.importUri.path == "core" &&
             topType.classNode.name == "Object");
     assert(
diff --git a/pkg/front_end/lib/src/fasta/uri_translator.dart b/pkg/front_end/lib/src/fasta/uri_translator.dart
index dac8845..e4df37b 100644
--- a/pkg/front_end/lib/src/fasta/uri_translator.dart
+++ b/pkg/front_end/lib/src/fasta/uri_translator.dart
@@ -22,7 +22,7 @@
       dartLibraries.libraryInfoFor(libraryName)?.patches;
 
   bool isPlatformImplementation(Uri uri) {
-    if (uri.scheme != "dart") return false;
+    if (!uri.isScheme("dart")) return false;
     String path = uri.path;
     return dartLibraries.libraryInfoFor(path) == null || path.startsWith("_");
   }
@@ -31,8 +31,8 @@
   // callback, so we can provide an error location when one is available. For
   // example, if the error occurs in an `import`.
   Uri? translate(Uri uri, [bool reportMessage = true]) {
-    if (uri.scheme == "dart") return _translateDartUri(uri);
-    if (uri.scheme == "package") {
+    if (uri.isScheme("dart")) return _translateDartUri(uri);
+    if (uri.isScheme("package")) {
       return _translatePackageUri(uri, reportMessage);
     }
     return null;
@@ -42,7 +42,7 @@
   Package? getPackage(Uri uri) {
     // ignore: unnecessary_null_comparison
     if (packages == null) return null;
-    if (uri.scheme != "package") return null;
+    if (!uri.isScheme("package")) return null;
     int firstSlash = uri.path.indexOf('/');
     if (firstSlash == -1) return null;
     String packageName = uri.path.substring(0, firstSlash);
diff --git a/pkg/front_end/lib/src/fasta/util/outline_extractor.dart b/pkg/front_end/lib/src/fasta/util/outline_extractor.dart
index ff65e37..d1f5d0a 100644
--- a/pkg/front_end/lib/src/fasta/util/outline_extractor.dart
+++ b/pkg/front_end/lib/src/fasta/util/outline_extractor.dart
@@ -116,7 +116,7 @@
   Future<TopLevel> preprocessUri(Uri importUri, {Uri? partOf}) async {
     if (verbosityLevel >= 20) log("$importUri =>");
     Uri fileUri = importUri;
-    if (importUri.scheme == "package") {
+    if (importUri.isScheme("package")) {
       fileUri = uriTranslator.translate(importUri)!;
     }
     if (verbosityLevel >= 20) log("$fileUri");
@@ -202,14 +202,14 @@
       worklist.add(new _TopLevelAndAstNode(entrypointish, child));
 
       if (child is Part) {
-        if (child.uri.scheme != "dart") {
+        if (!child.uri.isScheme("dart")) {
           TopLevel partTopLevel = parsed[child.uri] ??
               await preprocessUri(child.uri, partOf: entrypointish.uri);
           await _premarkTopLevel(worklist, closed, partTopLevel);
         }
       } else if (child is Export) {
         for (Uri importedUri in child.uris) {
-          if (importedUri.scheme != "dart") {
+          if (!importedUri.isScheme("dart")) {
             TopLevel exportTopLevel =
                 parsed[importedUri] ?? await preprocessUri(importedUri);
             await _premarkTopLevel(worklist, closed, exportTopLevel);
@@ -230,7 +230,7 @@
         if (child is Import) {
           child.marked = Coloring.Marked;
           for (Uri importedUri in child.uris) {
-            if (importedUri.scheme != "dart") {
+            if (!importedUri.isScheme("dart")) {
               TopLevel importedTopLevel =
                   parsed[importedUri] ?? await preprocessUri(importedUri);
               imported.add(importedTopLevel);
@@ -238,7 +238,7 @@
           }
         } else if (child is PartOf) {
           child.marked = Coloring.Marked;
-          if (child.partOfUri.scheme != "dart") {
+          if (!child.partOfUri.isScheme("dart")) {
             TopLevel part = parsed[child.partOfUri]!;
             List<TopLevel> importsFromPart =
                 await _preprocessImportsAsNeeded(imports, part);
@@ -392,7 +392,7 @@
           if (child is Part) {
             child.marked = Coloring.Marked;
             // do stuff to part.
-            if (child.uri.scheme != "dart") {
+            if (!child.uri.isScheme("dart")) {
               other = parsed[child.uri] ??
                   await preprocessUri(child.uri, partOf: topLevel.uri);
             }
@@ -400,7 +400,7 @@
             child.marked = Coloring.Marked;
             // do stuff to export.
             for (Uri importedUri in child.uris) {
-              if (importedUri.scheme != "dart") {
+              if (!importedUri.isScheme("dart")) {
                 other = parsed[importedUri] ?? await preprocessUri(importedUri);
               }
             }
@@ -468,7 +468,7 @@
           }
           if (child is Import) {
             for (Uri importedUri in child.uris) {
-              if (importedUri.scheme != "dart") {
+              if (!importedUri.isScheme("dart")) {
                 imported.add(importedUri);
               }
             }
@@ -478,7 +478,7 @@
       if (sb.isNotEmpty) count++;
       Uri uri = entry.key;
       Uri fileUri = uri;
-      if (uri.scheme == "package") {
+      if (uri.isScheme("package")) {
         fileUri = uriTranslator.translate(uri)!;
       }
       result[fileUri] = sb.toString();
@@ -489,7 +489,7 @@
       // uri imports a file we haven't read. Check if it exists and include it
       // as an empty file if it does.
       Uri fileUri = uri;
-      if (uri.scheme == "package") {
+      if (uri.isScheme("package")) {
         fileUri = uriTranslator.translate(uri)!;
       }
       if (await fileSystem.entityForUri(fileUri).exists()) {
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 0ee8f98..6c2620b 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -140,7 +140,7 @@
 ''';
 
 bool isDartCoreLibrary(Library lib) => isDartCore(lib.importUri);
-bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core';
+bool isDartCore(Uri uri) => uri.isScheme('dart') && uri.path == 'core';
 
 /// Find a library in [component] whose Uri ends with the given [suffix]
 Library findLibrary(Component component, String suffix) {
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index b9a1a86..48fe099 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -451,8 +451,8 @@
 
   bool excludeLibrary(Library library) {
     return forUserLibrariesOnly &&
-        (library.importUri.scheme == 'dart' ||
-            library.importUri.scheme == 'package');
+        (library.importUri.isScheme('dart') ||
+            library.importUri.isScheme('package'));
   }
 
   await dataComputer.inspectTestResultData(testResultData);
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index 0c27d6f..ea54f97 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -55,7 +55,7 @@
               .where((Member m) =>
                   !m.isAbstract &&
                   m.name.text == "toString" &&
-                  m.enclosingLibrary.importUri.scheme != "dart")
+                  !m.enclosingLibrary.importUri.isScheme("dart"))
               .toList();
           if (toStringList.length > 1) throw "What?";
           if (toStringList.length == 1) {
@@ -157,7 +157,7 @@
             .where((Member m) =>
                 !m.isAbstract &&
                 m.name.text == "toString" &&
-                m.enclosingLibrary.importUri.scheme != "dart")
+                !m.enclosingLibrary.importUri.isScheme("dart"))
             .toList();
         Member toString = toStringList.single;
         if (toString.fileUri != uri) continue;
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
index 254ff7d..3607cc2 100644
--- a/pkg/front_end/test/comments_on_certain_arguments_tool.dart
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -88,7 +88,7 @@
   component = incrementalCompilerResult.component;
 
   for (Library library in component.libraries) {
-    if (library.importUri.scheme == "dart") continue;
+    if (library.importUri.isScheme("dart")) continue;
     // This isn't perfect because of parts, but (for now) it'll do.
     for (Uri uri in libUris) {
       if (library.fileUri.toString().startsWith(uri.toString())) {
diff --git a/pkg/front_end/test/compile_benchmark.dart b/pkg/front_end/test/compile_benchmark.dart
index c244da3..e6cea76 100644
--- a/pkg/front_end/test/compile_benchmark.dart
+++ b/pkg/front_end/test/compile_benchmark.dart
@@ -363,7 +363,7 @@
 
   @override
   void visitLibrary(Library node) {
-    if (node.importUri.scheme == "package" &&
+    if (node.importUri.isScheme("package") &&
         node.importUri.pathSegments.first == "front_end") {
       super.visitLibrary(node);
     }
@@ -395,7 +395,7 @@
 
   @override
   void visitLibrary(Library node) {
-    if (node.importUri.scheme == "package" &&
+    if (node.importUri.isScheme("package") &&
         node.importUri.pathSegments.first == "front_end") {
       super.visitLibrary(node);
     }
diff --git a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
index 437c010..e6ffb2b 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer_impl.dart
@@ -778,9 +778,9 @@
   void _rewriteImportsExportsToUriInternal(
       Token uriToken, Uri oldUri, List<_Replacement> replacements, Uri newUri) {
     Uri tokenUri = _getUri(uriToken, oldUri, resolvePackage: false);
-    if (tokenUri.scheme == "package" || tokenUri.scheme == "dart") return;
+    if (tokenUri.isScheme("package") || tokenUri.isScheme("dart")) return;
     Uri asPackageUri = _getImportUri(tokenUri);
-    if (asPackageUri.scheme == "package") {
+    if (asPackageUri.isScheme("package")) {
       // Just replace with this package uri.
       replacements.add(new _Replacement(
         uriToken.offset - 1,
@@ -803,7 +803,7 @@
     String uriString = uriToken.lexeme;
     uriString = uriString.substring(1, uriString.length - 1);
     Uri uriTokenUri = uri.resolve(uriString);
-    if (resolvePackage && uriTokenUri.scheme == "package") {
+    if (resolvePackage && uriTokenUri.isScheme("package")) {
       Package package = _latestCrashingIncrementalCompiler!
           .getPackageForPackageName(uriTokenUri.pathSegments.first)!;
       uriTokenUri = package.packageUriRoot
diff --git a/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
index a5f766e..b2076ac 100644
--- a/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
+++ b/pkg/front_end/test/enable_non_nullable/enable_non_nullable_test.dart
@@ -116,7 +116,7 @@
   Expect.isFalse(
       hadDiagnostic, "Compilation had diagnostics (errors, warnings)!");
   for (Library library in result.component!.libraries) {
-    if (library.importUri.scheme != 'dart') {
+    if (!library.importUri.isScheme('dart')) {
       bool usesLegacy =
           await uriUsesLegacyLanguageVersion(library.fileUri, options);
       VersionAndPackageUri versionAndPackageUri =
@@ -143,7 +143,7 @@
           "Expected library ${library.importUri} with version "
           "${library.languageVersion} to be opted in.");
       Expect.isTrue(
-          versionAndPackageUri.packageUri.scheme != 'package' ||
+          !versionAndPackageUri.packageUri.isScheme('package') ||
               !versionAndPackageUri.packageUri.path
                   .startsWith('allowed_package') ||
               library.languageVersion < versionOptsInAllowed ||
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 02231dd..2b3db8d 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -598,7 +598,7 @@
         }
         for (String argument in parsedOptions.arguments) {
           Uri uri = description.uri.resolve(argument);
-          if (uri.scheme != 'package') {
+          if (!uri.isScheme('package')) {
             File f = new File.fromUri(uri);
             if (!f.existsSync()) {
               throw new UnsupportedError("No file found: $f ($argument)");
@@ -1328,11 +1328,11 @@
     Map<Uri, LibraryBuilder> builders = {};
     for (LibraryBuilder builder
         in incrementalCompiler.kernelTargetForTesting!.loader.libraryBuilders) {
-      if (builder.importUri.scheme == "dart" && !builder.isSynthetic) continue;
+      if (builder.importUri.isScheme("dart") && !builder.isSynthetic) continue;
       builders[builder.fileUri] = builder;
       for (LibraryPart part in builder.library.parts) {
         Uri thisPartUri = builder.importUri.resolve(part.partUri);
-        if (thisPartUri.scheme == "package") {
+        if (thisPartUri.isScheme("package")) {
           thisPartUri = incrementalCompiler
               .kernelTargetForTesting!.uriTranslator
               .translate(thisPartUri)!;
@@ -1761,8 +1761,8 @@
       component.libraries.map((Library library) => library.importUri).toSet();
   Set<Uri> userLibraries = component.libraries
       .where((Library library) =>
-          library.importUri.scheme != 'dart' &&
-          library.importUri.scheme != 'package' &&
+          !library.importUri.isScheme('dart') &&
+          !library.importUri.isScheme('package') &&
           !excludedLibraries.contains(library))
       .map((Library library) => library.importUri)
       .toSet();
@@ -2171,7 +2171,7 @@
       ComponentResult result, FastaContext context) {
     Component component = result.component;
     Uri uri =
-        component.uriToSource.keys.firstWhere((uri) => uri.scheme == "file");
+        component.uriToSource.keys.firstWhere((uri) => uri.isScheme("file"));
     KernelTarget target = result.sourceTarget;
     ClassHierarchyBuilder hierarchy = target.loader.hierarchyBuilder;
     StringBuffer sb = new StringBuffer();
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 f037ae5..6bb5a32 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
@@ -48,13 +48,13 @@
         "the core library and the test library.");
     Library firstLibrary = env.component.libraries.first;
     Library secondLibrary = env.component.libraries.last;
-    if (firstLibrary.importUri.scheme == "dart" &&
+    if (firstLibrary.importUri.isScheme("dart") &&
         firstLibrary.importUri.path == "core") {
       _coreLibrary = firstLibrary;
       _testLibrary = secondLibrary;
     } else {
       assert(
-          secondLibrary.importUri.scheme == "dart" &&
+          secondLibrary.importUri.isScheme("dart") &&
               secondLibrary.importUri.path == "core",
           "One of the libraries is expected to be 'dart:core'.");
       _coreLibrary == secondLibrary;
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 e42fc10..f0aa16d 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
@@ -48,13 +48,13 @@
         "the core library and the test library.");
     Library firstLibrary = env.component.libraries.first;
     Library secondLibrary = env.component.libraries.last;
-    if (firstLibrary.importUri.scheme == "dart" &&
+    if (firstLibrary.importUri.isScheme("dart") &&
         firstLibrary.importUri.path == "core") {
       _coreLibrary = firstLibrary;
       _testLibrary = secondLibrary;
     } else {
       assert(
-          secondLibrary.importUri.scheme == "dart" &&
+          secondLibrary.importUri.isScheme("dart") &&
               secondLibrary.importUri.path == "core",
           "One of the libraries is expected to be 'dart:core'.");
       _coreLibrary == secondLibrary;
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index 182d44b..df6740e 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -46,13 +46,13 @@
         "the core library and the test library.");
     Library firstLibrary = typeParserEnvironment.component.libraries.first;
     Library secondLibrary = typeParserEnvironment.component.libraries.last;
-    if (firstLibrary.importUri.scheme == "dart" &&
+    if (firstLibrary.importUri.isScheme("dart") &&
         firstLibrary.importUri.path == "core") {
       _coreLibrary = firstLibrary;
       _testLibrary = secondLibrary;
     } else {
       assert(
-          secondLibrary.importUri.scheme == "dart" &&
+          secondLibrary.importUri.isScheme("dart") &&
               secondLibrary.importUri.path == "core",
           "One of the libraries is expected to be 'dart:core'.");
       _coreLibrary == secondLibrary;
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 526e061..cd094fe 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -46,13 +46,13 @@
         "the core library and the test library.");
     Library firstLibrary = typeParserEnvironment.component.libraries.first;
     Library secondLibrary = typeParserEnvironment.component.libraries.last;
-    if (firstLibrary.importUri.scheme == "dart" &&
+    if (firstLibrary.importUri.isScheme("dart") &&
         firstLibrary.importUri.path == "core") {
       _coreLibrary = firstLibrary;
       _testLibrary = secondLibrary;
     } else {
       assert(
-          secondLibrary.importUri.scheme == "dart" &&
+          secondLibrary.importUri.isScheme("dart") &&
               secondLibrary.importUri.path == "core",
           "One of the libraries is expected to be 'dart:core'.");
       _coreLibrary == secondLibrary;
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 a47c4ee..ecb3664 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
@@ -28,13 +28,13 @@
         "the core library and the test library.");
     Library firstLibrary = env.component.libraries.first;
     Library secondLibrary = env.component.libraries.last;
-    if (firstLibrary.importUri.scheme == "dart" &&
+    if (firstLibrary.importUri.isScheme("dart") &&
         firstLibrary.importUri.path == "core") {
       coreLibrary = firstLibrary;
       testLibrary = secondLibrary;
     } else {
       assert(
-          secondLibrary.importUri.scheme == "dart" &&
+          secondLibrary.importUri.isScheme("dart") &&
               secondLibrary.importUri.path == "core",
           "One of the libraries is expected to be 'dart:core'.");
       coreLibrary = secondLibrary;
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index 86ddcb0..07cf63b 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -330,7 +330,7 @@
   // TODO(sigmund): the incremental generator should always filter these
   // libraries instead.
   new BinaryPrinter(sink,
-          libraryFilter: (library) => library.importUri.scheme != 'dart')
+          libraryFilter: (library) => !library.importUri.isScheme('dart'))
       .writeComponentFile(component);
   await sink.close();
 }
diff --git a/pkg/front_end/test/incremental_dart2js_tester.dart b/pkg/front_end/test/incremental_dart2js_tester.dart
index 59add48..c3d7600 100644
--- a/pkg/front_end/test/incremental_dart2js_tester.dart
+++ b/pkg/front_end/test/incremental_dart2js_tester.dart
@@ -220,7 +220,7 @@
     uris = c.uriToSource.values
         .map((s) => s.importUri)
         .whereType<Uri>()
-        .where((u) => u.scheme != "dart")
+        .where((u) => !u.isScheme("dart"))
         .toSet()
         .toList();
 
diff --git a/pkg/front_end/test/incremental_flutter_tester.dart b/pkg/front_end/test/incremental_flutter_tester.dart
index 4a745aa..7527279 100644
--- a/pkg/front_end/test/incremental_flutter_tester.dart
+++ b/pkg/front_end/test/incremental_flutter_tester.dart
@@ -120,7 +120,7 @@
   List<Uri> uris = c.uriToSource.values
       .map((s) => s.importUri)
       .whereType<Uri>()
-      .where((u) => u.scheme != "dart")
+      .where((u) => !u.isScheme("dart"))
       .toSet()
       .toList();
 
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 20ed53a..e72f3f2 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -789,7 +789,7 @@
           // null is always there, so allow it implicitly.
           // Dart scheme uris too.
           // ignore: unnecessary_null_comparison
-          if (uri == null || uri.scheme == "org-dartlang-sdk") continue;
+          if (uri == null || uri.isScheme("org-dartlang-sdk")) continue;
           if (!allowed.contains(uri)) {
             return new Result<TestData>(
                 data,
@@ -1226,7 +1226,7 @@
   Component component = compilerResult.component;
   StringBuffer sb = new StringBuffer();
   for (Library library in component.libraries) {
-    if (library.importUri.scheme == "dart") continue;
+    if (library.importUri.isScheme("dart")) continue;
     sb.writeln("Library ${library.importUri}");
     for (Class c in library.classes) {
       sb.writeln("  - Class ${c.name}");
@@ -1533,7 +1533,7 @@
   while (workList.isNotEmpty) {
     Library library = workList.removeLast();
     for (LibraryDependency dependency in library.dependencies) {
-      if (dependency.targetLibrary.importUri.scheme == "dart") continue;
+      if (dependency.targetLibrary.importUri.isScheme("dart")) continue;
       if (libraries.add(dependency.targetLibrary)) {
         workList.add(dependency.targetLibrary);
         allLibraries.add(dependency.targetLibrary);
@@ -1607,7 +1607,7 @@
   if (world["neededDillLibraries"] != null) {
     List<Uri> actualContent = <Uri>[];
     for (Library lib in neededDillLibraries!) {
-      if (lib.importUri.scheme == "dart") continue;
+      if (lib.importUri.isScheme("dart")) continue;
       actualContent.add(lib.importUri);
     }
 
@@ -1652,7 +1652,7 @@
   Component c = new Component();
   List<Uri> dartUris = <Uri>[];
   for (Library lib in component.libraries) {
-    if (lib.importUri.scheme == "dart") {
+    if (lib.importUri.isScheme("dart")) {
       dartUris.add(lib.importUri);
     } else {
       c.libraries.add(lib);
@@ -1686,7 +1686,7 @@
 int countNonSyntheticPlatformLibraries(Component c) {
   int result = 0;
   for (Library lib in c.libraries) {
-    if (!lib.isSynthetic && lib.importUri.scheme == "dart") result++;
+    if (!lib.isSynthetic && lib.importUri.isScheme("dart")) result++;
   }
   return result;
 }
diff --git a/pkg/front_end/test/incremental_utils.dart b/pkg/front_end/test/incremental_utils.dart
index 8a46cd6..49c7663 100644
--- a/pkg/front_end/test/incremental_utils.dart
+++ b/pkg/front_end/test/incremental_utils.dart
@@ -77,7 +77,7 @@
     for (Uri uri in uris) {
       // ignore: unnecessary_null_comparison
       if (uri == null) continue;
-      if (uri.scheme != "org-dartlang-test") continue;
+      if (!uri.isScheme("org-dartlang-test")) continue;
       // The file system doesn't have the sources for any modules.
       // For now assume that that is always what's going on.
       if (!await fileSystem.entityForUri(uri).exists()) continue;
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart
index 5e88669..dabc98e 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -85,7 +85,7 @@
     CompilerOptions options = testResultData.customData;
     Component component = testResultData.compilerResult.component!;
     for (Library library in component.libraries) {
-      if (library.importUri.scheme == "dart") continue;
+      if (library.importUri.isScheme("dart")) continue;
       Version lvFile =
           (await lv.languageVersionForUri(library.fileUri, options)).version;
       Version lvImportUri =
diff --git a/pkg/front_end/test/lint_suite.dart b/pkg/front_end/test/lint_suite.dart
index d61759d..16bc592 100644
--- a/pkg/front_end/test/lint_suite.dart
+++ b/pkg/front_end/test/lint_suite.dart
@@ -315,7 +315,7 @@
       importUri = importUri.substring(1, importUri.length - 1);
     }
     Uri resolved = uri.resolve(importUri);
-    if (resolved.scheme == "package") {
+    if (resolved.isScheme("package")) {
       if (description.cache.packages != null) {
         resolved = description.cache.packages!.resolve(resolved)!;
       }
@@ -345,7 +345,7 @@
       exportUri = exportUri.substring(1, exportUri.length - 1);
     }
     Uri resolved = uri.resolve(exportUri);
-    if (resolved.scheme == "package") {
+    if (resolved.isScheme("package")) {
       if (description.cache.packages != null) {
         resolved = description.cache.packages!.resolve(resolved)!;
       }
diff --git a/pkg/front_end/test/macros/macro_test.dart b/pkg/front_end/test/macros/macro_test.dart
index c4db330..ce03989 100644
--- a/pkg/front_end/test/macros/macro_test.dart
+++ b/pkg/front_end/test/macros/macro_test.dart
@@ -98,9 +98,9 @@
 }
 
 String importUriToString(Uri importUri) {
-  if (importUri.scheme == 'package') {
+  if (importUri.isScheme('package')) {
     return importUri.toString();
-  } else if (importUri.scheme == 'dart') {
+  } else if (importUri.isScheme('dart')) {
     return importUri.toString();
   } else {
     return importUri.pathSegments.last;
diff --git a/pkg/front_end/test/mock_file_system.dart b/pkg/front_end/test/mock_file_system.dart
index 60e45be..fa674e1 100644
--- a/pkg/front_end/test/mock_file_system.dart
+++ b/pkg/front_end/test/mock_file_system.dart
@@ -11,7 +11,8 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (scheme != null && uri.scheme != scheme) throw "unsupported";
+    final scheme = this.scheme;
+    if (scheme != null && !uri.isScheme(scheme)) throw "unsupported";
     return new MockFileSystemEntity(uri, this);
   }
 }
diff --git a/pkg/front_end/test/static_types/analysis_helper.dart b/pkg/front_end/test/static_types/analysis_helper.dart
index 6564bd1..ab60ab7 100644
--- a/pkg/front_end/test/static_types/analysis_helper.dart
+++ b/pkg/front_end/test/static_types/analysis_helper.dart
@@ -312,7 +312,7 @@
     String uriString = relativizeUri(uri)!;
     Map<String, List<FormattedMessage>> actualMap = _actualMessages.putIfAbsent(
         uriString, () => <String, List<FormattedMessage>>{});
-    if (uri.scheme == 'org-dartlang-sdk') {
+    if (uri.isScheme('org-dartlang-sdk')) {
       location = new Location(Uri.base.resolve(uri.path.substring(1)),
           location.line, location.column);
     }
diff --git a/pkg/front_end/test/static_types/static_type_test.dart b/pkg/front_end/test/static_types/static_type_test.dart
index 80a339d..41bc89c 100644
--- a/pkg/front_end/test/static_types/static_type_test.dart
+++ b/pkg/front_end/test/static_types/static_type_test.dart
@@ -136,7 +136,7 @@
     if (object is ConstructorInvocation) {
       Class cls = object.target.enclosingClass;
       return cls.name == 'ReachabilityError' &&
-          cls.enclosingLibrary.importUri.scheme == 'dart' &&
+          cls.enclosingLibrary.importUri.isScheme('dart') &&
           cls.enclosingLibrary.importUri.path == '_internal';
     }
     return false;
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 2c96443..d526f13 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -384,8 +384,8 @@
       TextSerializationVerifier verifier =
           new TextSerializationVerifier(root: component.root);
       for (Library library in component.libraries) {
-        if (library.importUri.scheme != "dart" &&
-            library.importUri.scheme != "package") {
+        if (!library.importUri.isScheme("dart") &&
+            !library.importUri.isScheme("package")) {
           verifier.verify(library);
         }
       }
@@ -401,7 +401,7 @@
 
       if (writeRoundTripStatus) {
         Uri uri = component.uriToSource.keys
-            .firstWhere((uri) => uri.scheme == "file");
+            .firstWhere((uri) => uri.isScheme("file"));
         String filename = "${uri.toFilePath()}${suffix}";
         uri = new File(filename).uri;
         StringBuffer buffer = new StringBuffer();
diff --git a/pkg/front_end/test/vm_service_coverage.dart b/pkg/front_end/test/vm_service_coverage.dart
index 2112bd0..cb6736c 100644
--- a/pkg/front_end/test/vm_service_coverage.dart
+++ b/pkg/front_end/test/vm_service_coverage.dart
@@ -112,10 +112,10 @@
   }
 
   bool includeCoverageFor(Uri uri) {
-    if (uri.scheme == "dart") {
+    if (uri.isScheme("dart")) {
       return false;
     }
-    if (uri.scheme == "package") {
+    if (uri.isScheme("package")) {
       return uri.pathSegments.first == "front_end" ||
           uri.pathSegments.first == "_fe_analyzer_shared" ||
           uri.pathSegments.first == "kernel";
diff --git a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
index 3128758..70b7dad 100644
--- a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
+++ b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
@@ -23,7 +23,7 @@
 
   @override
   bool includeCoverageFor(Uri uri) {
-    if (uri.scheme != "package") return false;
+    if (!uri.isScheme("package")) return false;
     if (uri.path.startsWith("front_end/src/fasta/kernel/constant_")) {
       return true;
     }
diff --git a/pkg/front_end/tool/_fasta/bench_maker.dart b/pkg/front_end/tool/_fasta/bench_maker.dart
index 4e95837..58c45c97 100644
--- a/pkg/front_end/tool/_fasta/bench_maker.dart
+++ b/pkg/front_end/tool/_fasta/bench_maker.dart
@@ -270,7 +270,7 @@
     }
     Uri clsImportUri = cls.enclosingLibrary.importUri;
     bool isNull = cls.name == "Null" &&
-        clsImportUri.scheme == "dart" &&
+        clsImportUri.isScheme("dart") &&
         clsImportUri.path == "core";
     if (!isNull) {
       writeNullability(node.nullability, sb);
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 822fced..adc8826 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -421,7 +421,7 @@
         userCode.setMainMethodAndMode(
             outline.mainMethodName, true, outline.mode);
         for (Library library in outline.libraries) {
-          if (library.importUri.scheme != "dart") {
+          if (!library.importUri.isScheme("dart")) {
             userCode.libraries.add(library);
           }
         }
@@ -465,13 +465,13 @@
       userCode.setMainMethodAndMode(
           component.mainMethodName, true, component.mode);
       for (Library library in component.libraries) {
-        if (library.importUri.scheme != "dart") {
+        if (!library.importUri.isScheme("dart")) {
           userCode.libraries.add(library);
         }
       }
       component = userCode;
     }
-    if (uri.scheme == "file") {
+    if (uri.isScheme("file")) {
       benchmarker?.enterPhase(BenchmarkPhases.writeComponent);
       await writeComponentToFile(component, uri);
       ticker.logMs("Wrote component to ${uri.toFilePath()}");
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index afb0e81..0a1186d 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -168,7 +168,7 @@
       print('edit $edit');
     }
     var uri = edit.uri;
-    if (uri.scheme == 'package') uri = uriTranslator.translate(uri)!;
+    if (uri.isScheme('package')) uri = uriTranslator.translate(uri)!;
     generator.invalidate(uri);
     OverlayFileSystemEntity entity =
         fs.entityForUri(uri) as OverlayFileSystemEntity;
@@ -212,9 +212,9 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'org-dartlang-overlay') {
+    if (uri.isScheme('org-dartlang-overlay')) {
       return new OverlayFileSystemEntity(uri, this);
-    } else if (uri.scheme == 'file') {
+    } else if (uri.isScheme('file')) {
       // The IKG compiler reads ".packages" which might contain absolute file
       // URIs (which it will then try to use on the FS).  We therefore replace
       // them with overlay-fs URIs as usual.
diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
index 3fd7f05..e9aac60 100644
--- a/pkg/frontend_server/lib/compute_kernel.dart
+++ b/pkg/frontend_server/lib/compute_kernel.dart
@@ -296,7 +296,7 @@
     if (recordUsedInputs) {
       Set<Uri> usedOutlines = {};
       for (Library lib in incrementalCompilerResult.neededDillLibraries) {
-        if (lib.importUri.scheme == "dart") continue;
+        if (lib.importUri.isScheme("dart")) continue;
         Uri uri = state.libraryToInputDill[lib.importUri];
         if (uri == null) {
           throw new StateError("Library ${lib.importUri} was recorded as used, "
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index d68a4ec..bcfd799 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -630,7 +630,7 @@
     Set<Uri> uris = Set<Uri>();
     for (Uri uri in compiledSources) {
       // Skip empty or corelib dependencies.
-      if (uri == null || uri.scheme == 'org-dartlang-sdk') continue;
+      if (uri == null || uri.isScheme('org-dartlang-sdk')) continue;
       uris.add(uri);
     }
     for (Uri uri in uris) {
@@ -986,7 +986,7 @@
 
     for (var lib in deltaProgram.libraries) {
       Uri uri = lib.importUri;
-      if (uri.scheme == "package") {
+      if (uri.isScheme("package")) {
         packageLibraries.add(lib);
       } else {
         libraries.add(lib);
@@ -1040,7 +1040,7 @@
       for (Library lib in libraries) {
         for (LibraryDependency dep in lib.dependencies) {
           Library dependencyLibrary = dep.importedLibraryReference.asLibrary;
-          if (dependencyLibrary.importUri.scheme != "package") continue;
+          if (!dependencyLibrary.importUri.isScheme("package")) continue;
           Uri dependencyLibraryUri =
               dep.importedLibraryReference.asLibrary.fileUri;
           if (libraryUris.contains(dependencyLibraryUri)) continue;
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index a989fb1..d39ee75 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.dart
@@ -110,7 +110,7 @@
 
     for (Library library in _originalComponent.libraries) {
       if (loadedLibraries.contains(library) ||
-          library.importUri.scheme == 'dart') {
+          library.importUri.isScheme('dart')) {
         continue;
       }
       final Uri moduleUri =
@@ -156,7 +156,7 @@
 
       final moduleUrl = urlForComponentUri(moduleUri);
       String sourceMapBase;
-      if (moduleUri.scheme == 'package') {
+      if (moduleUri.isScheme('package')) {
         // Source locations come through as absolute file uris. In order to
         // make relative paths in the source map we get the absolute uri for
         // the module and make them relative to that.
@@ -218,7 +218,7 @@
   }
 }
 
-String urlForComponentUri(Uri componentUri) => componentUri.scheme == 'package'
+String urlForComponentUri(Uri componentUri) => componentUri.isScheme('package')
     ? '/packages/${componentUri.path}'
     : componentUri.path;
 
diff --git a/pkg/frontend_server/lib/src/strong_components.dart b/pkg/frontend_server/lib/src/strong_components.dart
index a631c30..4c010a8 100644
--- a/pkg/frontend_server/lib/src/strong_components.dart
+++ b/pkg/frontend_server/lib/src/strong_components.dart
@@ -103,7 +103,7 @@
     return <Library>[
       for (LibraryDependency dependency in vertex.dependencies)
         if (!loadedLibraries.contains(dependency.targetLibrary) &&
-            dependency.targetLibrary.importUri.scheme != 'dart')
+            !dependency.targetLibrary.importUri.isScheme('dart'))
           dependency.targetLibrary
     ];
   }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a2fce2f..cbf0d44 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -10071,7 +10071,7 @@
           type.className.node != null &&
           type.classNode.name == 'Object') {
         Uri uri = type.classNode.enclosingLibrary.importUri;
-        return uri.scheme == 'dart' &&
+        return uri.isScheme('dart') &&
             uri.path == 'core' &&
             type.nullability == Nullability.nonNullable;
       }
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
index fd5f59f..eea2adb 100644
--- a/pkg/kernel/lib/import_table.dart
+++ b/pkg/kernel/lib/import_table.dart
@@ -89,7 +89,7 @@
     // whether the scheme is 'file:', but instead we check that is not 'dart:'
     // or 'package:'.
     bool isFileOrCustomScheme(Uri uri) =>
-        uri.scheme != '' && uri.scheme != 'package' && uri.scheme != 'dart';
+        uri.hasScheme && !uri.isScheme('package') && !uri.isScheme('dart');
     bool isTargetSchemeFileOrCustom = isFileOrCustomScheme(targetUri);
     bool isReferenceSchemeFileOrCustom = isFileOrCustomScheme(referenceUri);
     if (isTargetSchemeFileOrCustom && isReferenceSchemeFileOrCustom) {
diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart
index 5f231b4..da1d0e7 100644
--- a/pkg/kernel/lib/library_index.dart
+++ b/pkg/kernel/lib/library_index.dart
@@ -44,7 +44,7 @@
   /// Indexes `dart:` libraries.
   LibraryIndex.coreLibraries(Component component) {
     for (Library library in component.libraries) {
-      if (library.importUri.scheme == 'dart') {
+      if (library.importUri.isScheme('dart')) {
         _libraries['${library.importUri}'] = new _ClassTable(library);
       }
     }
diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart
index 3d28d32..fc81e9c 100644
--- a/pkg/kernel/lib/src/printer.dart
+++ b/pkg/kernel/lib/src/printer.dart
@@ -266,7 +266,7 @@
               type.className.node != null &&
               type.classNode.name == 'Object') {
             Uri uri = type.classNode.enclosingLibrary.importUri;
-            return uri.scheme == 'dart' &&
+            return uri.isScheme('dart') &&
                 uri.path == 'core' &&
                 (type.nullability == Nullability.legacy ||
                     type.nullability == Nullability.nullable);
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 678cc33..330d683 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -368,8 +368,8 @@
   /// By default only `dart:*` libraries are allowed. May be overridden for
   /// testing purposes.
   bool allowPlatformPrivateLibraryAccess(Uri importer, Uri imported) =>
-      importer.scheme == "dart" ||
-      (importer.scheme == "package" &&
+      importer.isScheme("dart") ||
+      (importer.isScheme("package") &&
           importer.path.startsWith("dart_internal/"));
 
   /// Whether the `native` language extension is supported within [library].
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 6beaa67..1f9fab5 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -289,7 +289,7 @@
       Nullability nullability =
           interpretParsedNullability(node.parsedNullability);
       if (declaration.name == 'Null' &&
-          declaration.enclosingLibrary.importUri.scheme == 'dart' &&
+          declaration.enclosingLibrary.importUri.isScheme('dart') &&
           declaration.enclosingLibrary.importUri.path == 'core') {
         if (node.parsedNullability != ParsedNullability.omitted) {
           throw "Null type must be written without explicit nullability";
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index fee2089..5af5475 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -77,7 +77,7 @@
     Library enclosingLibrary = class_.enclosingLibrary;
 
     if (!librariesToBeTransformed.contains(enclosingLibrary) &&
-        enclosingLibrary.importUri.scheme == "dart") {
+        enclosingLibrary.importUri.isScheme("dart")) {
       // If we're not asked to transform the platform libraries then we expect
       // that they will be already transformed.
       return;
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 318b720..cb6601e 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -298,7 +298,7 @@
     for (Library library in libraries) {
       final Uri importUri = library.importUri;
       // ignore: unnecessary_null_comparison
-      if (importUri != null && importUri.scheme == 'package') {
+      if (importUri != null && importUri.isScheme('package')) {
         if (importUri.path == 'flutter/src/widgets/framework.dart') {
           for (Class class_ in library.classes) {
             if (class_.name == 'Widget') {
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index e575a00..e19ef36 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -27,7 +27,7 @@
 
   void checkComponent(Component component) {
     for (Library library in component.libraries) {
-      if (ignoreSdk && library.importUri.scheme == 'dart') continue;
+      if (ignoreSdk && library.importUri.isScheme('dart')) continue;
       for (Class class_ in library.classes) {
         hierarchy.forEachOverridePair(class_,
             (Member ownMember, Member superMember, bool isSetter) {
@@ -39,7 +39,7 @@
         new TypeCheckingVisitor(this, environment, hierarchy);
     for (Library library in component.libraries) {
       currentLibrary = library;
-      if (ignoreSdk && library.importUri.scheme == 'dart') continue;
+      if (ignoreSdk && library.importUri.isScheme('dart')) continue;
       for (Class class_ in library.classes) {
         currentThisType = coreTypes.thisInterfaceType(
             class_, class_.enclosingLibrary.nonNullable);
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 5ab9d26..4b03467 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -3167,7 +3167,7 @@
     var calleeUri = callee?.library?.source.uri;
     var isQuiverCheckNull = callee?.name == 'checkNotNull' &&
         calleeUri != null &&
-        calleeUri.scheme == 'package' &&
+        calleeUri.isScheme('package') &&
         calleeUri.path.startsWith('quiver/');
 
     if (isQuiverCheckNull && node.argumentList.arguments.isNotEmpty) {
@@ -3215,7 +3215,7 @@
         if (enclosingInvocation.name == 'setUp') {
           var uri = enclosingInvocation.staticElement!.library?.source.uri;
           if (uri != null &&
-              uri.scheme == 'package' &&
+              uri.isScheme('package') &&
               uri.path.startsWith('test_core/')) {
             return true;
           }
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 0f1e8f4..9f7c831 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -969,7 +969,7 @@
 
   /// Determines whether the given [uri] comes from the Angular package.
   bool _isAngularUri(Uri uri) {
-    if (uri.scheme != 'package') return false;
+    if (!uri.isScheme('package')) return false;
     var packageName = uri.pathSegments[0];
     if (packageName == 'angular') return true;
     if (packageName == 'third_party.dart_src.angular.angular') {
diff --git a/pkg/test_runner/lib/src/utils.dart b/pkg/test_runner/lib/src/utils.dart
index fc27e18..03d3f84 100644
--- a/pkg/test_runner/lib/src/utils.dart
+++ b/pkg/test_runner/lib/src/utils.dart
@@ -306,7 +306,7 @@
   /// In case [uri] is not a local file, this method will always return
   /// the current date.
   DateTime getLastModified(Uri uri) {
-    if (uri.scheme == "file") {
+    if (uri.isScheme("file")) {
       if (_cache.containsKey(uri.path)) {
         return _cache[uri.path];
       }
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 8e3f752..a843655 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -552,7 +552,7 @@
       // If it does not, try to load from dart_platform_kernel or from file.
       bool foundDartCore = false;
       for (Library library in component.libraries) {
-        if (library.importUri.scheme == "dart" &&
+        if (library.importUri.isScheme("dart") &&
             library.importUri.path == "core" &&
             !library.isSynthetic) {
           foundDartCore = true;
@@ -665,12 +665,12 @@
 
   if (component != null) {
     for (var lib in component.libraries) {
-      if (lib.importUri.scheme == "dart") continue;
+      if (lib.importUri.isScheme("dart")) continue;
 
       dependencies.add(lib.fileUri);
       for (var part in lib.parts) {
         final fileUri = lib.fileUri.resolve(part.partUri);
-        if (fileUri.scheme != "" && fileUri.scheme != "file") {
+        if (fileUri.hasScheme && !fileUri.isScheme("file")) {
           // E.g. part 'package:foo/foo.dart';
           // Maybe the front end should resolve this?
           continue;
@@ -827,7 +827,7 @@
     if (packageConfigWithDefault != null) {
       packagesUri = Uri.parse(packageConfigWithDefault);
     }
-    if (packagesUri != null && packagesUri.scheme == '') {
+    if (packagesUri != null && !packagesUri.hasScheme) {
       // Script does not have a scheme, assume that it is a path,
       // resolve it against the working directory.
       packagesUri = Uri.directory(workingDirectory!).resolveUri(packagesUri);
diff --git a/pkg/vm/bin/protobuf_aware_treeshaker.dart b/pkg/vm/bin/protobuf_aware_treeshaker.dart
index 3af79b6..bb746af 100644
--- a/pkg/vm/bin/protobuf_aware_treeshaker.dart
+++ b/pkg/vm/bin/protobuf_aware_treeshaker.dart
@@ -185,5 +185,5 @@
 }
 
 bool isCoreLibrary(Library library) {
-  return library.importUri.scheme == 'dart';
+  return library.importUri.isScheme('dart');
 }
diff --git a/pkg/vm/lib/http_filesystem.dart b/pkg/vm/lib/http_filesystem.dart
index 18ee3e1..5966494 100644
--- a/pkg/vm/lib/http_filesystem.dart
+++ b/pkg/vm/lib/http_filesystem.dart
@@ -14,7 +14,7 @@
 
   @override
   FileSystemEntity entityForUri(Uri uri) {
-    if (uri.scheme == 'http' || uri.scheme == 'https') {
+    if (uri.isScheme('http') || uri.isScheme('https')) {
       return new HttpFileSystemEntity(this, uri);
     } else {
       return original.entityForUri(uri);
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index fdf6e5c..6f109b3 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -95,7 +95,7 @@
       uriToSource.addAll(delta.uriToSource);
       for (Library library in delta.libraries) {
         bool isPlatform =
-            library.importUri.scheme == "dart" && !library.isSynthetic;
+            library.importUri.isScheme("dart") && !library.isSynthetic;
         if (!includePlatform && isPlatform) continue;
         combined[library.importUri] = library;
       }
diff --git a/pkg/vm/lib/transformations/deferred_loading.dart b/pkg/vm/lib/transformations/deferred_loading.dart
index b7dd321..91beb11 100644
--- a/pkg/vm/lib/transformations/deferred_loading.dart
+++ b/pkg/vm/lib/transformations/deferred_loading.dart
@@ -54,7 +54,7 @@
   // Fake imports from root library to every core library so they end up in
   // the same loading unit attributed to the user's root library.
   for (final vertex in map.values) {
-    if (vertex.library.importUri.scheme == "dart") {
+    if (vertex.library.importUri.isScheme("dart")) {
       root.successors.add(vertex);
       vertex.isLoadingRoot = false;
     }
diff --git a/pkg/vm/lib/transformations/ffi/common.dart b/pkg/vm/lib/transformations/ffi/common.dart
index 5c20ebf..22f2195 100644
--- a/pkg/vm/lib/transformations/ffi/common.dart
+++ b/pkg/vm/lib/transformations/ffi/common.dart
@@ -992,7 +992,7 @@
   for (Library lib in component.libraries) {
     // Skip real dart: libraries. dart:core imports dart:ffi, but that doesn't
     // mean we have to transform anything.
-    if (lib.importUri.scheme == "dart" && !lib.isSynthetic) continue;
+    if (lib.importUri.isScheme("dart") && !lib.isSynthetic) continue;
     allLibs.add(lib);
   }
   return allLibs;
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 8b96b9a..450233d 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -208,7 +208,7 @@
     for (var annotation in member.annotations) {
       ParsedPragma? pragma = _matcher.parsePragma(annotation);
       if (pragma is ParsedDisableUnboxedParameters) {
-        if (member.enclosingLibrary.importUri.scheme != "dart") {
+        if (!member.enclosingLibrary.importUri.isScheme("dart")) {
           throw "ERROR: Cannot use @pragma(vm:disable-unboxed-parameters) outside core libraries.";
         }
         return true;
@@ -236,7 +236,7 @@
         // We can only use the 'vm:exact-result-type' pragma on methods in core
         // libraries for safety reasons. See 'result_type_pragma.md', detail 1.2
         // for explanation.
-        if (member.enclosingLibrary.importUri.scheme != "dart") {
+        if (!member.enclosingLibrary.importUri.isScheme("dart")) {
           throw "ERROR: Cannot use $kVmExactResultTypePragmaName "
               "outside core libraries.";
         }
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index d44ca15..ef627ac 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -1707,7 +1707,7 @@
 
   void defaultMemberReference(Member node) {
     Library lib = node.enclosingLibrary;
-    if (lib.importUri.scheme != "dart") {
+    if (!lib.importUri.isScheme("dart")) {
       librariesReferenced.add(lib);
     }
     return super.defaultMemberReference(node);
diff --git a/pkg/vm/test/transformations/deferred_loading_test.dart b/pkg/vm/test/transformations/deferred_loading_test.dart
index f36b610..5b7cce8 100644
--- a/pkg/vm/test/transformations/deferred_loading_test.dart
+++ b/pkg/vm/test/transformations/deferred_loading_test.dart
@@ -28,7 +28,7 @@
 
   // Remove core libraries so the expected output isn't enormous and broken by
   // core libraries changes.
-  component.libraries.removeWhere((lib) => lib.importUri.scheme == "dart");
+  component.libraries.removeWhere((lib) => lib.importUri.isScheme("dart"));
 
   String actual = kernelComponentToString(component);
 
diff --git a/pkg/vm/test/unlinked_ast_to_text_test.dart b/pkg/vm/test/unlinked_ast_to_text_test.dart
index 8b03a2c..ecf80d0 100644
--- a/pkg/vm/test/unlinked_ast_to_text_test.dart
+++ b/pkg/vm/test/unlinked_ast_to_text_test.dart
@@ -45,7 +45,7 @@
     final component = loadComponentFromBinary(dillFile);
     final IOSink sink = new File(unlinkedDillFile).openWrite();
     final printer = new BinaryPrinter(sink,
-        libraryFilter: (lib) => lib.importUri.scheme != 'dart');
+        libraryFilter: (lib) => !lib.importUri.isScheme('dart'));
     printer.writeComponentFile(component);
     await sink.close();
 
@@ -54,7 +54,7 @@
     final unlinkedComponent = loadComponentFromBinary(unlinkedDillFile);
     final coreLibraryCount = unlinkedComponent.libraries
         .where(
-            (lib) => lib.importUri.scheme == 'dart' && lib.members.isNotEmpty)
+            (lib) => lib.importUri.isScheme('dart') && lib.members.isNotEmpty)
         .length;
     Expect.equals(0, coreLibraryCount);
 
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
index 950e802..7777d7a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -22,6 +22,6 @@
   synthetic constructor •() → self::Class
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3399,getterSelectorId:3400]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3398,getterSelectorId:3399]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
     return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
index 5ccaefa..5a63ba0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -51,6 +51,6 @@
   synthetic constructor •() → self::ConstClass
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3403,getterSelectorId:3404]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3402,getterSelectorId:3403]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
     return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
 }
diff --git a/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/BreakpointConsumer.java b/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/BreakpointConsumer.java
index 7fdc2dd..b9b746f 100644
--- a/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/BreakpointConsumer.java
+++ b/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/BreakpointConsumer.java
@@ -13,7 +13,7 @@
  */
 package org.dartlang.vm.service.consumer;
 
-// This is a generated file.
+// This file is generated by the script: pkg/vm_service/tool/generate.dart in dart-lang/sdk.
 
 import org.dartlang.vm.service.element.Breakpoint;
 
diff --git a/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/CpuSamplesConsumer.java b/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/CpuSamplesConsumer.java
index 6bc5e2f..8b45e8a 100644
--- a/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/CpuSamplesConsumer.java
+++ b/pkg/vm_service/java/src/org/dartlang/vm/service/consumer/CpuSamplesConsumer.java
@@ -13,7 +13,7 @@
  */
 package org.dartlang.vm.service.consumer;
 
-// This is a generated file.
+// This file is generated by the script: pkg/vm_service/tool/generate.dart in dart-lang/sdk.
 
 import org.dartlang.vm.service.element.CpuSamples;
 
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart
index a5001d0..4100c68 100644
--- a/pkg/vm_service/test/common/test_helper.dart
+++ b/pkg/vm_service/test/common/test_helper.dart
@@ -32,7 +32,7 @@
 }
 
 Uri _getTestUri(String script) {
-  if (io.Platform.script.scheme == 'data') {
+  if (io.Platform.script.isScheme('data')) {
     // If running from pub we can assume that we're in the root of the package
     // directory.
     return Uri.parse('test/$script');
diff --git a/pkg/vm_service/test/regress_48279_test.dart b/pkg/vm_service/test/regress_48279_test.dart
new file mode 100644
index 0000000..d57b084
--- /dev/null
+++ b/pkg/vm_service/test/regress_48279_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test verifies that generic type argument ('T') can be evaluated
+// when stopped on an exception which is thrown during type check in
+// the implicit field setter.
+// Regression test for https://github.com/dart-lang/sdk/issues/48279.
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+class A<T, U, V> {
+  List<T> foo = [];
+}
+
+testeeMain() {
+  A<num, Object, Object> object = A<int, String, String>();
+  object.foo = <double>[];
+}
+
+var tests = <IsolateTest>[
+  hasStoppedWithUnhandledException,
+  (VmService? service, IsolateRef? isolateRef) async {
+    print("We stopped!");
+    final isolateId = isolateRef!.id!;
+    final stack = await service!.getStack(isolateId);
+    final topFrame = stack.frames![0];
+    expect(topFrame.function!.name, equals('foo='));
+    final result = await service.evaluateInFrame(isolateId, 0, 'T');
+    print(result);
+    expect((result as InstanceRef).name, equals("int"));
+  }
+];
+
+main(args) => runIsolateTests(
+      args,
+      tests,
+      'regress_48279_test.dart',
+      pause_on_unhandled_exceptions: true,
+      testeeConcurrent: testeeMain,
+    );
diff --git a/pkg/vm_service/tool/generate.dart b/pkg/vm_service/tool/generate.dart
index 79d74eb..e91c0f3 100644
--- a/pkg/vm_service/tool/generate.dart
+++ b/pkg/vm_service/tool/generate.dart
@@ -67,7 +67,12 @@
 Future _generateJava(String appDirPath, List<Node> nodes) async {
   var srcDirPath = normalize(join(appDirPath, '..', 'java', 'src'));
   var generator = java.JavaGenerator(srcDirPath);
-  java.api = java.Api();
+
+  final scriptPath = Platform.script.toFilePath();
+  final kSdk = '/sdk/';
+  final scriptLocation =
+      scriptPath.substring(scriptPath.indexOf(kSdk) + kSdk.length);
+  java.api = java.Api(scriptLocation);
   java.api.parse(nodes);
   java.api.generate(generator);
 
diff --git a/pkg/vm_service/tool/java/generate_java.dart b/pkg/vm_service/tool/java/generate_java.dart
index 0f61371..9f48c01 100644
--- a/pkg/vm_service/tool/java/generate_java.dart
+++ b/pkg/vm_service/tool/java/generate_java.dart
@@ -101,11 +101,14 @@
   List<Enum?> enums = [];
   List<Type?> types = [];
   Map<String, List<String>> streamIdMap = {};
+  final String scriptLocation;
 
   String? get docs => null;
 
   String get name => 'api';
 
+  Api(this.scriptLocation);
+
   void addProperty(String typeName, String propertyName, {String? javadoc}) {
     var t = types.firstWhere((t) => t!.name == typeName)!;
     for (var f in t.fields) {
@@ -148,7 +151,8 @@
       }
     }
 
-    gen.writeType('$servicePackage.VmService', (TypeWriter writer) {
+    gen.writeType('$servicePackage.VmService', scriptLocation,
+        (TypeWriter writer) {
       writer.addImport('com.google.gson.JsonArray');
       writer.addImport('com.google.gson.JsonObject');
       writer.addImport('com.google.gson.JsonPrimitive');
@@ -311,11 +315,11 @@
     if (docs != null) docs = docs.trim();
 
     if (definition.startsWith('class ')) {
-      types.add(Type(this, name, definition, docs));
+      types.add(Type(this, scriptLocation, name, definition, docs));
     } else if (name.substring(0, 1).toLowerCase() == name.substring(0, 1)) {
-      methods.add(Method(name, definition, docs));
+      methods.add(Method(name, scriptLocation, definition, docs));
     } else if (definition.startsWith('enum ')) {
-      enums.add(Enum(name, definition, docs));
+      enums.add(Enum(name, scriptLocation, definition, docs));
     } else {
       throw 'unexpected entity: ${name}, ${definition}';
     }
@@ -365,18 +369,19 @@
 
 class Enum extends Member {
   final String name;
+  final String scriptLocation;
   final String? docs;
 
   List<EnumValue> enums = [];
 
-  Enum(this.name, String definition, [this.docs]) {
+  Enum(this.name, this.scriptLocation, String definition, [this.docs]) {
     _parse(Tokenizer(definition).tokenize());
   }
 
   String get elementTypeName => '$servicePackage.element.$name';
 
   void generateEnum(JavaGenerator gen) {
-    gen.writeType(elementTypeName, (TypeWriter writer) {
+    gen.writeType(elementTypeName, scriptLocation, (TypeWriter writer) {
       writer.javadoc = convertDocLinks(docs);
       writer.isEnum = true;
       enums.sort((v1, v2) => v1.name!.compareTo(v2.name!));
@@ -496,13 +501,14 @@
 
 class Method extends Member {
   final String name;
+  final String scriptLocation;
   final String? docs;
 
   MemberType returnType = MemberType();
   bool deprecated = false;
   List<MethodArg> args = [];
 
-  Method(this.name, String definition, [this.docs]) {
+  Method(this.name, this.scriptLocation, String definition, [this.docs]) {
     _parse(Tokenizer(definition).tokenize());
   }
 
@@ -521,7 +527,7 @@
   bool get hasOptionalArgs => args.any((MethodArg arg) => arg.optional);
 
   void generateConsumerInterface(JavaGenerator gen) {
-    gen.writeType(consumerTypeName, (TypeWriter writer) {
+    gen.writeType(consumerTypeName, scriptLocation, (TypeWriter writer) {
       writer.javadoc = convertDocLinks(returnType.docs);
       writer.interfaceNames.add('$servicePackage.consumer.Consumer');
       writer.isInterface = true;
@@ -752,13 +758,15 @@
 
 class Type extends Member {
   final Api parent;
+  final String scriptLocation;
   String? rawName;
   String? name;
   String? superName;
   final String? docs;
   List<TypeField> fields = [];
 
-  Type(this.parent, String categoryName, String definition, [this.docs]) {
+  Type(this.parent, this.scriptLocation, String categoryName, String definition,
+      [this.docs]) {
     _parse(Tokenizer(definition).tokenize());
   }
 
@@ -787,7 +795,8 @@
       api.types.toList()..retainWhere((t) => t!.superName == name);
 
   void generateElement(JavaGenerator gen) {
-    gen.writeType('$servicePackage.element.$name', (TypeWriter writer) {
+    gen.writeType('$servicePackage.element.$name', scriptLocation,
+        (TypeWriter writer) {
       if (fields.any((f) => f.type.types.any((t) => t.isArray))) {
         writer.addImport('com.google.gson.JsonObject');
       }
diff --git a/pkg/vm_service/tool/java/src_gen_java.dart b/pkg/vm_service/tool/java/src_gen_java.dart
index a2e62e5..4342380 100644
--- a/pkg/vm_service/tool/java/src_gen_java.dart
+++ b/pkg/vm_service/tool/java/src_gen_java.dart
@@ -57,8 +57,8 @@
   Iterable<String> get allWrittenFiles => _generatedPaths;
 
   /// Generate a Java class/interface in the given package
-  void writeType(String typeName, WriteType write) {
-    var classWriter = TypeWriter(typeName);
+  void writeType(String typeName, scriptLocation, WriteType write) {
+    var classWriter = TypeWriter(typeName, scriptLocation);
     write(classWriter);
     var pkgDirPath = join(srcDirPath, joinAll(pkgNameFor(typeName).split('.')));
     var pkgDir = Directory(pkgDirPath);
@@ -123,10 +123,12 @@
   final StringBuffer _content = StringBuffer();
   final List<String> _fields = <String>[];
   final Map<String, String> _methods = Map<String, String>();
+  final String scriptLocation;
 
-  TypeWriter(String typeName)
+  TypeWriter(String typeName, scriptLocation)
       : this.pkgName = pkgNameFor(typeName),
-        this.className = classNameFor(typeName);
+        this.className = classNameFor(typeName),
+        this.scriptLocation = scriptLocation;
 
   String get kind {
     if (isInterface) return 'interface';
@@ -263,7 +265,8 @@
     if (fileHeader != null) buffer.write(fileHeader);
     buffer.writeln('package $pkgName;');
     buffer.writeln();
-    buffer.writeln('// This is a generated file.');
+    buffer.writeln(
+        '// This file is generated by the script: ${scriptLocation} in dart-lang/sdk.');
     buffer.writeln();
     addImport(superclassName);
     interfaceNames.forEach((t) => addImport(t));
diff --git a/runtime/observatory/bin/heap_snapshot.dart b/runtime/observatory/bin/heap_snapshot.dart
index b5aaf93..3820096 100644
--- a/runtime/observatory/bin/heap_snapshot.dart
+++ b/runtime/observatory/bin/heap_snapshot.dart
@@ -401,9 +401,9 @@
   }
 
   var uri = Uri.parse(args[0]);
-  if (uri.scheme == 'http') {
+  if (uri.isScheme('http')) {
     uri = uri.replace(scheme: 'ws');
-  } else if (uri.scheme == 'https') {
+  } else if (uri.isScheme('https')) {
     uri = uri.replace(scheme: 'wss');
   }
   if (!uri.path.endsWith('/ws')) {
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 68dc829..ca74491 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -439,7 +439,7 @@
         return l as S.Library;
       }
     }
-    if (targetUri.scheme == 'package') {
+    if (targetUri.isScheme('package')) {
       var targetUriString = "packages/${targetUri.path}";
       for (M.Library l in script.isolate!.libraries) {
         if (targetUriString == l.uri) {
@@ -482,7 +482,7 @@
   S.Script? resolvePart(String relativeUri) {
     S.Script script = _loadedScript as S.Script;
     var rootUri = Uri.parse(script.library!.uri!);
-    if (rootUri.scheme == 'dart') {
+    if (rootUri.isScheme('dart')) {
       // The relative paths from dart:* libraries to their parts are not valid.
       rootUri = Uri.parse(script.library!.uri! + '/');
     }
diff --git a/runtime/observatory_2/bin/heap_snapshot.dart b/runtime/observatory_2/bin/heap_snapshot.dart
index 495c778..11e25ea 100644
--- a/runtime/observatory_2/bin/heap_snapshot.dart
+++ b/runtime/observatory_2/bin/heap_snapshot.dart
@@ -401,9 +401,9 @@
   }
 
   var uri = Uri.parse(args[0]);
-  if (uri.scheme == 'http') {
+  if (uri.isScheme('http')) {
     uri = uri.replace(scheme: 'ws');
-  } else if (uri.scheme == 'https') {
+  } else if (uri.isScheme('https')) {
     uri = uri.replace(scheme: 'wss');
   }
   if (!uri.path.endsWith('/ws')) {
diff --git a/runtime/observatory_2/lib/src/elements/script_inset.dart b/runtime/observatory_2/lib/src/elements/script_inset.dart
index c4a0094..70d2049 100644
--- a/runtime/observatory_2/lib/src/elements/script_inset.dart
+++ b/runtime/observatory_2/lib/src/elements/script_inset.dart
@@ -436,7 +436,7 @@
         return l;
       }
     }
-    if (targetUri.scheme == 'package') {
+    if (targetUri.isScheme('package')) {
       var targetUriString = "packages/${targetUri.path}";
       for (M.Library l in script.isolate.libraries) {
         if (targetUriString == l.uri) {
@@ -479,7 +479,7 @@
   M.Script resolvePart(String relativeUri) {
     S.Script script = _loadedScript as S.Script;
     var rootUri = Uri.parse(script.library.uri);
-    if (rootUri.scheme == 'dart') {
+    if (rootUri.isScheme('dart')) {
       // The relative paths from dart:* libraries to their parts are not valid.
       rootUri = Uri.parse(script.library.uri + '/');
     }
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 9fd1243..eb4d2c9 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1839,13 +1839,14 @@
 
 Fragment FlowGraphBuilder::CheckAssignable(const AbstractType& dst_type,
                                            const String& dst_name,
-                                           AssertAssignableInstr::Kind kind) {
+                                           AssertAssignableInstr::Kind kind,
+                                           TokenPosition token_pos) {
   Fragment instructions;
   if (!dst_type.IsTopTypeForSubtyping()) {
     LocalVariable* top_of_stack = MakeTemporary();
     instructions += LoadLocal(top_of_stack);
-    instructions += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
-                                                      dst_type, dst_name, kind);
+    instructions +=
+        AssertAssignableLoadTypeArguments(token_pos, dst_type, dst_name, kind);
     instructions += Drop();
   }
   return instructions;
@@ -3679,7 +3680,8 @@
                                   setter_value->needs_type_check();
     if (needs_type_check) {
       body += CheckAssignable(setter_value->type(), setter_value->name(),
-                              AssertAssignableInstr::kParameterCheck);
+                              AssertAssignableInstr::kParameterCheck,
+                              field.token_pos());
     }
     body += BuildNullAssertions();
     if (field.is_late()) {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index cb66e59..f226a12 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -243,7 +243,8 @@
   Fragment CheckAssignable(
       const AbstractType& dst_type,
       const String& dst_name,
-      AssertAssignableInstr::Kind kind = AssertAssignableInstr::kUnknown);
+      AssertAssignableInstr::Kind kind = AssertAssignableInstr::kUnknown,
+      TokenPosition token_pos = TokenPosition::kNoSource);
 
   Fragment AssertAssignableLoadTypeArguments(
       TokenPosition position,
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 622c662..80ee3b5 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -1094,7 +1094,7 @@
       {_HttpHeaders? initialHeaders})
       : _uri = uri,
         headers = _HttpHeaders(protocolVersion,
-            defaultPortForScheme: uri.scheme == 'https'
+            defaultPortForScheme: uri.isScheme('https')
                 ? HttpClient.defaultHttpsPort
                 : HttpClient.defaultHttpPort,
             initialHeaders: initialHeaders),
@@ -2665,7 +2665,7 @@
     if (method != "CONNECT") {
       if (uri.host.isEmpty) {
         throw ArgumentError("No host specified in URI $uri");
-      } else if (uri.scheme != "http" && uri.scheme != "https") {
+      } else if (!uri.isScheme("http") && !uri.isScheme("https")) {
         throw ArgumentError("Unsupported scheme '${uri.scheme}' in URI $uri");
       }
     }
@@ -2717,7 +2717,7 @@
   }
 
   static bool _isSubdomain(Uri subdomain, Uri domain) {
-    return (subdomain.scheme == domain.scheme &&
+    return (subdomain.isScheme(domain.scheme) &&
         subdomain.port == domain.port &&
         (subdomain.host == domain.host ||
             subdomain.host.endsWith("." + domain.host)));
@@ -2928,13 +2928,13 @@
       return proxyCfg;
     }
 
-    if (url.scheme == "http") {
+    if (url.isScheme("http")) {
       String? proxy = environment["http_proxy"] ?? environment["HTTP_PROXY"];
       proxyCfg = checkProxy(proxy);
       if (proxyCfg != null) {
         return proxyCfg;
       }
-    } else if (url.scheme == "https") {
+    } else if (url.isScheme("https")) {
       String? proxy = environment["https_proxy"] ?? environment["HTTPS_PROXY"];
       proxyCfg = checkProxy(proxy);
       if (proxyCfg != null) {
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index c7126c2..fdafda8 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -996,7 +996,7 @@
       {CompressionOptions compression = CompressionOptions.compressionDefault,
       HttpClient? customClient}) {
     Uri uri = Uri.parse(url);
-    if (uri.scheme != "ws" && uri.scheme != "wss") {
+    if (!uri.isScheme("ws") && !uri.isScheme("wss")) {
       throw WebSocketException("Unsupported URL scheme '${uri.scheme}'");
     }
 
@@ -1011,7 +1011,7 @@
     final callerStackTrace = StackTrace.current;
 
     uri = Uri(
-        scheme: uri.scheme == "wss" ? "https" : "http",
+        scheme: uri.isScheme("wss") ? "https" : "http",
         userInfo: uri.userInfo,
         host: uri.host,
         port: uri.port,
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
index 95b46d6..1ef87b9 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -17,7 +17,8 @@
         Primitives,
         PrivateSymbol,
         quoteStringForRegExp,
-        undefined;
+        undefined,
+        wrapZoneUnaryCallback;
 import 'dart:_runtime' as dart;
 import 'dart:_foreign_helper' show JS, JSExportName;
 import 'dart:_native_typed_data' show NativeUint8List;
@@ -165,19 +166,55 @@
   }
 }
 
+// Patch for WeakReference implementation.
 @patch
 class WeakReference<T extends Object> {
   @patch
   factory WeakReference(T object) {
-    throw UnimplementedError("WeakReference");
+    return _WeakReferenceWrapper<T>(object);
   }
 }
 
+class _WeakReferenceWrapper<T extends Object> implements WeakReference<T> {
+  final Object _weakRef;
+
+  _WeakReferenceWrapper(T object)
+      : _weakRef = JS('!', 'new WeakRef(#)', object);
+
+  T? get target {
+    var target = JS<T?>('', '#.deref()', _weakRef);
+    // Coerce to null if JavaScript returns undefined.
+    if (JS<bool>('!', 'target === void 0')) return null;
+    return target;
+  }
+}
+
+// Patch for Finalizer implementation.
 @patch
 class Finalizer<T> {
   @patch
   factory Finalizer(void Function(T) object) {
-    throw UnimplementedError("Finalizer");
+    return _FinalizationRegistryWrapper<T>(object);
+  }
+}
+
+class _FinalizationRegistryWrapper<T> implements Finalizer<T> {
+  final Object _registry;
+
+  _FinalizationRegistryWrapper(void Function(T) callback)
+      : _registry = JS('!', 'new FinalizationRegistry(#)',
+            wrapZoneUnaryCallback(callback));
+
+  void attach(Object value, T token, {Object? detach}) {
+    if (detach != null) {
+      JS('', '#.register(#, #, #)', _registry, value, token, detach);
+    } else {
+      JS('', '#.register(#, #)', _registry, value, token);
+    }
+  }
+
+  void detach(Object detachToken) {
+    JS('', '#.unregister(#)', _registry, detachToken);
   }
 }
 
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
index 3fc8f51..1eed466 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -4,6 +4,7 @@
 
 library dart._js_helper;
 
+import 'dart:async' show Zone;
 import 'dart:collection';
 
 import 'dart:_foreign_helper' show JS, JSExportName;
@@ -828,3 +829,11 @@
 /// Like [assertInterop], except iterates over a list of arguments
 /// non-recursively.
 void assertInteropArgs(List<Object?> args) => args.forEach(assertInterop);
+
+/// Wraps the given [callback] within the current Zone.
+void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
+  // For performance reasons avoid wrapping if we are in the root zone.
+  if (Zone.current == Zone.root) return callback;
+  if (callback == null) return null;
+  return Zone.current.bindUnaryCallbackGuarded(callback);
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 529682d..1332aef 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -13,6 +13,7 @@
         checkInt,
         Closure,
         ConstantMap,
+        convertDartClosureToJS,
         getRuntimeType,
         JsLinkedHashMap,
         jsonEncodeNative,
@@ -23,7 +24,8 @@
         quoteStringForRegExp,
         getTraceFromException,
         RuntimeError,
-        wrapException;
+        wrapException,
+        wrapZoneUnaryCallback;
 
 import 'dart:_foreign_helper' show JS;
 import 'dart:_native_typed_data' show NativeUint8List;
@@ -117,19 +119,49 @@
   }
 }
 
+// Patch for WeakReference implementation.
 @patch
 class WeakReference<T extends Object> {
   @patch
   factory WeakReference(T object) {
-    throw UnimplementedError("WeakReference");
+    return _WeakReferenceWrapper<T>(object);
   }
 }
 
+class _WeakReferenceWrapper<T extends Object> implements WeakReference<T> {
+  final Object _weakRef;
+
+  _WeakReferenceWrapper(T object) : _weakRef = JS('', 'new WeakRef(#)', object);
+
+  T? get target => JS('', '#.deref()', _weakRef);
+}
+
+// Patch for Finalizer implementation.
 @patch
 class Finalizer<T> {
   @patch
   factory Finalizer(void Function(T) object) {
-    throw UnimplementedError("Finalizer");
+    return _FinalizationRegistryWrapper<T>(object);
+  }
+}
+
+class _FinalizationRegistryWrapper<T> implements Finalizer<T> {
+  final Object _registry;
+
+  _FinalizationRegistryWrapper(void Function(T) callback)
+      : _registry = JS('', 'new FinalizationRegistry(#)',
+            convertDartClosureToJS(wrapZoneUnaryCallback(callback), 1));
+
+  void attach(Object value, T token, {Object? detach}) {
+    if (detach != null) {
+      JS('', '#.register(#, #, #)', _registry, value, token, detach);
+    } else {
+      JS('', '#.register(#, #)', _registry, value, token);
+    }
+  }
+
+  void detach(Object detachToken) {
+    JS('', '#.unregister(#)', _registry, detachToken);
   }
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index f0ecaa5..5fd54ae 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -27,7 +27,7 @@
 
 import 'dart:collection';
 
-import 'dart:async' show Completer, DeferredLoadException, Future;
+import 'dart:async' show Completer, DeferredLoadException, Future, Zone;
 
 import 'dart:_foreign_helper'
     show
@@ -3029,3 +3029,11 @@
 Object? rawStartupMetrics() {
   return JS('JSArray', '#.a', JS_EMBEDDED_GLOBAL('', STARTUP_METRICS));
 }
+
+/// Wraps the given [callback] within the current Zone.
+void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
+  // For performance reasons avoid wrapping if we are in the root zone.
+  if (Zone.current == Zone.root) return callback;
+  if (callback == null) return null;
+  return Zone.current.bindUnaryCallbackGuarded(callback);
+}
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index e39fa7f..2684e6f 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -96,7 +96,7 @@
 _setPackagesConfig(String packagesParam) {
   var packagesName = _sanitizeWindowsPath(packagesParam);
   var packagesUri = Uri.parse(packagesName);
-  if (packagesUri.scheme == '') {
+  if (!packagesUri.hasScheme) {
     // Script does not have a scheme, assume that it is a path,
     // resolve it against the working directory.
     packagesUri = _workingDirectory.resolveUri(packagesUri);
@@ -107,7 +107,7 @@
 // Given a uri with a 'package' scheme, return a Uri that is prefixed with
 // the package root or resolved relative to the package configuration.
 Uri _resolvePackageUri(Uri uri) {
-  assert(uri.scheme == "package");
+  assert(uri.isScheme("package"));
   assert(_packagesReady);
 
   if (uri.host.isNotEmpty) {
@@ -444,7 +444,7 @@
 _handlePackagesRequest(bool traceLoading, int tag, Uri resource) {
   try {
     if (tag == -1) {
-      if (resource.scheme == '' || resource.scheme == 'file') {
+      if (!resource.hasScheme || resource.isScheme('file')) {
         return _findPackagesConfiguration(traceLoading, resource);
       } else {
         return "Unsupported scheme used to locate .packages file:'$resource'.";
@@ -454,13 +454,13 @@
         _log("Handling load of packages map: '$resource'.");
       }
       late Uint8List bytes;
-      if (resource.scheme == '' || resource.scheme == 'file') {
+      if (!resource.hasScheme || resource.isScheme('file')) {
         final file = File.fromUri(resource);
         if (!file.existsSync()) {
           return "Packages file '$resource' does not exit.";
         }
         bytes = file.readAsBytesSync();
-      } else if (resource.scheme == 'data') {
+      } else if (resource.isScheme('data')) {
         final uriData = resource.data!;
         if (!_isValidUtf8DataUrl(uriData)) {
           return "The data resource '$resource' must have a 'text/plain' mime "
@@ -543,7 +543,7 @@
   }
   var packagesName = _sanitizeWindowsPath(packagesParam);
   var packagesUri = Uri.parse(packagesName);
-  if (packagesUri.scheme == '') {
+  if (!packagesUri.hasScheme) {
     // Script does not have a scheme, assume that it is a path,
     // resolve it against the working directory.
     packagesUri = _workingDirectory.resolveUri(packagesUri);
@@ -569,7 +569,7 @@
   scriptName = _sanitizeWindowsPath(scriptName);
 
   var scriptUri = Uri.parse(scriptName);
-  if (scriptUri.scheme == '') {
+  if (!scriptUri.hasScheme) {
     // Script does not have a scheme, assume that it is a path,
     // resolve it against the working directory.
     scriptUri = _workingDirectory.resolveUri(scriptUri);
@@ -608,7 +608,7 @@
   if (_traceLoading) {
     _log("Request for package Uri resolution from user code: $packageUri");
   }
-  if (packageUri.scheme != "package") {
+  if (!packageUri.isScheme("package")) {
     if (_traceLoading) {
       _log("Non-package Uri, returning unmodified: $packageUri");
     }
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index ea6c234..546f62d 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -75,7 +75,7 @@
 /// Here the `File.readAsString` method from `dart:io` is an asychronous
 /// function returning a `Future<String>`.
 /// The `fileContains` function is marked with `async` right before its body,
-/// which means that you can use `await` insider it,
+/// which means that you can use `await` inside it,
 /// and that it must return a future.
 /// The call to `File(path).readAsString()` initiates reading the file into
 /// a string and produces a `Future<String>` which will eventually contain the
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 1b7176e..44b3906 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -604,7 +604,9 @@
   /// succeed by the way the function is called.
   /// Should be used judiciously.
   void _asyncCompleteUnchecked(/*FutureOr<T>*/ dynamic value) {
-    assert((value as FutureOr<T>) == value);
+    // Ensure [value] is FutureOr<T>, do so using an `as` check so it works
+    // also correctly in non-sound null-safety mode.
+    assert(identical(value as FutureOr<T>, value));
     final typedValue = unsafeCast<FutureOr<T>>(value);
 
     // Doing just "is Future" is not sufficient.
@@ -625,7 +627,9 @@
   /// [Future].
   /// Should be used judiciously.
   void _asyncCompleteUncheckedNoFuture(/*T*/ dynamic value) {
-    assert((value as T) == value);
+    // Ensure [value] is T, do so using an `as` check so it works also correctly
+    // in non-sound null-safety mode.
+    assert(identical(value as T, value));
     _asyncCompleteWithValue(unsafeCast<T>(value));
   }
 
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index cd38662..d8ee831 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -2184,7 +2184,9 @@
           }
         }
         String slice = host.substring(sectionStart, index);
-        (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char));
+        (buffer ??= StringBuffer())
+          ..write(slice)
+          ..write(_escapeChar(char));
         index += sourceLength;
         sectionStart = index;
       }
@@ -2261,7 +2263,9 @@
         }
         String slice = host.substring(sectionStart, index);
         if (!isNormalized) slice = slice.toLowerCase();
-        (buffer ??= StringBuffer())..write(slice)..write(_escapeChar(char));
+        (buffer ??= StringBuffer())
+          ..write(slice)
+          ..write(_escapeChar(char));
         index += sourceLength;
         sectionStart = index;
       }
@@ -2928,7 +2932,10 @@
 
   String _initializeText() {
     StringBuffer sb = StringBuffer();
-    if (scheme.isNotEmpty) sb..write(scheme)..write(":");
+    if (scheme.isNotEmpty)
+      sb
+        ..write(scheme)
+        ..write(":");
     if (hasAuthority || (scheme == "file")) {
       // File URIS always have the authority, even if it is empty.
       // The empty URI means "localhost".
@@ -2936,8 +2943,14 @@
       _writeAuthority(sb);
     }
     sb.write(path);
-    if (_query != null) sb..write("?")..write(_query);
-    if (_fragment != null) sb..write("#")..write(_fragment);
+    if (_query != null)
+      sb
+        ..write("?")
+        ..write(_query);
+    if (_fragment != null)
+      sb
+        ..write("#")
+        ..write(_fragment);
     return sb.toString();
   }
 
@@ -3439,7 +3452,7 @@
   /// and the path (concatenated with the query, if there is one) must be valid
   /// as data URI content with the same rules as [parse].
   factory UriData.fromUri(Uri uri) {
-    if (uri.scheme != "data") {
+    if (!uri.isScheme("data")) {
       throw ArgumentError.value(uri, "uri", "Scheme must be 'data'");
     }
     if (uri.hasAuthority) {
@@ -3487,7 +3500,10 @@
     }
     if (charsetName != null) {
       // TODO(39209): Use ?.. when sequences are properly supported.
-      if (indices != null) indices..add(buffer.length)..add(buffer.length + 8);
+      if (indices != null)
+        indices
+          ..add(buffer.length)
+          ..add(buffer.length + 8);
       buffer.write(";charset=");
       buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, utf8, false));
     }
diff --git a/tests/corelib/uri_base_test.dart b/tests/corelib/uri_base_test.dart
index a54a287..51822c4 100644
--- a/tests/corelib/uri_base_test.dart
+++ b/tests/corelib/uri_base_test.dart
@@ -7,7 +7,7 @@
 main() {
   try {
     Uri base = Uri.base;
-    Expect.isTrue(Uri.base.scheme == "file" || Uri.base.scheme == "http");
+    Expect.isTrue(Uri.base.isScheme("file") || Uri.base.isScheme("http"));
   } on UnsupportedError catch (e) {
     Expect.isTrue(e.toString().contains("'Uri.base' is not supported"));
   }
diff --git a/tests/corelib_2/uri_base_test.dart b/tests/corelib_2/uri_base_test.dart
index 3717571..eb35e61 100644
--- a/tests/corelib_2/uri_base_test.dart
+++ b/tests/corelib_2/uri_base_test.dart
@@ -9,7 +9,7 @@
 main() {
   try {
     Uri base = Uri.base;
-    Expect.isTrue(Uri.base.scheme == "file" || Uri.base.scheme == "http");
+    Expect.isTrue(Uri.base.isScheme("file") || Uri.base.isScheme("http"));
   } on UnsupportedError catch (e) {
     Expect.isTrue(e.toString().contains("'Uri.base' is not supported"));
   }
diff --git a/tests/lib/collection/map_iterables_consistency_test.dart b/tests/lib/collection/map_iterables_consistency_test.dart
new file mode 100644
index 0000000..d3c1ea6
--- /dev/null
+++ b/tests/lib/collection/map_iterables_consistency_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+
+// Test that a Map's keys, values and entries iterables are consistent with
+// their map.
+//
+// While it is generally not permitted to modify a map while iterating the keys,
+// values, or entries, it is possible to iterate these collections in between
+// modifications of the map.
+//
+// See #48282
+
+void check(String kind, Map m) {
+  Expect.equals(0, m.length);
+
+  // These existing iterables
+  final keys = m.keys;
+  final values = m.values;
+  final entries = m.entries;
+
+  for (int i = 0; i < 20; i++) {
+    Expect.equals(i, m.length);
+
+    // Fresh iterables.
+    Expect.equals(i, m.keys.length);
+    Expect.equals(i, m.values.length);
+    Expect.equals(i, m.entries.length);
+
+    Expect.equals(i, List.of(m.keys).length);
+    Expect.equals(i, List.of(m.values).length);
+    Expect.equals(i, List.of(m.entries).length);
+
+    Expect.equals(i, iteratedLength(m.keys));
+    Expect.equals(i, iteratedLength(m.values));
+    Expect.equals(i, iteratedLength(m.entries));
+
+    // Existing iterables.
+    Expect.equals(i, keys.length);
+    Expect.equals(i, values.length);
+    Expect.equals(i, entries.length);
+
+    Expect.equals(i, List.of(keys).length);
+    Expect.equals(i, List.of(values).length);
+    Expect.equals(i, List.of(entries).length);
+
+    Expect.equals(i, iteratedLength(keys));
+    Expect.equals(i, iteratedLength(values));
+    Expect.equals(i, iteratedLength(entries));
+
+    m[i] = i;
+  }
+}
+
+int iteratedLength(Iterable iterable) {
+  int length = 0;
+  final iterator = iterable.iterator;
+  while (iterator.moveNext()) {
+    length++;
+  }
+  return length;
+}
+
+void main() {
+  check('Map', {});
+  check('Map.identity', Map.identity());
+  check('HashMap', HashMap());
+  check('HashMap.identity', HashMap.identity());
+  check('SplayTreeMap', SplayTreeMap());
+}
diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart
index e546722..1ed7d66 100644
--- a/tests/lib/mirrors/library_uri_package_test.dart
+++ b/tests/lib/mirrors/library_uri_package_test.dart
@@ -15,7 +15,7 @@
   ClassMirror valueClass = valueMirror.type;
   LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
   Uri uri = valueLibrary.uri;
-  if (uri.scheme != "https" ||
+  if (!uri.isScheme("https") ||
       uri.host != "dartlang.org" ||
       uri.path != "/dart2js-stripped-uri") {
     expect(uri, equals(expectedUri));
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index e48269e..a3e2a9c 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -199,7 +199,7 @@
   ClassMirror valueClass = valueMirror.type;
   LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
   Uri uri = valueLibrary.uri;
-  if (uri.scheme != "https" ||
+  if (!uri.isScheme("https") ||
       uri.host != "dartlang.org" ||
       uri.path != "/dart2js-stripped-uri") {
     expect(check(uri), isTrue);
diff --git a/tests/lib_2/collection/map_iterables_consistency_test.dart b/tests/lib_2/collection/map_iterables_consistency_test.dart
new file mode 100644
index 0000000..3ba421e
--- /dev/null
+++ b/tests/lib_2/collection/map_iterables_consistency_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+
+// Test that a Map's keys, values and entries iterables are consistent with
+// their map.
+//
+// While it is generally not permitted to modify a map while iterating the keys,
+// values, or entries, it is possible to iterate these collections in between
+// modifications of the map.
+//
+// See #48282
+
+void check(String kind, Map m) {
+  Expect.equals(0, m.length);
+
+  // These existing iterables
+  final keys = m.keys;
+  final values = m.values;
+  final entries = m.entries;
+
+  for (int i = 0; i < 20; i++) {
+    Expect.equals(i, m.length);
+
+    // Fresh iterables.
+    Expect.equals(i, m.keys.length);
+    Expect.equals(i, m.values.length);
+    Expect.equals(i, m.entries.length);
+
+    Expect.equals(i, List.of(m.keys).length);
+    Expect.equals(i, List.of(m.values).length);
+    Expect.equals(i, List.of(m.entries).length);
+
+    Expect.equals(i, iteratedLength(m.keys));
+    Expect.equals(i, iteratedLength(m.values));
+    Expect.equals(i, iteratedLength(m.entries));
+
+    // Existing iterables.
+    Expect.equals(i, keys.length);
+    Expect.equals(i, values.length);
+    Expect.equals(i, entries.length);
+
+    Expect.equals(i, List.of(keys).length);
+    Expect.equals(i, List.of(values).length);
+    Expect.equals(i, List.of(entries).length);
+
+    Expect.equals(i, iteratedLength(keys));
+    Expect.equals(i, iteratedLength(values));
+    Expect.equals(i, iteratedLength(entries));
+
+    m[i] = i;
+  }
+}
+
+int iteratedLength(Iterable iterable) {
+  int length = 0;
+  final iterator = iterable.iterator;
+  while (iterator.moveNext()) {
+    length++;
+  }
+  return length;
+}
+
+void main() {
+  check('Map', {});
+  check('Map.identity', Map.identity());
+  check('HashMap', HashMap());
+  check('HashMap.identity', HashMap.identity());
+  check('SplayTreeMap', SplayTreeMap());
+}
diff --git a/tests/lib_2/mirrors/library_uri_package_test.dart b/tests/lib_2/mirrors/library_uri_package_test.dart
index 38afa90..8f55ead 100644
--- a/tests/lib_2/mirrors/library_uri_package_test.dart
+++ b/tests/lib_2/mirrors/library_uri_package_test.dart
@@ -17,7 +17,7 @@
   ClassMirror valueClass = valueMirror.type;
   LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
   Uri uri = valueLibrary.uri;
-  if (uri.scheme != "https" ||
+  if (!uri.isScheme("https") ||
       uri.host != "dartlang.org" ||
       uri.path != "/dart2js-stripped-uri") {
     expect(uri, equals(expectedUri));
diff --git a/tests/lib_2/mirrors/mirrors_test.dart b/tests/lib_2/mirrors/mirrors_test.dart
index 11f81ec..5c4ef4e 100644
--- a/tests/lib_2/mirrors/mirrors_test.dart
+++ b/tests/lib_2/mirrors/mirrors_test.dart
@@ -201,7 +201,7 @@
   ClassMirror valueClass = valueMirror.type;
   LibraryMirror valueLibrary = valueClass.owner as LibraryMirror;
   Uri uri = valueLibrary.uri;
-  if (uri.scheme != "https" ||
+  if (!uri.isScheme("https") ||
       uri.host != "dartlang.org" ||
       uri.path != "/dart2js-stripped-uri") {
     expect(check(uri), isTrue);
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
index 37b458e..56ada33 100644
--- a/tests/standalone/io/web_socket_compression_test.dart
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -55,7 +55,7 @@
     String nonce = base64.encode(nonceData);
 
     uri = new Uri(
-        scheme: uri.scheme == "wss" ? "https" : "http",
+        scheme: uri.isScheme("wss") ? "https" : "http",
         userInfo: uri.userInfo,
         host: uri.host,
         port: uri.port,
diff --git a/tests/standalone_2/io/web_socket_compression_test.dart b/tests/standalone_2/io/web_socket_compression_test.dart
index 5931062..c62a521 100644
--- a/tests/standalone_2/io/web_socket_compression_test.dart
+++ b/tests/standalone_2/io/web_socket_compression_test.dart
@@ -57,7 +57,7 @@
     String nonce = base64.encode(nonceData);
 
     uri = new Uri(
-        scheme: uri.scheme == "wss" ? "https" : "http",
+        scheme: uri.isScheme("wss") ? "https" : "http",
         userInfo: uri.userInfo,
         host: uri.host,
         port: uri.port,
@@ -100,8 +100,7 @@
     createServer().then((server) {
       server.listen((request) {
         Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
-        WebSocketTransformer
-            .upgrade(request, compression: serverOptions)
+        WebSocketTransformer.upgrade(request, compression: serverOptions)
             .then((webSocket) {
           webSocket.listen((message) {
             Expect.equals("Hello World", message);
@@ -136,8 +135,7 @@
     createServer().then((server) {
       server.listen((request) {
         Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
-        WebSocketTransformer
-            .upgrade(request, compression: serverOpts)
+        WebSocketTransformer.upgrade(request, compression: serverOpts)
             .then((webSocket) {
           webSocket.listen((message) {
             Expect.equals("Hello World", message);
@@ -186,9 +184,9 @@
           ..headers.add(
               "Sec-WebSocket-Extensions",
               "permessage-deflate;"
-              // Test quoted values and space padded =
-              'server_max_window_bits="10"; client_max_window_bits = 12'
-              'client_no_context_takeover; server_no_context_takeover');
+                  // Test quoted values and space padded =
+                  'server_max_window_bits="10"; client_max_window_bits = 12'
+                  'client_no_context_takeover; server_no_context_takeover');
         request.response.contentLength = 0;
         request.response.detachSocket().then((socket) {
           return new WebSocket.fromUpgradedSocket(socket, serverSide: true);
@@ -218,8 +216,7 @@
       server.listen((request) {
         // Stuff
         Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
-        WebSocketTransformer
-            .upgrade(request, compression: serverCompression)
+        WebSocketTransformer.upgrade(request, compression: serverCompression)
             .then((webSocket) {
           webSocket.listen((message) {
             Expect.equals("Hello World", message);
@@ -342,22 +339,22 @@
     testReturnHeaders(
         'permessage-deflate; server_max_window_bits=10',
         "permessage-deflate;"
-        " server_max_window_bits=10;"
-        " client_max_window_bits=10");
+            " server_max_window_bits=10;"
+            " client_max_window_bits=10");
     // Don't provider context takeover if requested but not enabled.
     // Default is not enabled.
     testReturnHeaders(
         'permessage-deflate; client_max_window_bits;'
-        'client_no_context_takeover',
+            'client_no_context_takeover',
         'permessage-deflate; client_max_window_bits=15');
     // Enable context Takeover and provide if requested.
     compression = new CompressionOptions(
         clientNoContextTakeover: true, serverNoContextTakeover: true);
     testReturnHeaders(
         'permessage-deflate; client_max_window_bits; '
-        'client_no_context_takeover',
+            'client_no_context_takeover',
         'permessage-deflate; client_no_context_takeover; '
-        'client_max_window_bits=15',
+            'client_max_window_bits=15',
         serverCompression: compression);
     // Enable context takeover and don't provide if not requested
     compression = new CompressionOptions(
diff --git a/tests/web/weak_reference_test.dart b/tests/web/weak_reference_test.dart
new file mode 100644
index 0000000..3bbaa21
--- /dev/null
+++ b/tests/web/weak_reference_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Basic tests for the WeakReference and Finalizer API for the web backends.
+// Does not trigger garbage collection to heavily test the functionality.
+
+import 'package:expect/minitest.dart';
+
+class Foo {
+  int close() {
+    return 42; // no-op, dropped return value.
+  }
+}
+
+void callback(Foo f) {
+  f.close();
+}
+
+main() {
+  test('weak reference', () {
+    var list = ["foo"];
+    var weakRef = WeakReference<List<String>>(list);
+    expect(weakRef.target, equals(list));
+
+    // Javascript API throws when the representation of target is not 'object'
+    // in the compiled Javascript.
+    expect(() => WeakReference<String>("foo"), throws);
+    expect(() => WeakReference<int>(1), throws);
+  });
+
+  test('finalizer', () {
+    var finalizer = Finalizer<Foo>(callback);
+    var list = ["foo"];
+    var foo = Foo();
+    // Should not cause errors to attach or detach
+    finalizer.attach(list, foo);
+    finalizer.attach(list, foo, detach: list);
+    finalizer.detach(list);
+
+    // Should not cause errors to use a different detach token
+    var detachList = [1, 2, 3];
+    finalizer.attach(list, foo, detach: detachList);
+    finalizer.detach(detachList);
+
+    // JavaScript API returns false when unknown target detached.
+    // Should not cause an error to detach unknown token.
+    var unknownList = [2, 4, 6];
+    finalizer.detach(unknownList);
+
+    // JavaScript API throws when target and detach token are not objects.
+    expect(() => finalizer.attach("token string value", foo), throws);
+    expect(() => finalizer.detach("detach string value"), throws);
+  });
+}
diff --git a/tests/web/web.status b/tests/web/web.status
index 7bdbea2..c54cd80 100644
--- a/tests/web/web.status
+++ b/tests/web/web.status
@@ -53,3 +53,6 @@
 [ $compiler == none && $runtime == vm ]
 new_from_env_test: SkipByDesign # dart2js only test
 unconditional_dartio_import_test: SkipByDesign # dart2js only test
+
+[ $compiler == dartkp || $runtime == vm ]
+weak_reference_test: SkipByDesign # Web only test
diff --git a/tests/web_2/weak_reference_test.dart b/tests/web_2/weak_reference_test.dart
new file mode 100644
index 0000000..3bbaa21
--- /dev/null
+++ b/tests/web_2/weak_reference_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Basic tests for the WeakReference and Finalizer API for the web backends.
+// Does not trigger garbage collection to heavily test the functionality.
+
+import 'package:expect/minitest.dart';
+
+class Foo {
+  int close() {
+    return 42; // no-op, dropped return value.
+  }
+}
+
+void callback(Foo f) {
+  f.close();
+}
+
+main() {
+  test('weak reference', () {
+    var list = ["foo"];
+    var weakRef = WeakReference<List<String>>(list);
+    expect(weakRef.target, equals(list));
+
+    // Javascript API throws when the representation of target is not 'object'
+    // in the compiled Javascript.
+    expect(() => WeakReference<String>("foo"), throws);
+    expect(() => WeakReference<int>(1), throws);
+  });
+
+  test('finalizer', () {
+    var finalizer = Finalizer<Foo>(callback);
+    var list = ["foo"];
+    var foo = Foo();
+    // Should not cause errors to attach or detach
+    finalizer.attach(list, foo);
+    finalizer.attach(list, foo, detach: list);
+    finalizer.detach(list);
+
+    // Should not cause errors to use a different detach token
+    var detachList = [1, 2, 3];
+    finalizer.attach(list, foo, detach: detachList);
+    finalizer.detach(detachList);
+
+    // JavaScript API returns false when unknown target detached.
+    // Should not cause an error to detach unknown token.
+    var unknownList = [2, 4, 6];
+    finalizer.detach(unknownList);
+
+    // JavaScript API throws when target and detach token are not objects.
+    expect(() => finalizer.attach("token string value", foo), throws);
+    expect(() => finalizer.detach("detach string value"), throws);
+  });
+}
diff --git a/tests/web_2/web_2.status b/tests/web_2/web_2.status
index 7bdbea2..c54cd80 100644
--- a/tests/web_2/web_2.status
+++ b/tests/web_2/web_2.status
@@ -53,3 +53,6 @@
 [ $compiler == none && $runtime == vm ]
 new_from_env_test: SkipByDesign # dart2js only test
 unconditional_dartio_import_test: SkipByDesign # dart2js only test
+
+[ $compiler == dartkp || $runtime == vm ]
+weak_reference_test: SkipByDesign # Web only test
diff --git a/tools/VERSION b/tools/VERSION
index a12a574..cd65607 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 89
+PRERELEASE 90
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 79f5d04..2400619 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -147,7 +147,9 @@
         ..group("Current library: $_currentLibrary")
         ..groupCollapsed("All libraries:");
       _listLibraries();
-      window.console..groupEnd()..groupEnd();
+      window.console
+        ..groupEnd()
+        ..groupEnd();
       return;
     }
     var matches = findMatches(name);
@@ -169,9 +171,9 @@
   static List<Uri> _sortUris(Iterable<Uri> uris) {
     return (uris.toList())
       ..sort((Uri a, Uri b) {
-        if (a.scheme != b.scheme) {
-          if (a.scheme == 'dart') return -1;
-          if (b.scheme == 'dart') return 1;
+        if (!a.isScheme(b.scheme)) {
+          if (a.isScheme('dart')) return -1;
+          if (b.isScheme('dart')) return 1;
           return a.scheme.compareTo(b.scheme);
         }
         return a.toString().compareTo(b.toString());
@@ -213,14 +215,18 @@
       if (index != -1) {
         // %c enables styling console log messages with css
         // specified at the end of the console.
-        sb..write(txt.substring(0, index))..write('%c');
+        sb
+          ..write(txt.substring(0, index))
+          ..write('%c');
         var matchEnd = index + key.length;
         sb
           ..write(txt.substring(index, matchEnd))
           ..write('%c')
           ..write(txt.substring(matchEnd))
           ..write('\n');
-        boldPairs..add('font-weight: bold')..add('font-weight: normal');
+        boldPairs
+          ..add('font-weight: bold')
+          ..add('font-weight: normal');
       }
     }
     _log([sb.toString()]..addAll(boldPairs));
@@ -738,7 +744,7 @@
     // This matches JavaScript behavior. We should consider displaying
     // getters for all dart platform libraries rather than just the DOM
     // libraries.
-    return libraryMirror.uri.scheme == 'dart' &&
+    return libraryMirror.uri.isScheme('dart') &&
         SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
   }
 
diff --git a/tools/package_deps/bin/package_deps.dart b/tools/package_deps/bin/package_deps.dart
index 38cca34..1bf3598 100644
--- a/tools/package_deps/bin/package_deps.dart
+++ b/tools/package_deps/bin/package_deps.dart
@@ -168,7 +168,7 @@
       for (var import in _collectImports(file)) {
         try {
           var uri = Uri.parse(import);
-          if (uri.hasScheme && uri.scheme == 'package') {
+          if (uri.hasScheme && uri.isScheme('package')) {
             var packageName = path.split(uri.path).first;
             importedPackages.add(packageName);
           }