Version 2.17.0-107.0.dev

Merge commit '4bd312d1e6b101e6aa61149b9af2d9b062bdc251' into 'dev'
diff --git a/.dart_tool/OWNERS b/.dart_tool/OWNERS
new file mode 100644
index 0000000..d52dde4
--- /dev/null
+++ b/.dart_tool/OWNERS
@@ -0,0 +1,2 @@
+# Generated file
+per-file package_config.json=*
diff --git a/.github/OWNERS b/.github/OWNERS
new file mode 100644
index 0000000..12997a6
--- /dev/null
+++ b/.github/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_PRODUCT
+file:/tools/OWNERS_INFRA
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..88fdd3c
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,23 @@
+# Global approvers - only to be used as a last resort.
+asiva@google.com #{LAST_RESORT_SUGGESTION}
+athom@google.com #{LAST_RESORT_SUGGESTION}
+kustermann@google.com #{LAST_RESORT_SUGGESTION}
+leafp@google.com #{LAST_RESORT_SUGGESTION}
+sigmund@google.com #{LAST_RESORT_SUGGESTION}
+vegorov@google.com #{LAST_RESORT_SUGGESTION}
+vsm@google.com #{LAST_RESORT_SUGGESTION}
+
+# DEPS
+per-file DEPS=/tools/OWNERS_ENG
+
+# Changelog, AUTHORS, and .git* do not require approval.
+per-file CHANGELOG.md,AUTHORS,.gitattributes,.gitconfig,.gitignore=*
+
+# Product documentation
+CONTRIBUTING.md,LICENSE,PATENT_GRANT,README.*,SECURITY.md=file:/tools/OWNERS_PRODUCT
+
+# Top level build files
+per-file .clang-format,BUILD.gn,sdk_args.gni=file:/tools/OWNERS_VM,file:/tools/OWNERS_INFRA
+
+# Generated file
+per-file .packages=*
diff --git a/benchmarks/OWNERS b/benchmarks/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/benchmarks/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/build/OWNERS b/build/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/build/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/docs/OWNERS b/docs/OWNERS
new file mode 100644
index 0000000..22a2e82
--- /dev/null
+++ b/docs/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION
+file:/tools/OWNERS_PRODUCT
diff --git a/pkg/OWNERS b/pkg/OWNERS
new file mode 100644
index 0000000..c3abcf9
--- /dev/null
+++ b/pkg/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION #{LAST_RESORT_SUGGESTION}
+file:/tools/OWNERS_INFRA #{LAST_RESORT_SUGGESTION}
diff --git a/pkg/_fe_analyzer_shared/OWNERS b/pkg/_fe_analyzer_shared/OWNERS
new file mode 100644
index 0000000..6fd2278
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_CFE
diff --git a/pkg/analysis_server/OWNERS b/pkg/analysis_server/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analysis_server/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index a782782..55257c6 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -208,6 +208,8 @@
   static const InvalidFileLineCol = ErrorCodes(-32004);
   static const UnknownCommand = ErrorCodes(-32005);
   static const InvalidCommandArguments = ErrorCodes(-32006);
+
+  /// A file that is not part of the analyzed set.
   static const FileNotAnalyzed = ErrorCodes(-32007);
   static const FileHasErrors = ErrorCodes(-32008);
   static const ClientFailedToApplyEdit = ErrorCodes(-32009);
@@ -215,6 +217,9 @@
   static const RefactorFailed = ErrorCodes(-32011);
   static const FeatureDisabled = ErrorCodes(-32012);
 
