Version 2.5.0-dev.2.1

* Cherry-pick 81569e5fe360b9d3229b560b756c477c42058828 to dev
* Cherry-pick 28e857bbf5ba54a10fdab3aeec1917d153495e3d to dev
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
index cfb01cc..5c7fde6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking.dart
@@ -17,6 +17,9 @@
 /// Minimum probability to prioritize model-only suggestion.
 const double _MODEL_RELEVANCE_CUTOFF = 0.5;
 
+/// Number of code completion isolates.
+const int _ISOLATE_COUNT = 4;
+
 /// Prediction service run by the model isolate.
 void entrypoint(SendPort sendPort) {
   LanguageModel model;
@@ -44,8 +47,11 @@
   /// Filesystem location of model files.
   final String _directory;
 
-  /// Port to communicate from main to model isolate.
-  SendPort _write;
+  /// Ports to communicate from main to model isolates.
+  List<SendPort> _writes;
+
+  /// Pointer for round robin load balancing over isolates.
+  int _index;
 
   CompletionRanking(this._directory);
 
@@ -53,11 +59,12 @@
   Future<Map<String, Map<String, double>>> makeRequest(
       String method, List<String> args) async {
     final port = ReceivePort();
-    _write.send({
+    _writes[_index].send({
       'method': method,
       'args': args,
       'port': port.sendPort,
     });
+    this._index = (_index + 1) % _ISOLATE_COUNT;
     return await port.first;
   }
 
@@ -83,7 +90,7 @@
       DartCompletionRequest request,
       FeatureSet featureSet) async {
     final probability = await probabilityFuture
-        .timeout(const Duration(milliseconds: 500), onTimeout: () => null);
+        .timeout(const Duration(seconds: 1), onTimeout: () => null);
     if (probability == null || probability.isEmpty) {
       // Failed to compute probability distribution, don't rerank.
       return suggestions;
@@ -177,9 +184,20 @@
 
   /// Spins up the model isolate and tells it to load the tflite model.
   Future<void> start() async {
+    this._writes = [];
+    this._index = 0;
+    final initializations = <Future<void>>[];
+    for (var i = 0; i < _ISOLATE_COUNT; i++) {
+      initializations.add(_startIsolate());
+    }
+
+    await Future.wait(initializations);
+  }
+
+  Future<void> _startIsolate() async {
     final port = ReceivePort();
     await Isolate.spawn(entrypoint, port.sendPort);
-    this._write = await port.first;
+    this._writes.add(await port.first);
     await makeRequest('load', [_directory]);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
index 9ec82f9..cb8c923 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_ranking_internal.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:front_end/src/fasta/scanner.dart';
 
 /// Constructs a [CompletionSuggestion] object.
 CompletionSuggestion createCompletionSuggestion(
@@ -160,7 +161,7 @@
 
   final result = List<String>();
   for (var size = 0; size < n && !token.isEof; token = token.previous) {
-    if (!token.isSynthetic) {
+    if (!token.isSynthetic && token is! ErrorToken) {
       result.add(token.lexeme);
       size += 1;
     }
diff --git a/tools/VERSION b/tools/VERSION
index f100d4d..a5d8aa2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -34,6 +34,6 @@
 MINOR 5
 PATCH 0
 PRERELEASE 2
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1
 ABI_VERSION 11
 OLDEST_SUPPORTED_ABI_VERSION 11