Version 2.18.0-71.0.dev

Merge commit 'f484e2e5db910ae4cadd57c819b0e23ac9e46c18' into 'dev'
diff --git a/pkg/analysis_server/lib/src/handler/legacy/analysis_get_navigation.dart b/pkg/analysis_server/lib/src/handler/legacy/analysis_get_navigation.dart
index 5dc0820..2b9aa1e 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/analysis_get_navigation.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/analysis_get_navigation.dart
@@ -7,9 +7,9 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 import 'package:analysis_server/src/plugin/result_merger.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
index 5a08236..48d75db 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
@@ -7,10 +7,10 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
diff --git a/pkg/analysis_server/lib/src/handler/legacy/edit_get_assists.dart b/pkg/analysis_server/lib/src/handler/legacy/edit_get_assists.dart
index 27d4485b..b66b6c5 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/edit_get_assists.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/edit_get_assists.dart
@@ -8,10 +8,10 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/plugin/result_converter.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
diff --git a/pkg/analysis_server/lib/src/handler/legacy/edit_get_fixes.dart b/pkg/analysis_server/lib/src/handler/legacy/edit_get_fixes.dart
index fdb2806..2a16f57 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/edit_get_fixes.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/edit_get_fixes.dart
@@ -6,11 +6,11 @@
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/plugin/result_converter.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
diff --git a/pkg/analysis_server/lib/src/handler/legacy/kythe_get_kythe_entries.dart b/pkg/analysis_server/lib/src/handler/legacy/kythe_get_kythe_entries.dart
index 2b92067..7e70ef1 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/kythe_get_kythe_entries.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/kythe_get_kythe_entries.dart
@@ -7,9 +7,9 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
 import 'package:analysis_server/src/plugin/result_merger.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analysis_server/src/services/kythe/kythe_visitors.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 6a8fd79..a312139 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -7,13 +7,13 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/analysis_server_abstract.dart';
-import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_cancel_request.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_reject.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/progress.dart';
+import 'package:analysis_server/src/request_handler_mixin.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/utilities/cancellation.dart';
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/request_handler_mixin.dart
similarity index 82%
rename from pkg/analysis_server/lib/src/domain_abstract.dart
rename to pkg/analysis_server/lib/src/request_handler_mixin.dart
index 3ff067b..b4a9dfb 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/request_handler_mixin.dart
@@ -5,26 +5,11 @@
 import 'dart:async';
 import 'dart:convert';
 
-import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/analysis_server_abstract.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
 
-/// An abstract implementation of a request handler.
-abstract class AbstractRequestHandler
-    with RequestHandlerMixin<AnalysisServer>
-    implements RequestHandler {
-  /// The analysis server that is using this handler to process requests.
-  @override
-  final AnalysisServer server;
-
-  /// Initialize a newly created request handler to be associated with the given
-  /// analysis [server].
-  AbstractRequestHandler(this.server);
-}
-
 mixin RequestHandlerMixin<T extends AbstractAnalysisServer> {
   /// The analysis server that is using this handler to process requests.
   T get server;
diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart
deleted file mode 100644
index 2221c34..0000000
--- a/pkg/analysis_server/test/src/domain_abstract_test.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/domain_abstract.dart';
-import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analysis_server/src/protocol_server.dart' hide Element;
-import 'package:analyzer/instrumentation/service.dart';
-import 'package:analyzer/src/utilities/cancellation.dart';
-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_server_base.dart';
-import 'plugin/plugin_manager_test.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AbstractRequestHandlerTest);
-  });
-}
-
-@reflectiveTest
-class AbstractRequestHandlerTest extends PubPackageAnalysisServerTest {
-  Future<void> test_waitForResponses_empty_noTimeout() async {
-    AbstractRequestHandler handler = TestAbstractRequestHandler(server);
-    var futures = <PluginInfo, Future<plugin.Response>>{};
-    var responses = await handler.waitForResponses(futures);
-    expect(responses, isEmpty);
-  }
-
-  Future<void> test_waitForResponses_empty_timeout() async {
-    AbstractRequestHandler handler = TestAbstractRequestHandler(server);
-    var futures = <PluginInfo, Future<plugin.Response>>{};
-    var responses = await handler.waitForResponses(futures,
-        timeout: const Duration(milliseconds: 250));
-    expect(responses, isEmpty);
-  }
-
-  Future<void> test_waitForResponses_nonEmpty_noTimeout_immediate() async {
-    AbstractRequestHandler handler = TestAbstractRequestHandler(server);
-    var plugin1 = _pluginInfo('p1');
-    var plugin2 = _pluginInfo('p2');
-    var response1 = plugin.Response('1', 1);
-    var response2 = plugin.Response('2', 2);
-    var futures = <PluginInfo, Future<plugin.Response>>{
-      plugin1: Future.value(response1),
-      plugin2: Future.value(response2),
-    };
-    var responses = await handler.waitForResponses(futures);
-    expect(responses, unorderedEquals([response1, response2]));
-  }
-
-  Future<void> test_waitForResponses_nonEmpty_noTimeout_withError() async {
-    AbstractRequestHandler handler = TestAbstractRequestHandler(server);
-    var plugin1 = _pluginInfo('p1');
-    var plugin2 = _pluginInfo('p2');
-    var response1 = plugin.Response('1', 1);
-    var response2 = plugin.Response('2', 2,
-        error: plugin.RequestError(
-            plugin.RequestErrorCode.PLUGIN_ERROR, 'message'));
-    var futures = <PluginInfo, Future<plugin.Response>>{
-      plugin1: Future.value(response1),
-      plugin2: Future.value(response2),
-    };
-    var responses = await handler.waitForResponses(futures);
-    expect(responses, unorderedEquals([response1]));
-  }
-
-  Future<void> test_waitForResponses_nonEmpty_timeout_someDelayed() async {
-    AbstractRequestHandler handler = TestAbstractRequestHandler(server);
-    var plugin1 = _pluginInfo('p1');
-    var plugin2 = _pluginInfo('p2');
-    var plugin3 = _pluginInfo('p3');
-    var response1 = plugin.Response('1', 1);
-    var response2 = plugin.Response('2', 2);
-    var response3 = plugin.Response('3', 3);
-    var futures = <PluginInfo, Future<plugin.Response>>{
-      plugin1: Future.delayed(Duration(milliseconds: 500), () => response1),
-      plugin2: Future.value(response2),
-      plugin3: Future.delayed(Duration(milliseconds: 500), () => response3)
-    };
-    var responses = await handler.waitForResponses(futures,
-        timeout: const Duration(milliseconds: 50));
-    expect(responses, unorderedEquals([response2]));
-  }
-
-  PluginInfo _pluginInfo(String path) {
-    return DiscoveredPluginInfo(path, '', '', TestNotificationManager(),
-        InstrumentationService.NULL_SERVICE);
-  }
-}
-
-class TestAbstractRequestHandler extends AbstractRequestHandler {
-  TestAbstractRequestHandler(super.server);
-
-  @override
-  Response handleRequest(Request request, CancellationToken cancellationToken) {
-    fail('Unexpected invocation of handleRequest');
-  }
-}
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 85dd930..feab036 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -6,7 +6,6 @@
 
 import 'cider/test_all.dart' as cider;
 import 'computer/test_all.dart' as computer;