+  /// A file that is expected to be analyzed, but failed.
+  static const FileAnalysisFailed = ErrorCodes(-32013);
+
   /// An error raised when the server detects that the server and client are out
   /// of sync and cannot recover. For example if a textDocument/didChange notification
   /// has invalid offsets, suggesting the client and server have become out of sync
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
index 81b9b85..84da8f2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -23,7 +23,8 @@
   ErrorOr<List<TextEdit>?> formatFile(String path) {
     final file = server.resourceProvider.getFile(path);
     if (!file.exists) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      return error(
+          ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
     }
 
     final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
index a6bbf90..f28ef15 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
@@ -23,7 +23,8 @@
   ErrorOr<List<TextEdit>?> formatRange(String path, Range range) {
     final file = server.resourceProvider.getFile(path);
     if (!file.exists) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      return error(
+          ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
     }
 
     final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index be75ccb..6ff4313 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -23,7 +23,8 @@
   ErrorOr<List<TextEdit>?> formatFile(String path) {
     final file = server.resourceProvider.getFile(path);
     if (!file.exists) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      return error(
+          ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
     }
 
     final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index e0f497c..ddd82dc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -56,7 +56,8 @@
     final lineInfo = server.getLineInfo(path);
 
     if (lineInfo == null) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      return error(ServerErrorCodes.InvalidFilePath,
+          'Unable to obtain line information for file', path);
     } else {
       return success(lineInfo);
     }
@@ -65,7 +66,19 @@
   Future<ErrorOr<ResolvedUnitResult>> requireResolvedUnit(String path) async {
     final result = await server.getResolvedUnit(path);
     if (result == null) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      if (server.isAnalyzed(path)) {
+        // If the file was being analyzed and we got a null result, that usually
+        // indicators a parser or analysis failure, so provide a more specific
+        // message.
+        return error(ServerErrorCodes.FileAnalysisFailed,
+            'Analysis failed for file', path);
+      } else {
+        return error(ServerErrorCodes.FileNotAnalyzed,
+            'File is not being analyzed', path);
+      }
+    } else if (!result.exists) {
+      return error(
+          ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
     }
     return success(result);
   }
@@ -73,7 +86,16 @@
   ErrorOr<ParsedUnitResult> requireUnresolvedUnit(String path) {
     final result = server.getParsedUnit(path);
     if (result == null) {
-      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+      if (server.isAnalyzed(path)) {
+        // If the file was being analyzed and we got a null result, that usually
+        // indicators a parser or analysis failure, so provide a more specific
+        // message.
+        return error(ServerErrorCodes.FileAnalysisFailed,
+            'Analysis failed for file', path);
+      } else {
+        return error(ServerErrorCodes.FileNotAnalyzed,
+            'File is not being analyzed', path);
+      }
     }
     return success(result);
   }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 853fa09..ba6a1d6 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
 import 'dart:math';
 
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart'
@@ -798,7 +799,18 @@
     ));
   }
   try {
-    return ErrorOr<String>.success(uri.toFilePath());
+    final filePath = uri.toFilePath();
+    // On Windows, paths that start with \ and not a drive letter are not
+    // supported but will return `true` from `path.isAbsolute` so check for them
+    // specifically.
+    if (Platform.isWindows && filePath.startsWith(r'\')) {
+      return ErrorOr<String>.error(ResponseError(
+        code: lsp.ServerErrorCodes.InvalidFilePath,
+        message: 'URI was not an absolute file path (missing drive letter)',
+        data: uri.toString(),
+      ));
+    }
+    return ErrorOr<String>.success(filePath);
   } catch (e) {
     // Even if tryParse() works and file == scheme, toFilePath() can throw on
     // Windows if there are invalid characters.
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index a37882a..48ddc1b 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -206,8 +206,10 @@
     newFile(mainFilePath, content: content);
     await initialize(allowEmptyRootUri: true);
 
-    await expectLater(getDocumentSymbols(mainFileUri.toString()),
-        throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)));
+    await expectLater(
+        getDocumentSymbols(mainFileUri.toString()),
+        throwsA(isResponseError(ServerErrorCodes.FileNotAnalyzed,
+            message: 'File is not being analyzed')));
   }
 
   Future<void> test_nonDartFile() async {
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 7ffff8a..f3d24e8 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -640,7 +640,8 @@
     await expectLater(
       formatDocument(
           Uri.file(join(projectFolderPath, 'missing.dart')).toString()),
-      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'File does not exist')),
     );
   }
 
@@ -649,8 +650,9 @@
 
     await expectLater(
       // Add some invalid path characters to the end of a valid file:// URI.
-      formatDocument(mainFileUri.toString() + '***.dart'),
-      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+      formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'File URI did not contain a valid file path')),
     );
   }
 
@@ -659,7 +661,8 @@
 
     await expectLater(
       formatDocument('a:/a.dart'),
-      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'URI was not a valid file:// URI')),
     );
   }
 
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 22608c0..48d0109 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_test.dart
@@ -2,11 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../tool/lsp_spec/matchers.dart';
 import 'server_abstract.dart';
 
 void main() {
@@ -44,6 +48,67 @@
     await server.exited.timeout(const Duration(seconds: 10));
   }
 