-import 'domain_abstract_test.dart' as domain_abstract;
 import 'domains/test_all.dart' as domains;
 import 'flutter/test_all.dart' as flutter;
 import 'g3/test_all.dart' as g3;
@@ -20,7 +19,6 @@
   defineReflectiveSuite(() {
     cider.main();
     computer.main();
-    domain_abstract.main();
     domains.main();
     flutter.main();
     g3.main();
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index 9466097..d785338 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -261,8 +261,6 @@
 }
 
 abstract class WebDriverBrowser extends Browser {
-  static int _nextPort = 4444;
-  final int _port = _nextPort++;
   WebDriver _driver;
 
   String get driverExecutable;
@@ -272,11 +270,12 @@
   @override
   Future<bool> start(String url) async {
     _logEvent('Starting $this browser on: $url');
+    var port = await _findUnusedPort();
     if (!await startBrowserProcess(
-        driverExecutable, ['--port', '$_port', ...driverArguments])) {
+        driverExecutable, ['--port', '$port', ...driverArguments])) {
       return false;
     }
-    await _createDriver();
+    await _createDriver(port);
     await _driver.get(url);
     try {
       _logEvent('Got version: ${await version}');
@@ -287,13 +286,13 @@
     return true;
   }
 
-  Future<void> _createDriver() async {
+  Future<void> _createDriver(int port) async {
     for (var i = 5; i >= 0; i--) {
       // Give the driver process some time to be ready to accept connections.
       await Future.delayed(const Duration(seconds: 1));
       try {
         _driver = await createDriver(
-            uri: Uri.parse('http://localhost:$_port/'),
+            uri: Uri.parse('http://localhost:$port/'),
             desired: desiredCapabilities);
       } catch (error) {
         if (i > 0) {
@@ -309,6 +308,24 @@
     }
   }
 
+  /// Returns a port that is probably, but not definitely, not in use.
+  ///
+  /// This has a built-in race condition: another process may bind this port at
+  /// any time after this call has returned.
+  static Future<int> _findUnusedPort() async {
+    int port;
+    ServerSocket socket;
+    try {
+      socket = await ServerSocket.bind(InternetAddress.loopbackIPv6, 0,
+          v6Only: true);
+    } on SocketException {
+      socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
+    }
+    port = socket.port;
+    await socket.close();
+    return port;
+  }
+
   @override
   Future<bool> close() async {
     try {
diff --git a/tools/VERSION b/tools/VERSION
index 448f620..9e80e1b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 70
+PRERELEASE 71
 PRERELEASE_PATCH 0
\ No newline at end of file