+  Future<void> test_path_doesNotExist() async {
+    final missingFileUri = Uri.file(join(projectFolderPath, 'missing.dart'));
+    await initialize();
+    await expectLater(
+      getHover(missingFileUri, startOfDocPos),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'File does not exist')),
+    );
+  }
+
+  Future<void> test_path_invalidFormat() async {
+    await initialize();
+    await expectLater(
+      // Add some invalid path characters to the end of a valid file:// URI.
+      formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'File URI did not contain a valid file path')),
+    );
+  }
+
+  Future<void> test_path_missingDriveLetterWindows() async {
+    // This test is only valid on Windows, as a URI in the format:
+    //    file:///foo/bar.dart
+    // is valid for non-Windows platforms, but not valid on Windows as it does
+    // not have a drive letter.
+    if (!Platform.isWindows) {
+      return;
+    }
+    final missingDriveLetterFileUri = Uri.file('/foo/bar.dart');
+    await initialize();
+    await expectLater(
+      getHover(missingDriveLetterFileUri, startOfDocPos),
+      // The Uri.file() above translates to a non-file:// URI of just 'a/b.dart'
+      // so will get the not-file-scheme error message.
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'URI was not an absolute file path (missing drive letter)')),
+    );
+  }
+
+  Future<void> test_path_notFileScheme() async {
+    final relativeFileUri = Uri(scheme: 'foo', path: '/a/b.dart');
+    await initialize();
+    await expectLater(
+      getHover(relativeFileUri, startOfDocPos),
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'URI was not a valid file:// URI')),
+    );
+  }
+
+  Future<void> test_path_relative() async {
+    final relativeFileUri = Uri.file('a/b.dart');
+    await initialize();
+    await expectLater(
+      getHover(relativeFileUri, startOfDocPos),
+      // The Uri.file() above translates to a non-file:// URI of just 'a/b.dart'
+      // so will get the not-file-scheme error message.
+      throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+          message: 'URI was not a valid file:// URI')),
+    );
+  }
+
   Future<void> test_shutdown_initialized() async {
     await initialize();
     final response = await sendShutdown();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
index a424ae1..65bb7ae 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
@@ -15,8 +15,13 @@
 Matcher isMapOf(Matcher indexMatcher, Matcher valueMatcher) =>
     MapTypeMatcher(wrapMatcher(indexMatcher), wrapMatcher(valueMatcher));
 
-Matcher isResponseError(ErrorCodes code) => const TypeMatcher<ResponseError>()
-    .having((e) => e.code, 'code', equals(code));
+Matcher isResponseError(ErrorCodes code, {String? message}) {
+  final matcher = const TypeMatcher<ResponseError>()
+      .having((e) => e.code, 'code', equals(code));
+  return message != null
+      ? matcher.having((e) => e.message, 'message', equals(message))
+      : matcher;
+}
 
 Matcher isSimpleType(String name) => SimpleTypeMatcher(name);
 
diff --git a/pkg/analysis_server_client/OWNERS b/pkg/analysis_server_client/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analysis_server_client/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer/OWNERS b/pkg/analyzer/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_cli/OWNERS b/pkg/analyzer_cli/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_cli/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_plugin/OWNERS b/pkg/analyzer_plugin/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_plugin/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_utilities/OWNERS b/pkg/analyzer_utilities/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_utilities/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/async_helper/OWNERS b/pkg/async_helper/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/async_helper/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/build_integration/OWNERS b/pkg/build_integration/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/build_integration/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/compiler/OWNERS b/pkg/compiler/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/compiler/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_info/OWNERS b/pkg/dart2js_info/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_info/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_runtime_metrics/OWNERS b/pkg/dart2js_runtime_metrics/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_runtime_metrics/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_tools/OWNERS b/pkg/dart2js_tools/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_tools/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2native/OWNERS b/pkg/dart2native/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dart2native/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dart_internal/OWNERS b/pkg/dart_internal/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/dart_internal/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/dartdev/OWNERS b/pkg/dartdev/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/dartdev/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/dds/OWNERS b/pkg/dds/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dds/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dds_service_extensions/OWNERS b/pkg/dds_service_extensions/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dds_service_extensions/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dev_compiler/OWNERS b/pkg/dev_compiler/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dev_compiler/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/diagnostic/OWNERS b/pkg/diagnostic/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/diagnostic/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/expect/OWNERS b/pkg/expect/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/expect/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/front_end/OWNERS b/pkg/front_end/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/front_end/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/frontend_server/OWNERS b/pkg/frontend_server/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/frontend_server/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/js/OWNERS b/pkg/js/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/js_ast/OWNERS b/pkg/js_ast/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js_ast/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/js_runtime/OWNERS b/pkg/js_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/kernel/OWNERS b/pkg/kernel/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/kernel/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/language_versioning_2.7_test/OWNERS b/pkg/language_versioning_2.7_test/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/language_versioning_2.7_test/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/meta/OWNERS b/pkg/meta/OWNERS
new file mode 100644
index 0000000..80d5ff4
--- /dev/null
+++ b/pkg/meta/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/modular_test/OWNERS b/pkg/modular_test/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/modular_test/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/native_stack_traces/OWNERS b/pkg/native_stack_traces/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/native_stack_traces/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/nnbd_migration/OWNERS b/pkg/nnbd_migration/OWNERS
new file mode 100644
index 0000000..80d5ff4
--- /dev/null
+++ b/pkg/nnbd_migration/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/scrape/OWNERS b/pkg/scrape/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/scrape/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/smith/OWNERS b/pkg/smith/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/smith/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/sourcemap_testing/OWNERS b/pkg/sourcemap_testing/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/sourcemap_testing/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/status_file/OWNERS b/pkg/status_file/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/status_file/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/telemetry/OWNERS b/pkg/telemetry/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/telemetry/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/test_runner/OWNERS b/pkg/test_runner/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/test_runner/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/testing/OWNERS b/pkg/testing/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/testing/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/vm/OWNERS b/pkg/vm/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/vm_service/OWNERS b/pkg/vm_service/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm_service/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/vm_snapshot_analysis/OWNERS b/pkg/vm_snapshot_analysis/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm_snapshot_analysis/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/runtime/OWNERS b/runtime/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2e80b0a..3461f25 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -502,7 +502,8 @@
   ASSERT(flags != nullptr);
 
 #if defined(DART_PRECOMPILED_RUNTIME)
-  // AOT: All isolates start from the app snapshot.
+  // AOT: The service isolate is included in any AOT snapshot in non-PRODUCT
+  // mode - so we launch the vm-service from the main app AOT snapshot.
   const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
   const uint8_t* isolate_snapshot_instructions =
       app_isolate_snapshot_instructions;
@@ -693,11 +694,31 @@
   AppSnapshot* app_snapshot = NULL;
 
 #if defined(DART_PRECOMPILED_RUNTIME)
-  // AOT: All isolates start from the app snapshot.
+  const uint8_t* isolate_snapshot_data = nullptr;
+  const uint8_t* isolate_snapshot_instructions = nullptr;
+  if (is_main_isolate) {
+    isolate_snapshot_data = app_isolate_snapshot_data;
+    isolate_snapshot_instructions = app_isolate_snapshot_instructions;
+  } else {
+    // AOT: All isolates need to be run from AOT compiled snapshots.
+    const bool kForceLoadElfFromMemory = false;
+    app_snapshot =
+        Snapshot::TryReadAppSnapshot(script_uri, kForceLoadElfFromMemory);
+    if (app_snapshot == nullptr) {
+      *error = Utils::StrDup(
+          "The uri provided to `Isolate.spawnUri()` does not "
+          "contain a valid AOT snapshot.");
+      return nullptr;
+    }
+
+    const uint8_t* ignore_vm_snapshot_data;
+    const uint8_t* ignore_vm_snapshot_instructions;
+    app_snapshot->SetBuffers(
+        &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
+        &isolate_snapshot_data, &isolate_snapshot_instructions);
+  }
+
   bool isolate_run_app_snapshot = true;
-  const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
-  const uint8_t* isolate_snapshot_instructions =
-      app_isolate_snapshot_instructions;
   flags->null_safety =
       Dart_DetectNullSafety(nullptr, nullptr, nullptr, isolate_snapshot_data,
                             isolate_snapshot_instructions, nullptr, -1);
diff --git a/runtime/tests/vm/dart/spawn_uri_aot_test.dart b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
new file mode 100644
index 0000000..ded95ce
--- /dev/null
+++ b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
@@ -0,0 +1,114 @@
+// 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:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and gen_snapshot not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('dwarf-flag-test', (String dir) async {
+    File(path.join(dir, 'main.dart')).writeAsStringSync('''
+        import 'dart:isolate';
+        main(List<String> args) async {
+          final rp = ReceivePort();
+          try {
+            await Isolate.spawnUri(Uri.parse(args.single), <String>[], rp.sendPort);
+            final result = await rp.first;
+            if (result != 'hello from spawnee') throw 'failed';
+            print('got spawnee message');
+            print('success');
+          } finally {
+            rp.close();
+          }
+        }
+    ''');
+    for (final basename in ['spawnee', 'spawnee_checked']) {
+      File(path.join(dir, '$basename.dart')).writeAsStringSync('''
+          import 'dart:isolate';
+          main(List<String> args, dynamic sendPort) {
+            print('spawnee started');
+            (sendPort as SendPort).send('hello from spawnee');
+          }
+      ''');
+    }
+
+    for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
+      final script = path.join(dir, '$basename.dart');
+      final scriptDill = path.join(dir, '$basename.dart.dill');
+      final bool checked = basename.endsWith('_checked');
+
+      await run(genKernel, <String>[
+        if (checked) '--enable-asserts',
+        '--aot',
+        '--platform=$platformDill',
+        '-o',
+        scriptDill,
+        script,
+      ]);
+
+      final scriptAot = path.join(dir, '$basename.dart.dill.so');
+      await run(genSnapshot, <String>[
+        if (checked) '--enable-asserts',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptAot',
+        scriptDill,
+      ]);
+    }
+
+    // Successful run
+    final result1 = await runOutput(aotRuntime, <String>[
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'spawnee.dart.dill.so'),
+    ]);
+    Expect.deepEquals([
+      'spawnee started',
+      'got spawnee message',
+      'success',
+    ], result1);
+
+    // File exists and is AOT snapshot but was compiled with different flags
+    // (namely --enable-asserts)
+    final result2 = await runHelper(aotRuntime, [
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'spawnee_checked.dart.dill.so'),
+    ]);
+    Expect.notEquals(0, result2.exitCode);
+    Expect.contains('Snapshot not compatible with the current VM configuration',
+        result2.stderr);
+
+    // File exists and is AOT snapshot but was compiled with different flags
+    // (namely --enable-asserts)
+    final result3 = await runHelper(aotRuntime, [
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'does_not_exist.dart.dill.so'),
+    ]);
+    Expect.notEquals(0, result3.exitCode);
+    Expect.contains(
+        'The uri provided to `Isolate.spawnUri()` does not contain a valid AOT '
+        'snapshot',
+        result3.stderr);
+  });
+}
diff --git a/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
new file mode 100644
index 0000000..b3e3c21
--- /dev/null
+++ b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
@@ -0,0 +1,116 @@
+// 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:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and gen_snapshot not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('dwarf-flag-test', (String dir) async {
+    File(path.join(dir, 'main.dart')).writeAsStringSync('''
+        import 'dart:isolate';
+        main(List<String> args) async {
+          final rp = ReceivePort();
+          try {
+            await Isolate.spawnUri(Uri.parse(args.single), <String>[], rp.sendPort);
+            final result = await rp.first;
+            if (result != 'hello from spawnee') throw 'failed';
+            print('got spawnee message');
+            print('success');
+          } finally {
+            rp.close();
+          }
+        }
+    ''');
+    for (final basename in ['spawnee', 'spawnee_checked']) {
+      File(path.join(dir, '$basename.dart')).writeAsStringSync('''
+          import 'dart:isolate';
+          main(List<String> args, dynamic sendPort) {
+            print('spawnee started');
+            (sendPort as SendPort).send('hello from spawnee');
+          }
+      ''');
+    }
+
+    for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
+      final script = path.join(dir, '$basename.dart');
+      final scriptDill = path.join(dir, '$basename.dart.dill');
+      final bool checked = basename.endsWith('_checked');
+
+      await run(genKernel, <String>[
+        if (checked) '--enable-asserts',
+        '--aot',
+        '--platform=$platformDill',
+        '-o',
+        scriptDill,
+        script,
+      ]);
+
+      final scriptAot = path.join(dir, '$basename.dart.dill.so');
+      await run(genSnapshot, <String>[
+        if (checked) '--enable-asserts',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptAot',
+        scriptDill,
+      ]);
+    }
+
+    // Successful run
+    final result1 = await runOutput(aotRuntime, <String>[
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'spawnee.dart.dill.so'),
+    ]);
+    Expect.deepEquals([
+      'spawnee started',
+      'got spawnee message',
+      'success',
+    ], result1);
+
+    // File exists and is AOT snapshot but was compiled with different flags
+    // (namely --enable-asserts)
+    final result2 = await runHelper(aotRuntime, [
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'spawnee_checked.dart.dill.so'),
+    ]);
+    Expect.notEquals(0, result2.exitCode);
+    Expect.contains('Snapshot not compatible with the current VM configuration',
+        result2.stderr);
+
+    // File exists and is AOT snapshot but was compiled with different flags
+    // (namely --enable-asserts)
+    final result3 = await runHelper(aotRuntime, [
+      path.join(dir, 'main.dart.dill.so'),
+      path.join(dir, 'does_not_exist.dart.dill.so'),
+    ]);
+    Expect.notEquals(0, result3.exitCode);
+    Expect.contains(
+        'The uri provided to `Isolate.spawnUri()` does not contain a valid AOT '
+        'snapshot',
+        result3.stderr);
+  });
+}
diff --git a/samples-dev/OWNERS b/samples-dev/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples-dev/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/samples/OWNERS b/samples/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/samples_2/OWNERS b/samples_2/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples_2/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/sdk/OWNERS b/sdk/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/sdk/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/sdk/lib/_internal/js_dev_runtime/OWNERS b/sdk/lib/_internal/js_dev_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/sdk/lib/_internal/js_dev_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/sdk/lib/_internal/js_runtime/OWNERS b/sdk/lib/_internal/js_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/sdk/lib/_internal/vm/OWNERS b/sdk/lib/_internal/vm/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/sdk/lib/_internal/vm/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/tests/OWNERS b/tests/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/tests/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/tests/lib/isolate/weak_reference_message_2_test.dart b/tests/lib/isolate/weak_reference_message_2_test.dart
index f925185..cc70985 100644
--- a/tests/lib/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib/isolate/weak_reference_message_2_test.dart
@@ -2,10 +2,10 @@
 // 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:typed_data';
+import 'dart:io';
 import "dart:isolate";
+import 'dart:typed_data';
 
-import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 
 void main(List<String> arguments, Object? message) async {
@@ -19,8 +19,11 @@
 
 Future<void> runTest() async {
   final port = ReceivePort();
+  // By spawning the isolate from an uri the newly isolate will run in it's own
+  // isolate group. This way we can test the message snapshot serialization
+  // code.
   await Isolate.spawnUri(
-    Uri.parse('weak_reference_message_2_test.dart'),
+    Platform.script,
     ['helper'],
     port.sendPort,
   );
diff --git a/tests/lib_2/isolate/weak_reference_message_2_test.dart b/tests/lib_2/isolate/weak_reference_message_2_test.dart
index bd9cb92..1c18735 100644
--- a/tests/lib_2/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib_2/isolate/weak_reference_message_2_test.dart
@@ -4,10 +4,10 @@
 
 // @dart = 2.9
 
-import 'dart:typed_data';
+import 'dart:io';
 import "dart:isolate";
+import 'dart:typed_data';
 
-import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 
 void main(List<String> arguments, Object message) async {
@@ -21,8 +21,11 @@
 
 Future<void> runTest() async {
   final port = ReceivePort();
+  // By spawning the isolate from an uri the newly isolate will run in it's own
+  // isolate group. This way we can test the message snapshot serialization
+  // code.
   await Isolate.spawnUri(
-    Uri.parse('weak_reference_message_2_test.dart'),
+    Platform.script,
     ['helper'],
     port.sendPort,
   );
diff --git a/third_party/OWNERS b/third_party/OWNERS
new file mode 100644
index 0000000..c3abcf9
--- /dev/null
+++ b/third_party/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION #{LAST_RESORT_SUGGESTION}
+file:/tools/OWNERS_INFRA #{LAST_RESORT_SUGGESTION}
diff --git a/third_party/tcmalloc/OWNERS b/third_party/tcmalloc/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/third_party/tcmalloc/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/tools/OWNERS b/tools/OWNERS
new file mode 100644
index 0000000..e2eae44
--- /dev/null
+++ b/tools/OWNERS
@@ -0,0 +1,10 @@
+file:/OWNERS_INFRA
+
+# Groups administrate themselves.
+per-file OWNERS_ANALYZER=file:OWNERS_ANALYZER
+per-file OWNERS_CFE=file:OWNERS_CFE
+per-file OWNERS_FOUNDATION=file:OWNERS_FOUNDATION
+per-file OWNERS_INFRA=file:OWNERS_INFRA
+per-file OWNERS_PRODUCT=file:OWNERS_PRODUCT
+per-file OWNERS_VM=file:OWNERS_VM
+per-file OWNERS_WEB=file:OWNERS_WEB
diff --git a/tools/OWNERS_ANALYZER b/tools/OWNERS_ANALYZER
new file mode 100644
index 0000000..dfcbd53
--- /dev/null
+++ b/tools/OWNERS_ANALYZER
@@ -0,0 +1,6 @@
+brianwilkerson@google.com
+jcollins@google.com
+leafp@google.com
+paulberry@google.com
+scheglov@google.com
+srawlins@google.com
diff --git a/tools/OWNERS_CFE b/tools/OWNERS_CFE
new file mode 100644
index 0000000..ceb75971
--- /dev/null
+++ b/tools/OWNERS_CFE
@@ -0,0 +1,4 @@
+cstefantsova@google.com
+jensj@google.com
+johnniwinther@google.com
+vegorov@google.com
diff --git a/tools/OWNERS_ENG b/tools/OWNERS_ENG
new file mode 100644
index 0000000..6857872
--- /dev/null
+++ b/tools/OWNERS_ENG
@@ -0,0 +1,7 @@
+# All engineering teams
+file:OWNERS_ANALYZER
+file:OWNERS_CFE
+file:OWNERS_FOUNDATION
+file:OWNERS_INFRA
+file:OWNERS_VM
+file:OWNERS_WEB
diff --git a/tools/OWNERS_FOUNDATION b/tools/OWNERS_FOUNDATION
new file mode 100644
index 0000000..b23483a
--- /dev/null
+++ b/tools/OWNERS_FOUNDATION
@@ -0,0 +1,7 @@
+eernst@google.com
+jakemac@google.com
+leafp@google.com
+lrn@google.com
+nbosch@google.com
+paulberry@google.com
+rnystrom@google.com
diff --git a/tools/OWNERS_INFRA b/tools/OWNERS_INFRA
new file mode 100644
index 0000000..838001e
--- /dev/null
+++ b/tools/OWNERS_INFRA
@@ -0,0 +1,3 @@
+athom@google.com
+sortie@google.com
+whesse@google.com
diff --git a/tools/OWNERS_PRODUCT b/tools/OWNERS_PRODUCT
new file mode 100644
index 0000000..c2c62b9
--- /dev/null
+++ b/tools/OWNERS_PRODUCT
@@ -0,0 +1,2 @@
+kevmoo@google.com
+mit@google.com
diff --git a/tools/OWNERS_VM b/tools/OWNERS_VM
new file mode 100644
index 0000000..018eb47
--- /dev/null
+++ b/tools/OWNERS_VM
@@ -0,0 +1,13 @@
+aam@google.com
+alexmarkov@google.com
+asiva@google.com
+askesc@google.com
+bkonyi@google.com
+bquinlan@google.com
+cskau@google.com
+dacoharkes@google.com
+kustermann@google.com
+liama@google.com
+rmacnak@google.com
+sstrickl@google.com
+vegorov@google.com
diff --git a/tools/OWNERS_WEB b/tools/OWNERS_WEB
new file mode 100644
index 0000000..df81259
--- /dev/null
+++ b/tools/OWNERS_WEB
@@ -0,0 +1,15 @@
+annagrin@google.com
+elliottbrooks@google.com
+fishythefish@google.com
+grouma@google.com
+jacobr@google.com
+joshualitt@google.com
+kevmoo@google.com
+leonsenft@google.com
+markzipan@google.com
+nshahan@google.com
+rileyporter@google.com
+sigmund@google.com
+sra@google.com
+srujzs@google.com
+vsm@google.com
diff --git a/tools/VERSION b/tools/VERSION
index 4400c24..f17707f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 106
+PRERELEASE 107
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/OWNERS b/utils/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/utils/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG